vrfkey

package
v0.10.13 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2021 License: MIT Imports: 17 Imported by: 2

Documentation

Overview

Package vrfkey tracks the secret keys associated with VRF proofs. It is a separate package from ../store to increase encapsulation of the keys, reduce the risk of them leaking, and reduce confusion between VRF keys and ethereum keys.

The three types, PrivateKey (private_key.go), PublicKey (public_key.go) and EncryptedVRFKey (serialzation.go) are all aspects of the one keypair.

The details of the secret key in a keypair should remain private to this package. If you need to access the secret key, you should add a method to PrivateKey which does the crypto requiring it, without leaking the secret. See MakeMarshaledProof in private_key.go, for an example.

PrivateKey#PublicKey represents the associated public key, and, in the context of a VRF, represents a public commitment to a particular "verifiable random function."

EncryptedVRFKey is used to store a public/private keypair in a database, in encrypted form.

Usage

Call vrfkey.CreateKey() to generate a PrivateKey with cryptographically secure randomness.

Call PrivateKey#Encrypt(passphrase) to create a representation of the key which is encrypted for storage.

Call MakeMarshaledProof(privateKey, seed) to generate the VRF proof for the given seed and private key. The proof is marshaled in the format expected by the on-chain verification mechanism in VRF.sol. If you want to know the VRF output independently of the on-chain verification mechanism, you can get it from vrf.UnmarshalSolidityProof(p).Output.

Index

Constants

This section is empty.

Variables

View Source
var (
	// FieldSize is number of elements in secp256k1's base field, i.e. GF(FieldSize)
	FieldSize = utils.HexToBig(
		"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
	)
	Secp256k1Curve = &secp256k1.Secp256k1{}
	Generator      = Secp256k1Curve.Point().Base()

	ErrCGammaEqualsSHash = fmt.Errorf("pick a different nonce; c*gamma = s*hash, with this one")

	// RandomOutputHashPrefix is a domain-separation tag for the hash used to
	// compute the final VRF random output
	RandomOutputHashPrefix = common.BigToHash(bm.Three).Bytes()
)

Functions

func FieldHash

func FieldHash(msg []byte) *big.Int

FieldHash hashes xs uniformly into {0, ..., fieldSize-1}. msg is assumed to already be a 256-bit hash

func HashToCurve

func HashToCurve(p kyber.Point, input *big.Int, ordinates func(x *big.Int),
) (kyber.Point, error)

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

func HashUint256s(xs ...*big.Int) (*big.Int, error)

HashUint256s returns a uint256 representing the hash of the concatenated byte representations of the inputs

func IsCurveXOrdinate

func IsCurveXOrdinate(x *big.Int) bool

IsCurveXOrdinate returns true iff there is y s.t. y^2=x^3+7

func IsSquare

func IsSquare(x *big.Int) bool

IsSquare returns true iff x = y^2 for some y in GF(p)

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

func ScalarFromCurvePoints(
	hash, pk, gamma kyber.Point, uWitness [20]byte, v kyber.Point) *big.Int

ScalarFromCurve returns a hash for the curve points. Corresponds to the hash computed in VRF.sol#ScalarFromCurvePoints

func SquareRoot

func SquareRoot(x *big.Int) *big.Int

SquareRoot returns a s.t. a^2=x, as long as x is a square

func YSquared

func YSquared(x *big.Int) *big.Int

YSquared returns x^3+7 mod fieldSize, the right-hand side of the secp256k1 curve equation.

Types

type EncryptedVRFKey

type EncryptedVRFKey struct {
	PublicKey secp256k1.PublicKey `gorm:"primary_key"`
	VRFKey    gethKeyStruct       `json:"vrf_key"`
	CreatedAt time.Time           `json:"-"`
	UpdatedAt time.Time           `json:"-"`
	DeletedAt gorm.DeletedAt      `json:"-"`
}

EncryptedVRFKey contains encrypted private key to be serialized to DB

We could re-use geth's key handling, here, but this makes it much harder to misuse VRF proving keys as ethereum keys or vice versa.

func (*EncryptedVRFKey) JSON

func (e *EncryptedVRFKey) JSON() ([]byte, error)

JSON returns the JSON representation of e, or errors

func (*EncryptedVRFKey) WriteToDisk

func (e *EncryptedVRFKey) WriteToDisk(path string) error

WriteToDisk writes the JSON representation of e to given file path, and ensures the file has appropriate access permissions

type PrivateKey

type PrivateKey struct {
	PublicKey secp256k1.PublicKey
	// contains filtered or unexported fields
}

PrivateKey represents the secret used to construct a VRF proof.

Don't serialize directly, use Encrypt method, with user-supplied passphrase. The unencrypted PrivateKey struct should only live in-memory.

Only use it if you absolutely need it (i.e., for a novel crypto protocol.) Implement whatever cryptography you need on this struct, so your callers don't need to know the secret key explicitly. (See, e.g., MarshaledProof.)

func CreateKey

func CreateKey() (key *PrivateKey)

CreateKey makes a new VRF proving key from cryptographically secure entropy

func Decrypt

func Decrypt(e *EncryptedVRFKey, auth string) (*PrivateKey, error)

Decrypt returns the PrivateKey in e, decrypted via auth, or an error

func NewPrivateKeyXXXTestingOnly

func NewPrivateKeyXXXTestingOnly(k *big.Int) *PrivateKey

NewPrivateKeyXXXTestingOnly is for testing purposes only!

func (*PrivateKey) Encrypt

func (k *PrivateKey) Encrypt(auth string, scryptParams utils.ScryptParams) (*EncryptedVRFKey, error)

Encrypt returns the key encrypted with passphrase auth

func (*PrivateKey) GenerateProof

func (k *PrivateKey) GenerateProof(seed *big.Int) (Proof, error)

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 (*PrivateKey) GenerateProofWithNonce

func (k *PrivateKey) GenerateProofWithNonce(seed, nonce *big.Int) (Proof, error)

GenerateProofWithNonce allows external nonce generation for testing purposes

As with signatures, using nonces which are in any way predictable to an adversary will leak your secret key! Most people should use GenerateProof instead.

func (*PrivateKey) GoStringer

func (k *PrivateKey) GoStringer() string

GoStringer reduces the risk of accidentally logging the private key

func (*PrivateKey) String

func (k *PrivateKey) String() string

String reduces the risk of accidentally logging the private key

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 (*Proof) String

func (p *Proof) String() string

func (*Proof) VerifyVRFProof

func (p *Proof) VerifyVRFProof() (bool, error)

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

func (p *Proof) WellFormed() bool

WellFormed is true iff p's attributes satisfy basic domain checks

Jump to

Keyboard shortcuts

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