github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/crypto/vrf/p256/p256.go (about) 1 // Package p256 implements a verifiable random function using curve p256. 2 package p256 3 4 import ( 5 "bytes" 6 "crypto/ecdsa" 7 "crypto/elliptic" 8 "crypto/hmac" 9 "crypto/rand" 10 "crypto/sha256" 11 "crypto/sha512" 12 "crypto/x509" 13 "encoding/binary" 14 "encoding/pem" 15 "errors" 16 "math/big" 17 18 "github.com/zhiqiangxu/util/crypto/vrf" 19 ) 20 21 // PublicKey for vrf 22 type PublicKey struct { 23 *ecdsa.PublicKey 24 } 25 26 // PrivateKey for vrf 27 type PrivateKey struct { 28 *ecdsa.PrivateKey 29 } 30 31 var ( 32 curve = elliptic.P256() 33 params = curve.Params() 34 ) 35 36 // H1 hashes m to a curve point 37 func H1(m []byte) (x, y *big.Int, err error) { 38 h := sha512.New() 39 var i uint32 40 byteLen := (params.BitSize + 7) >> 3 41 for x == nil && i < 100 { 42 // TODO: Use a NIST specified DRBG. 43 h.Reset() 44 binary.Write(h, binary.BigEndian, i) 45 h.Write(m) 46 r := []byte{2} // Set point encoding to "compressed", y=0. 47 r = h.Sum(r) 48 x, y, err = Unmarshal(curve, r[:byteLen+1]) 49 i++ 50 } 51 return 52 } 53 54 var one = big.NewInt(1) 55 56 // H2 hashes m to an integer [1,N-1] 57 func H2(m []byte) *big.Int { 58 // NIST SP 800-90A § A.5.1: Simple discard method. 59 byteLen := (params.BitSize + 7) >> 3 60 h := sha512.New() 61 for i := uint32(0); ; i++ { 62 // TODO: Use a NIST specified DRBG. 63 h.Reset() 64 binary.Write(h, binary.BigEndian, i) 65 h.Write(m) 66 b := h.Sum(nil) 67 k := new(big.Int).SetBytes(b[:byteLen]) 68 if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 { 69 return k.Add(k, one) 70 } 71 } 72 } 73 74 // Hash converts alpha to beta+proof 75 func (k PrivateKey) Hash(alpha []byte) (beta [32]byte, proof []byte, err error) { 76 r, _, _, err := elliptic.GenerateKey(curve, rand.Reader) 77 if err != nil { 78 return 79 } 80 81 ri := new(big.Int).SetBytes(r) 82 83 // H = H1(m) 84 Hx, Hy, err := H1(alpha) 85 if err != nil { 86 return 87 } 88 89 // VRF_k(m) = [k]H 90 sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes()) 91 vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes. 92 93 // G is the base point 94 // s = H2(G, H, [k]G, VRF, [r]G, [r]H) 95 rGx, rGy := curve.ScalarBaseMult(r) 96 rHx, rHy := curve.ScalarMult(Hx, Hy, r) 97 var b bytes.Buffer 98 b.Write(elliptic.Marshal(curve, params.Gx, params.Gy)) 99 b.Write(elliptic.Marshal(curve, Hx, Hy)) 100 b.Write(elliptic.Marshal(curve, k.PublicKey.X, k.PublicKey.Y)) 101 b.Write(vrf) 102 b.Write(elliptic.Marshal(curve, rGx, rGy)) 103 b.Write(elliptic.Marshal(curve, rHx, rHy)) 104 s := H2(b.Bytes()) 105 106 // t = r−s*k mod N 107 t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D)) 108 t.Mod(t, params.N) 109 110 // beta = H(vrf) 111 beta = sha256.Sum256(vrf) 112 113 // Write s, t, and vrf to a proof blob. Also write leading zeros before s and t 114 // if needed. 115 var buf bytes.Buffer 116 buf.Write(make([]byte, 32-len(s.Bytes()))) 117 buf.Write(s.Bytes()) 118 buf.Write(make([]byte, 32-len(t.Bytes()))) 119 buf.Write(t.Bytes()) 120 buf.Write(vrf) 121 proof = buf.Bytes() 122 123 return 124 } 125 126 // Public returns the corresponding public key as Verifier. 127 func (k PrivateKey) Public() vrf.Verifier { 128 return PublicKey{PublicKey: &k.PublicKey} 129 } 130 131 // Verify that beta+proof is generated from m by PrivateKey 132 func (pk PublicKey) Verify(m, proof []byte, beta [32]byte) (valid bool, err error) { 133 // verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m)) 134 if got, want := len(proof), 64+65; got != want { 135 return 136 } 137 138 // Parse proof into s, t, and vrf. 139 s := proof[0:32] 140 t := proof[32:64] 141 vrf := proof[64 : 64+65] 142 143 uHx, uHy := elliptic.Unmarshal(curve, vrf) 144 if uHx == nil { 145 return 146 } 147 148 // [t]G + [s]([k]G) = [t+ks]G 149 tGx, tGy := curve.ScalarBaseMult(t) 150 ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s) 151 tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy) 152 153 // H = H1(m) 154 // [t]H + [s]VRF = [t+ks]H 155 Hx, Hy, err := H1(m) 156 if err != nil { 157 return 158 } 159 tHx, tHy := curve.ScalarMult(Hx, Hy, t) 160 sHx, sHy := curve.ScalarMult(uHx, uHy, s) 161 tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy) 162 163 // H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF) 164 // = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H) 165 // = H2(G, H, [k]G, VRF, [r]G, [r]H) 166 var b bytes.Buffer 167 b.Write(elliptic.Marshal(curve, params.Gx, params.Gy)) 168 b.Write(elliptic.Marshal(curve, Hx, Hy)) 169 b.Write(elliptic.Marshal(curve, pk.X, pk.Y)) 170 b.Write(vrf) 171 b.Write(elliptic.Marshal(curve, tksGx, tksGy)) 172 b.Write(elliptic.Marshal(curve, tksHx, tksHy)) 173 h2 := H2(b.Bytes()) 174 175 // Left pad h2 with zeros if needed. This will ensure that h2 is padded 176 // the same way s is. 177 var buf bytes.Buffer 178 buf.Write(make([]byte, 32-len(h2.Bytes()))) 179 buf.Write(h2.Bytes()) 180 181 if !hmac.Equal(s, buf.Bytes()) { 182 return 183 } 184 185 valid = true 186 return 187 } 188 189 // GeneratePair generates a fresh signer/verifier pair for this VRF 190 func GeneratePair() (k vrf.Signer, pk vrf.Verifier, err error) { 191 key, err := ecdsa.GenerateKey(curve, rand.Reader) 192 if err != nil { 193 return 194 } 195 196 k, pk = PrivateKey{PrivateKey: key}, PublicKey{PublicKey: &key.PublicKey} 197 return 198 } 199 200 var ( 201 errPointNotOnCurve = errors.New("point not on curve") 202 errNoPEMFound = errors.New("no pem found") 203 errWrongKeyType = errors.New("wrong key type") 204 ) 205 206 // NewVRFSigner creates a signer object from a private key. 207 func NewVRFSigner(key *ecdsa.PrivateKey) (k vrf.Signer, err error) { 208 if *(key.Params()) != *curve.Params() { 209 err = errPointNotOnCurve 210 return 211 } 212 if !curve.IsOnCurve(key.X, key.Y) { 213 err = errPointNotOnCurve 214 return 215 } 216 k = PrivateKey{PrivateKey: key} 217 return 218 } 219 220 // NewVRFVerifier creates a verifier object from a public key. 221 func NewVRFVerifier(pubkey *ecdsa.PublicKey) (pk vrf.Verifier, err error) { 222 if *(pubkey.Params()) != *curve.Params() { 223 err = errPointNotOnCurve 224 return 225 } 226 if !curve.IsOnCurve(pubkey.X, pubkey.Y) { 227 err = errPointNotOnCurve 228 return 229 } 230 pk = PublicKey{PublicKey: pubkey} 231 return 232 } 233 234 // NewVRFSignerFromRawKey returns the private key from a raw private key bytes. 235 func NewVRFSignerFromRawKey(b []byte) (k vrf.Signer, err error) { 236 key, err := x509.ParseECPrivateKey(b) 237 if err != nil { 238 return 239 } 240 k, err = NewVRFSigner(key) 241 return 242 } 243 244 // NewVRFSignerFromPEM creates a vrf private key from a PEM data structure. 245 func NewVRFSignerFromPEM(b []byte) (k vrf.Signer, err error) { 246 p, _ := pem.Decode(b) 247 if p == nil { 248 err = errNoPEMFound 249 return 250 } 251 k, err = NewVRFSignerFromRawKey(p.Bytes) 252 return 253 } 254 255 // NewVRFVerifierFromRawKey returns the public key from a raw public key bytes. 256 func NewVRFVerifierFromRawKey(b []byte) (pk vrf.Verifier, err error) { 257 key, err := x509.ParsePKIXPublicKey(b) 258 if err != nil { 259 return 260 } 261 pubkey, ok := key.(*ecdsa.PublicKey) 262 if !ok { 263 err = errWrongKeyType 264 return 265 } 266 pk, err = NewVRFVerifier(pubkey) 267 return 268 }