ecvrf

package module
v0.0.0-...-9c382e0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2023 License: MIT Imports: 9 Imported by: 0

README

Note

Golang implementation of Elliptic Curve Verifiable Random Function (VRF).

This library has test to both show the generation of prove in Golang and verification of prove in Solidity using SECP256K1_SHA256_TAI cipher suite.

Changes Introduced to VeChain go-ecvrf following https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-10.html#name-elliptic-curve-vrf-ecvrf and https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vrf-10.html#name-ecvrf-ciphersuites includes:

  • ProveSecp256k1
  • VerifySecp256k1
  • HashToCurveTryAndIncrementSecp256k1
  • rfc6979nonceSecp256k1
  • HashPointsSecp256k1
  • GammaToHashSecp256k1
  • VerifySecp256k1

Usage

skBytes, _ := hex.DecodeString("b920c2c0cf474d02727d7215089d473580943c9e1f6f91d47c3cd025f0d10438")
sk := secp256k1.PrivKeyFromBytes(skBytes)
alpha, _ := hex.DecodeString("73616d706c65")

vrf := Secp256k1Sha256Tai

beta, pi, err := vrf.ProveSecp256k1(sk, alpha)

if err != nil {
  panic(err)
}

compareBeta, err := vrf.VerifySecp256k1(sk.PubKey().ToECDSA(), alpha, pi)
if err != nil {
  panic(err)
}

fmt.Println(beta)
fmt.Println(compareBeta)

Installation

go get -u github.com/klayoracle/go-ecvrf

Generate Proof in Golang and Verify in Solidity

// solidity_test/verify_test.go
func Test_Verify_Proof_GoVRF_Vs_SolidityVRF(t *testing.T) {

	chainId := big.NewInt(1337)
	chainRPC := "http://127.0.0.1:8545" //Ganache RPC Listening on

	client, err := ethclient.Dial(chainRPC)
	if err != nil {
		t.Errorf("start up Ganache client, to connect with client: %s", err)
	}

	privateKey, err := crypto.HexToECDSA("46dbea7b5d1b58285aa09e10aabf32a99a344385579c0bd1432f7d6ead2c8dd4") //Use account 1 provided by Ganache client
	if err != nil {
		t.Errorf("error with node signing key: %s", err)
	}

	gasPrice, err := client.SuggestGasPrice(context.Background())
	if err != nil {
		t.Errorf("error getting gas price: %s", err)
	}

	auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainId)
	if err != nil {
		t.Errorf("%s", err)
	}
	auth.Value = big.NewInt(0)      // in wei
	auth.GasLimit = uint64(9000000) // in units
	auth.GasPrice = gasPrice

	_, _, instance, err := DeployVerifyVRF(auth, client)
	if err != nil {
		t.Errorf("%v", err)
	}

	alpha, _ := hex.DecodeString("73616d706c65")

	vrf := ecvrf.Secp256k1Sha256Tai

	_, pi, err := vrf.ProveSecp256k1(privateKey, alpha)

	d, err := instance.DecodeProof(&bind.CallOpts{}, pi)
    
	valid, err := instance.Verify(&bind.CallOpts{}, [2]*big.Int{privateKey.X, privateKey.Y}, d, alpha)
	if err != nil {
		t.Errorf("%v", err)
	}

	assert.True(t, valid)
}

Note

Check Vechain go-ecvrf Readme for customization using a different cipher suite asides SECP256K1_SHA256_TAI or P256_SHA256_TAI.

References

License

Copyright (c) 2020 - 2023 vechain.org.
Copyright (c) 2023 digioracle.link
Licensed under the MIT license.

Documentation

Overview

Package ecvrf is the Elliptic Curve Verifiable Random Function (VRF) library.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Secp256k1Sha256Tai is the pre-configured VRF object with secp256k1/SHA256 and hash_to_curve_try_and_increment algorithm.
	Secp256k1Sha256Tai = New(&Config{
		Curve:       secp256k1.S256(),
		SuiteString: 0xfe,
		Cofactor:    0x01,
		NewHasher:   sha256.New,
		Decompress: func(c elliptic.Curve, pk []byte) (x, y *big.Int) {
			var fx, fy secp256k1.FieldVal

			format := pk[0]
			switch format {
			case secp256k1.PubKeyFormatCompressedEven, secp256k1.PubKeyFormatCompressedOdd:
			default:
				return
			}

			if overflow := fx.SetByteSlice(pk[1:33]); overflow {
				return
			}

			wantOddY := format == secp256k1.PubKeyFormatCompressedOdd
			if !secp256k1.DecompressY(&fx, wantOddY, &fy) {
				return
			}
			fy.Normalize()
			return new(big.Int).SetBytes(fx.Bytes()[:]), new(big.Int).SetBytes(fy.Bytes()[:])
		},
	})
	// P256Sha256Tai is the pre-configured VRF object with P256/SHA256 and hash_to_curve_try_and_increment algorithm.
	P256Sha256Tai = New(&Config{
		Curve:       elliptic.P256(),
		SuiteString: 0x01,
		Cofactor:    0x01,
		NewHasher:   sha256.New,
		Decompress:  elliptic.UnmarshalCompressed,
	})
)

Functions

This section is empty.

Types

type Config

type Config struct {
	// the elliptic curve.
	Curve elliptic.Curve
	// a single nonzero octet specifying the ECVRF ciphersuite.
	SuiteString byte
	// number of points on curve divided by group order.
	Cofactor byte
	// create cryptographic hash function.
	NewHasher func() hash.Hash
	// decompress the compressed public key into x and y coordinate.
	Decompress func(c elliptic.Curve, pk []byte) (x, y *big.Int)
}

Config contains VRF parameters.

type VRF

type VRF interface {
	// Prove constructs a VRF proof `pi` for the given input `alpha`,
	// using the private key `sk`. The hash output is returned as `beta`.
	Prove(sk *ecdsa.PrivateKey, alpha []byte) (beta, pi []byte, err error)

	ProveSecp256k1(sk *ecdsa.PrivateKey, alpha []byte) (beta, pi []byte, err error)

	// Verify checks the proof `pi` of the message `alpha` against the given
	// public key `pk`. The hash output is returned as `beta`.
	Verify(pk *ecdsa.PublicKey, alpha, pi []byte) (beta []byte, err error)

	VerifySecp256k1(pk *ecdsa.PublicKey, alpha, pi []byte) (beta []byte, err error)
}

VRF is the interface that wraps VRF methods.

func New

func New(cfg *Config) VRF

New creates and initializes a VRF object using customized config.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL