github.com/turingchain2020/turingchain@v1.1.21/common/vrf/secp256k1/secp256k1.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Copyright 2016 Google Inc. All Rights Reserved. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 // See the License for the specific language governing permissions and 17 // limitations under the License. 18 19 // Package secp256k1 implements a verifiable random function using curve secp256k1. 20 package secp256k1 21 22 import ( 23 "bytes" 24 "crypto" 25 "crypto/ecdsa" 26 "crypto/elliptic" 27 "crypto/hmac" 28 "crypto/rand" 29 "crypto/sha256" 30 "crypto/sha512" 31 "encoding/binary" 32 "errors" 33 "math/big" 34 35 vrfp "github.com/turingchain2020/turingchain/common/vrf" 36 "github.com/btcsuite/btcd/btcec" 37 ) 38 39 var ( 40 curve = btcec.S256() 41 // ErrInvalidVRF err 42 ErrInvalidVRF = errors.New("invalid VRF proof") 43 ) 44 45 // PublicKey holds a public VRF key. 46 type PublicKey struct { 47 *ecdsa.PublicKey 48 } 49 50 // PrivateKey holds a private VRF key. 51 type PrivateKey struct { 52 *ecdsa.PrivateKey 53 } 54 55 // GenerateKey generates a fresh keypair for this VRF 56 func GenerateKey() (vrfp.PrivateKey, vrfp.PublicKey) { 57 key, err := ecdsa.GenerateKey(curve, rand.Reader) 58 if err != nil { 59 return nil, nil 60 } 61 62 return &PrivateKey{PrivateKey: key}, &PublicKey{PublicKey: &key.PublicKey} 63 } 64 65 // H1 hashes m to a curve point 66 func H1(m []byte) (x, y *big.Int) { 67 h := sha512.New() 68 var i uint32 69 byteLen := (curve.BitSize + 7) >> 3 70 for x == nil && i < 100 { 71 // TODO: Use a NIST specified DRBG. 72 h.Reset() 73 if err := binary.Write(h, binary.BigEndian, i); err != nil { 74 panic(err) 75 } 76 if _, err := h.Write(m); err != nil { 77 panic(err) 78 } 79 r := []byte{2} // Set point encoding to "compressed", y=0. 80 r = h.Sum(r) 81 x, y = Unmarshal(curve, r[:byteLen+1]) 82 i++ 83 } 84 return 85 } 86 87 var one = big.NewInt(1) 88 89 // H2 hashes to an integer [1,N-1] 90 func H2(m []byte) *big.Int { 91 // NIST SP 800-90A § A.5.1: Simple discard method. 92 byteLen := (curve.BitSize + 7) >> 3 93 h := sha512.New() 94 for i := uint32(0); ; i++ { 95 // TODO: Use a NIST specified DRBG. 96 h.Reset() 97 if err := binary.Write(h, binary.BigEndian, i); err != nil { 98 panic(err) 99 } 100 if _, err := h.Write(m); err != nil { 101 panic(err) 102 } 103 b := h.Sum(nil) 104 k := new(big.Int).SetBytes(b[:byteLen]) 105 if k.Cmp(new(big.Int).Sub(curve.N, one)) == -1 { 106 return k.Add(k, one) 107 } 108 } 109 } 110 111 // Evaluate returns the verifiable unpredictable function evaluated at m 112 func (k PrivateKey) Evaluate(m []byte) (index [32]byte, proof []byte) { 113 nilIndex := [32]byte{} 114 // Prover chooses r <-- [1,N-1] 115 r, _, _, err := elliptic.GenerateKey(curve, rand.Reader) 116 if err != nil { 117 return nilIndex, nil 118 } 119 ri := new(big.Int).SetBytes(r) 120 121 // H = H1(m) 122 Hx, Hy := H1(m) 123 124 // VRF_k(m) = [k]H 125 sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes()) 126 vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes. 127 128 // G is the base point 129 // s = H2(G, H, [k]G, VRF, [r]G, [r]H) 130 rGx, rGy := curve.ScalarBaseMult(r) 131 rHx, rHy := curve.ScalarMult(Hx, Hy, r) 132 var b bytes.Buffer 133 if _, err := b.Write(elliptic.Marshal(curve, curve.Gx, curve.Gy)); err != nil { 134 panic(err) 135 } 136 if _, err := b.Write(elliptic.Marshal(curve, Hx, Hy)); err != nil { 137 panic(err) 138 } 139 if _, err := b.Write(elliptic.Marshal(curve, k.PublicKey.X, k.PublicKey.Y)); err != nil { 140 panic(err) 141 } 142 if _, err := b.Write(vrf); err != nil { 143 panic(err) 144 } 145 if _, err := b.Write(elliptic.Marshal(curve, rGx, rGy)); err != nil { 146 panic(err) 147 } 148 if _, err := b.Write(elliptic.Marshal(curve, rHx, rHy)); err != nil { 149 panic(err) 150 } 151 s := H2(b.Bytes()) 152 153 // t = r−s*k mod N 154 t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D)) 155 t.Mod(t, curve.N) 156 157 // Index = H(vrf) 158 index = sha256.Sum256(vrf) 159 160 // Write s, t, and vrf to a proof blob. Also write leading zeros before s and t 161 // if needed. 162 var buf bytes.Buffer 163 if _, err := buf.Write(make([]byte, 32-len(s.Bytes()))); err != nil { 164 panic(err) 165 } 166 if _, err := buf.Write(s.Bytes()); err != nil { 167 panic(err) 168 } 169 if _, err := buf.Write(make([]byte, 32-len(t.Bytes()))); err != nil { 170 panic(err) 171 } 172 if _, err := buf.Write(t.Bytes()); err != nil { 173 panic(err) 174 } 175 if _, err := buf.Write(vrf); err != nil { 176 panic(err) 177 } 178 179 return index, buf.Bytes() 180 } 181 182 // ProofToHash asserts that proof is correct for m and outputs index. 183 func (pk *PublicKey) ProofToHash(m, proof []byte) (index [32]byte, err error) { 184 nilIndex := [32]byte{} 185 // verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m)) 186 if got, want := len(proof), 64+65; got != want { 187 return nilIndex, ErrInvalidVRF 188 } 189 190 // Parse proof into s, t, and vrf. 191 s := proof[0:32] 192 t := proof[32:64] 193 vrf := proof[64 : 64+65] 194 195 uHx, uHy := elliptic.Unmarshal(curve, vrf) 196 if uHx == nil { 197 return nilIndex, ErrInvalidVRF 198 } 199 200 // [t]G + [s]([k]G) = [t+ks]G 201 tGx, tGy := curve.ScalarBaseMult(t) 202 ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s) 203 tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy) 204 205 // H = H1(m) 206 // [t]H + [s]VRF = [t+ks]H 207 Hx, Hy := H1(m) 208 tHx, tHy := curve.ScalarMult(Hx, Hy, t) 209 sHx, sHy := curve.ScalarMult(uHx, uHy, s) 210 tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy) 211 212 // H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF) 213 // = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H) 214 // = H2(G, H, [k]G, VRF, [r]G, [r]H) 215 var b bytes.Buffer 216 if _, err := b.Write(elliptic.Marshal(curve, curve.Gx, curve.Gy)); err != nil { 217 panic(err) 218 } 219 if _, err := b.Write(elliptic.Marshal(curve, Hx, Hy)); err != nil { 220 panic(err) 221 } 222 if _, err := b.Write(elliptic.Marshal(curve, pk.X, pk.Y)); err != nil { 223 panic(err) 224 } 225 if _, err := b.Write(vrf); err != nil { 226 panic(err) 227 } 228 if _, err := b.Write(elliptic.Marshal(curve, tksGx, tksGy)); err != nil { 229 panic(err) 230 } 231 if _, err := b.Write(elliptic.Marshal(curve, tksHx, tksHy)); err != nil { 232 panic(err) 233 } 234 h2 := H2(b.Bytes()) 235 236 // Left pad h2 with zeros if needed. This will ensure that h2 is padded 237 // the same way s is. 238 var buf bytes.Buffer 239 if _, err := buf.Write(make([]byte, 32-len(h2.Bytes()))); err != nil { 240 panic(err) 241 } 242 if _, err := buf.Write(h2.Bytes()); err != nil { 243 panic(err) 244 } 245 246 if !hmac.Equal(s, buf.Bytes()) { 247 return nilIndex, ErrInvalidVRF 248 } 249 return sha256.Sum256(vrf), nil 250 } 251 252 // Public returns the corresponding public key as bytes. 253 func (k PrivateKey) Public() crypto.PublicKey { 254 return &k.PublicKey 255 }