Documentation ¶
Overview ¶
Numbers are deterministically generated from seeds and a secret key, and are statistically indistinguishable from uniform sampling from {0,...,2**256-1}, to computationally-bounded observers who know the seeds, don't know the key, and only see the generated numbers. But each number also comes with a proof that it was generated according to the procedure mandated by a public key associated with that secret key.
See VRF.sol for design notes.
Usage -----
You should probably not be using this directly. adamoracle/store/core/models/vrfkey.PrivateKey provides a simple, more misuse-resistant interface to the same functionality, via the CreateKey and MarshaledProof methods.
Nonetheless, a secret key sk should be securely sampled uniformly from {0,...,Order-1}. Its public key can be calculated from it by
secp256k1.Secp256k1{}.Point().Mul(secretKey, Generator)
To generate random output from a big.Int seed, pass sk and the seed to GenerateProof, and use the Output field of the returned Proof object.
To verify a Proof object p, run p.Verify(); or to verify it on-chain pass p.MarshalForSolidityVerifier() to randomValueFromVRFProof on the VRF solidity contract.
Index ¶
- Constants
- Variables
- func FieldHash(msg []byte) *big.Int
- func FinalSeed(s PreSeedData) (finalSeed *big.Int)
- func HashToCurve(p kyber.Point, input *big.Int, ordinates func(x *big.Int)) (kyber.Point, error)
- func HashUint256s(xs ...*big.Int) (*big.Int, error)
- func IsCurveXOrdinate(x *big.Int) bool
- func IsSquare(x *big.Int) bool
- func ProjectiveECAdd(p, q kyber.Point) (x, y, z fieldElt)
- func ScalarFromCurvePoints(hash, pk, gamma kyber.Point, uWitness [20]byte, v kyber.Point) *big.Int
- func SquareRoot(x *big.Int) *big.Int
- func YSquared(x *big.Int) *big.Int
- type MarshaledOnChainResponse
- type MarshaledProof
- type PreSeedData
- type Proof
- type ProofResponse
- type Seed
- type SolidityProof
Constants ¶
const OnChainResponseLength = ProofLength + 32
OnChainResponseLength is the length of the MarshaledOnChainResponse. The extra 32 bytes are for blocknumber (as a uint256), which goes at the end. The seed is rewritten with the preSeed. (See MarshalForVRFCoordinator and ProofResponse#ActualProof.)
const ProofLength = 64 + 64 + 32 + 32 + 32 + 32 + 64 + 64 + 32 // zInv (Leave Output out, because that can be efficiently calculated)
Length of marshaled proof, in bytes
Variables ¶
var ErrCGammaEqualsSHash = fmt.Errorf(
"pick a different nonce; c*gamma = s*hash, with this one")
var FieldSize = bigFromHex(
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
FieldSize is number of elements in secp256k1's base field, i.e. GF(FieldSize)
var Generator = secp256k1Curve.Point().Base()
Generator is the generator point of secp256k1
Functions ¶
func FieldHash ¶
FieldHash hashes xs uniformly into {0, ..., fieldSize-1}. msg is assumed to already be a 256-bit hash
func FinalSeed ¶
func FinalSeed(s PreSeedData) (finalSeed *big.Int)
FinalSeed is the seed which is actually passed to the VRF proof generator, given the pre-seed and the hash of the block in which the VRFCoordinator emitted the log for the request this is responding to.
func HashToCurve ¶
HashToCurve is a cryptographic hash function which outputs a secp256k1 point, or an error. It passes each candidate x ordinate to ordinates function.
func HashUint256s ¶
HashUint256s returns a uint256 representing the hash of the concatenated byte representations of the inputs
func IsCurveXOrdinate ¶
IsCurveXOrdinate returns true iff there is y s.t. y^2=x^3+7
func ProjectiveECAdd ¶
func ProjectiveECAdd(p, q kyber.Point) (x, y, z fieldElt)
ProjectiveECAdd(px, py, qx, qy) duplicates the calculation in projective coordinates of VRF.sol#projectiveECAdd, so we can reliably get the denominator (i.e, z)
func ScalarFromCurvePoints ¶
ScalarFromCurve returns a hash for the curve points. Corresponds to the hash computed in VRF.sol#ScalarFromCurvePoints
func SquareRoot ¶
SquareRoot returns a s.t. a^2=x, as long as x is a square
Types ¶
type MarshaledOnChainResponse ¶
type MarshaledOnChainResponse [OnChainResponseLength]byte
MarshaledOnChainResponse is the flat bytes which are sent back to the VRFCoordinator.
func GenerateProofResponse ¶
func GenerateProofResponse(secretKey common.Hash, s PreSeedData) ( MarshaledOnChainResponse, error)
GenerateProofResponse returns the marshaled proof of the VRF output given the secretKey and the seed computed from the s.PreSeed and the s.BlockHash
type MarshaledProof ¶
type MarshaledProof [ProofLength]byte
MarshaledProof contains a VRF proof for randomValueFromVRFProof.
NB: when passing one of these to randomValueFromVRFProof via the geth blockchain simulator, it must be passed as a slice ("proof[:]"). Passing it as-is sends hundreds of single bytes, each padded to their own 32-byte word.
func (MarshaledProof) String ¶
func (m MarshaledProof) String() string
String returns m as 0x-hex bytes
type PreSeedData ¶
type PreSeedData struct { PreSeed Seed // Seed to be mixed with hash of containing block BlockHash common.Hash // Hash of block containing VRF request BlockNum uint64 // Cardinal number of block containing VRF request }
PreSeedData contains the data the VRF provider needs to compute the final VRF output and marshal the proof for transmission to the VRFCoordinator contract.
type Proof ¶
type Proof struct { PublicKey kyber.Point // secp256k1 public key of private key used in proof Gamma kyber.Point C *big.Int S *big.Int Seed *big.Int // Seed input to verifiable random function Output *big.Int // verifiable random function output;, uniform uint256 sample }
Proof represents a proof that Gamma was constructed from the Seed according to the process mandated by the PublicKey.
N.B.: The kyber.Point fields must contain secp256k1.secp256k1Point values, C, S and Seed must be secp256k1Point, and Output must be at most 256 bits. See Proof.WellFormed.
func GenerateProof ¶
GenerateProof returns gamma, plus proof that gamma was constructed from seed as mandated from the given secretKey, with public key secretKey*Generator
secretKey and seed must be less than secp256k1 group order. (Without this constraint on the seed, the samples and the possible public keys would deviate very slightly from uniform distribution.)
func UnmarshalSolidityProof ¶
func (*Proof) MarshalForSolidityVerifier ¶
func (p *Proof) MarshalForSolidityVerifier() (MarshaledProof, error)
MarshalForSolidityVerifier renders p as required by randomValueFromVRFProof
func (*Proof) SolidityPrecalculations ¶
func (p *Proof) SolidityPrecalculations() (*SolidityProof, error)
SolidityPrecalculations returns the precomputed values needed by the solidity verifier, or an error on failure.
func (*Proof) VerifyVRFProof ¶
VerifyProof is true iff gamma was generated in the mandated way from the given publicKey and seed, and no error was encountered
func (*Proof) WellFormed ¶
WellFormed is true iff p's attributes satisfy basic domain checks
type ProofResponse ¶
type ProofResponse struct { // Approximately the proof which will be checked on-chain. Note that this // contains the pre-seed in place of the final seed. That should be computed // as in FinalSeed. P Proof PreSeed Seed // Seed received during VRF request BlockNum uint64 // Height of the block in which tihs request was made }
ProofResponse is the data which is sent back to the VRFCoordinator, so that it can verify that the seed the oracle finally used is correct.
func UnmarshalProofResponse ¶
func UnmarshalProofResponse(m MarshaledOnChainResponse) (*ProofResponse, error)
UnmarshalProofResponse returns the ProofResponse represented by the bytes in m
func (ProofResponse) CryptoProof ¶
func (p ProofResponse) CryptoProof(s PreSeedData) (Proof, error)
CryptoProof returns the proof implied by p, with the correct seed
func (*ProofResponse) MarshalForVRFCoordinator ¶
func (p *ProofResponse) MarshalForVRFCoordinator() ( response MarshaledOnChainResponse, err error)
MarshalForVRFCoordinator constructs the flat bytes which are sent to the VRFCoordinator.
type Seed ¶
type Seed [32]byte
Seed represents a VRF seed as a serialized uint256
func BytesToSeed ¶
BytesToSeed returns the Seed corresponding to b, or an error if b is too long
type SolidityProof ¶
type SolidityProof struct { P *Proof // The core proof UWitness common.Address // Address of P.C*P.PK+P.S*G CGammaWitness, SHashWitness kyber.Point // P.C*P.Gamma, P.S*HashToCurve(P.Seed) ZInv *big.Int // Inverse of Z coord from ProjectiveECAdd(CGammaWitness, SHashWitness) }
SolidityProof contains precalculations which VRF.sol needs to verifiy proofs
func (*SolidityProof) MarshalForSolidityVerifier ¶
func (p *SolidityProof) MarshalForSolidityVerifier() (proof MarshaledProof)
MarshalForSolidityVerifier renders p as required by randomValueFromVRFProof
func (*SolidityProof) String ¶
func (p *SolidityProof) String() string
String returns the values in p, in hexadecimal format