Skip to content

Golang implementation of Elliptic Curve Verifiable Random Function (VRF), with Test case Showing Verify in Solidity

License

Notifications You must be signed in to change notification settings

KlayOracle/go-ecvrf

Repository files navigation

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.

About

Golang implementation of Elliptic Curve Verifiable Random Function (VRF), with Test case Showing Verify in Solidity

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published