github.com/Evanesco-Labs/go-evanesco@v1.0.1/zkpminer/vrf/vrf.go (about) 1 package vrf 2 3 import ( 4 "bytes" 5 "crypto/elliptic" 6 "crypto/hmac" 7 "crypto/rand" 8 "crypto/sha256" 9 "errors" 10 "github.com/Evanesco-Labs/go-evanesco/zkpminer/keypair" 11 "math/big" 12 ) 13 14 var ( 15 ErrInvalidVRF = errors.New("invalid VRF proof") 16 ) 17 18 // Evaluate returns the verifiable unpredictable function evaluated at m 19 func Evaluate(k *keypair.PrivateKey, m []byte) (index [32]byte, proof []byte) { 20 nilIndex := [32]byte{} 21 // Prover chooses r <-- [1,N-1] 22 r, _, _, err := elliptic.GenerateKey(keypair.Curve, rand.Reader) 23 if err != nil { 24 return nilIndex, nil 25 } 26 ri := new(big.Int).SetBytes(r) 27 28 // H = HashToCurve(m) 29 Hx, Hy := keypair.HashToCurve(m) 30 // VRF_k(m) = [k]H 31 sHx, sHy := keypair.Curve.ScalarMult(Hx, Hy, k.D.Bytes()) 32 vrf := elliptic.Marshal(keypair.Curve, sHx, sHy) // 65 bytes. 33 34 // G is the base point 35 // s = HashToField(G, H, [k]G, VRF, [r]G, [r]H) 36 rGx, rGy := keypair.Curve.ScalarBaseMult(r) 37 rHx, rHy := keypair.Curve.ScalarMult(Hx, Hy, r) 38 var b bytes.Buffer 39 b.Write(elliptic.Marshal(keypair.Curve, keypair.Params.Gx, keypair.Params.Gy)) 40 b.Write(elliptic.Marshal(keypair.Curve, Hx, Hy)) 41 b.Write(elliptic.Marshal(keypair.Curve, k.PublicKey.X, k.PublicKey.Y)) 42 b.Write(vrf) 43 b.Write(elliptic.Marshal(keypair.Curve, rGx, rGy)) 44 b.Write(elliptic.Marshal(keypair.Curve, rHx, rHy)) 45 s := keypair.HashToField(b.Bytes()) 46 47 // t = r−s*k mod N 48 t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D)) 49 t.Mod(t, keypair.Params.N) 50 51 // Index = H(vrf) 52 index = sha256.Sum256(vrf) 53 54 // Write s, t, and vrf to a proof blob. Also write leading zeros before s and t 55 // if needed. 56 var buf bytes.Buffer 57 buf.Write(make([]byte, 32-len(s.Bytes()))) 58 buf.Write(s.Bytes()) 59 buf.Write(make([]byte, 32-len(t.Bytes()))) 60 buf.Write(t.Bytes()) 61 buf.Write(vrf) 62 63 p := buf.Bytes() 64 65 //self verify 66 hash, err := ProofToHash(k.Public(), m, p) 67 if err != nil { 68 return nilIndex, nil 69 } 70 if hash != index { 71 return nilIndex, nil 72 } 73 74 return index, p 75 } 76 77 // ProofToHash asserts that proof is correct for m and outputs index. 78 func ProofToHash(pk *keypair.PublicKey, m, proof []byte) (index [32]byte, err error) { 79 nilIndex := [32]byte{} 80 81 if got, want := len(proof), 64+65; got != want { 82 return nilIndex, ErrInvalidVRF 83 } 84 85 s := proof[0:32] 86 t := proof[32:64] 87 vrf := proof[64 : 64+65] 88 89 uHx, uHy := elliptic.Unmarshal(keypair.Curve, vrf) 90 if uHx == nil { 91 return nilIndex, ErrInvalidVRF 92 } 93 94 tGx, tGy := keypair.Curve.ScalarBaseMult(t) 95 ksGx, ksGy := keypair.Curve.ScalarMult(pk.X, pk.Y, s) 96 tksGx, tksGy := keypair.Curve.Add(tGx, tGy, ksGx, ksGy) 97 98 Hx, Hy := keypair.HashToCurve(m) 99 tHx, tHy := keypair.Curve.ScalarMult(Hx, Hy, t) 100 sHx, sHy := keypair.Curve.ScalarMult(uHx, uHy, s) 101 tksHx, tksHy := keypair.Curve.Add(tHx, tHy, sHx, sHy) 102 103 var b bytes.Buffer 104 b.Write(elliptic.Marshal(keypair.Curve, keypair.Params.Gx, keypair.Params.Gy)) 105 b.Write(elliptic.Marshal(keypair.Curve, Hx, Hy)) 106 b.Write(elliptic.Marshal(keypair.Curve, pk.X, pk.Y)) 107 b.Write(vrf) 108 b.Write(elliptic.Marshal(keypair.Curve, tksGx, tksGy)) 109 b.Write(elliptic.Marshal(keypair.Curve, tksHx, tksHy)) 110 h2 := keypair.HashToField(b.Bytes()) 111 112 var buf bytes.Buffer 113 buf.Write(make([]byte, 32-len(h2.Bytes()))) 114 buf.Write(h2.Bytes()) 115 116 if !hmac.Equal(s, buf.Bytes()) { 117 return nilIndex, ErrInvalidVRF 118 } 119 return sha256.Sum256(vrf), nil 120 }