github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/crypto/key.go (about) 1 package crypto 2 3 import ( 4 "bytes" 5 "crypto/ecdsa" 6 "crypto/elliptic" 7 "crypto/hmac" 8 "crypto/rand" 9 "crypto/sha256" 10 "crypto/sha512" 11 "encoding/binary" 12 "encoding/hex" 13 "errors" 14 "fmt" 15 "math/big" 16 17 "github.com/sixexorg/magnetic-ring/crypto/secp256k1/bitelliptic" 18 ) 19 20 var ( 21 curve = bitelliptic.S256() 22 params = curve.Params() 23 one = big.NewInt(1) 24 25 ErrInvalidVRF = errors.New("invalid VRF proof") 26 ErrInvalidPubkey = errors.New("invalid secp256k1 public key") 27 ) 28 29 // PrivateKey supports evaluating the VRF function. 30 type PrivateKey interface { 31 // Evaluate returns the output of H(f_k(m)) and its proof. 32 Evaluate(m []byte) (index [32]byte, proof []byte) 33 // Public returns the corresponding public key. 34 Public() PublicKey 35 // Bytes byte array of private key. 36 Bytes() []byte 37 // Sign returns the result of the signature for hash. 38 Sign(hash []byte) ([]byte, error) 39 40 Hex() string 41 } 42 43 // PublicKey supports verifying output from the VRF function. 44 type PublicKey interface { 45 // ProofToHash verifies the NP-proof supplied by Proof and outputs Index. 46 ProofToHash(m, proof []byte) (index [32]byte, err error) 47 // Verify verify hash with signature and public key. 48 Verify(hash, sig []byte) (bool, error) 49 // Bytes byte array of public key. 50 Bytes() []byte 51 Hex() string 52 } 53 54 // GenerateKey 生成带VRF功能的私钥 55 func GenerateKey() (PrivateKey, error) { 56 priv, err := generateEcdsaKey() 57 if err != nil { 58 return nil, err 59 } 60 61 return &VrfablePrivateKey{priv}, nil 62 } 63 64 // ToPrivateKey 将字节数组转换成带VRF功能的私钥 65 func ToPrivateKey(d []byte) (PrivateKey, error) { 66 priv := new(VrfablePrivateKey) 67 ecdsaPriv, err := toECDSA(d) 68 if err != nil { 69 return nil, err 70 } 71 72 priv.PrivateKey = ecdsaPriv 73 return priv, nil 74 } 75 func HexToPrivateKey(hexStr string) (PrivateKey, error) { 76 byteArr, err := hex.DecodeString(hexStr) 77 if err != nil { 78 return nil, err 79 } 80 return ToPrivateKey(byteArr) 81 } 82 83 // UnmarshalPubkey converts bytes to a secp256k1 public key. 84 func UnmarshalPubkey(pub []byte) (PublicKey, error) { 85 x, y := elliptic.Unmarshal(S256(), pub) 86 if x == nil { 87 return nil, ErrInvalidPubkey 88 } 89 90 pubKey := new(VrfablePublicKey) 91 pubKey.PublicKey = &ecdsa.PublicKey{Curve: S256(), X: x, Y: y} 92 return pubKey, nil 93 } 94 95 // PrivateKey holds a private VRF key. 96 type VrfablePrivateKey struct { 97 *ecdsa.PrivateKey 98 } 99 100 // Evaluate returns the verifiable unpredictable function evaluated at m 101 func (k *VrfablePrivateKey) Evaluate(m []byte) (index [32]byte, proof []byte) { 102 nilIndex := [32]byte{} 103 // Prover chooses r <-- [1,N-1] 104 r, _, _, err := generateKeyFromCurve(curve, rand.Reader) 105 if err != nil { 106 return nilIndex, nil 107 } 108 ri := new(big.Int).SetBytes(r) 109 110 // H = H1(m) 111 Hx, Hy := H1(m) 112 113 // VRF_k(m) = [k]H 114 sHx, sHy := curve.ScalarMult(Hx, Hy, k.D.Bytes()) 115 116 // vrf := elliptic.Marshal(curve, sHx, sHy) // 65 bytes. 117 vrf := curve.Marshal(sHx, sHy) // 65 bytes. 118 119 // G is the base point 120 // s = H2(G, H, [k]G, VRF, [r]G, [r]H) 121 rGx, rGy := curve.ScalarBaseMult(r) 122 rHx, rHy := curve.ScalarMult(Hx, Hy, r) 123 var b bytes.Buffer 124 b.Write(curve.Marshal(params.Gx, params.Gy)) 125 b.Write(curve.Marshal(Hx, Hy)) 126 b.Write(curve.Marshal(k.PublicKey.X, k.PublicKey.Y)) 127 b.Write(vrf) 128 b.Write(curve.Marshal(rGx, rGy)) 129 b.Write(curve.Marshal(rHx, rHy)) 130 s := H2(b.Bytes()) 131 132 // t = r−s*k mod N 133 t := new(big.Int).Sub(ri, new(big.Int).Mul(s, k.D)) 134 t.Mod(t, params.N) 135 136 // Index = H(vrf) 137 index = sha256.Sum256(vrf) 138 139 // Write s, t, and vrf to a proof blob. Also write leading zeros before s and t 140 // if needed. 141 var buf bytes.Buffer 142 buf.Write(make([]byte, 32-len(s.Bytes()))) 143 buf.Write(s.Bytes()) 144 buf.Write(make([]byte, 32-len(t.Bytes()))) 145 buf.Write(t.Bytes()) 146 buf.Write(vrf) 147 148 return index, buf.Bytes() 149 } 150 151 // Public returns the corresponding public key as bytes. 152 func (k *VrfablePrivateKey) Public() PublicKey { 153 return &VrfablePublicKey{&k.PublicKey} 154 } 155 156 func (k *VrfablePrivateKey) Bytes() []byte { 157 priv := k.PrivateKey 158 return paddedBigBytes(priv.D, priv.Params().BitSize/8) 159 } 160 161 func (k *VrfablePrivateKey) Sign(hash []byte) ([]byte, error) { 162 return Sign(k.PrivateKey, hash) 163 } 164 func (k *VrfablePrivateKey) Hex() string { 165 return hex.EncodeToString(k.Bytes()) 166 } 167 168 func (k *VrfablePrivateKey) Clear(hash []byte) ([]byte, error) { 169 fmt.Printf("%s\n", k.D) 170 return Sign(k.PrivateKey, hash) 171 } 172 173 // PublicKey holds a public VRF key. 174 type VrfablePublicKey struct { 175 *ecdsa.PublicKey 176 } 177 178 func (pk *VrfablePublicKey) Verify(hash, sig []byte) (bool, error) { 179 return Verify(pk.PublicKey, hash, sig) 180 } 181 182 func (pk *VrfablePublicKey) Bytes() []byte { 183 pub := pk.PublicKey 184 if pub == nil || pub.X == nil || pub.Y == nil { 185 return nil 186 } 187 188 return elliptic.Marshal(curve, pub.X, pub.Y) 189 } 190 func (pk *VrfablePublicKey) Hex() string { 191 return hex.EncodeToString(pk.Bytes()) 192 } 193 194 // ProofToHash asserts that proof is correct for m and outputs index. 195 func (pk *VrfablePublicKey) ProofToHash(m, proof []byte) (index [32]byte, err error) { 196 nilIndex := [32]byte{} 197 // verifier checks that s == H2(m, [t]G + [s]([k]G), [t]H1(m) + [s]VRF_k(m)) 198 if got, want := len(proof), 64+65; got != want { 199 return nilIndex, ErrInvalidVRF 200 } 201 202 // Parse proof into s, t, and vrf. 203 s := proof[0:32] 204 t := proof[32:64] 205 vrf := proof[64 : 64+65] 206 207 // uHx, uHy := elliptic.Unmarshal(curve, vrf) 208 uHx, uHy := curve.Unmarshal(vrf) //////??? 209 if uHx == nil { 210 return nilIndex, ErrInvalidVRF 211 } 212 213 // [t]G + [s]([k]G) = [t+ks]G 214 tGx, tGy := curve.ScalarBaseMult(t) 215 ksGx, ksGy := curve.ScalarMult(pk.X, pk.Y, s) 216 tksGx, tksGy := curve.Add(tGx, tGy, ksGx, ksGy) 217 218 // H = H1(m) 219 // [t]H + [s]VRF = [t+ks]H 220 Hx, Hy := H1(m) 221 tHx, tHy := curve.ScalarMult(Hx, Hy, t) 222 sHx, sHy := curve.ScalarMult(uHx, uHy, s) 223 tksHx, tksHy := curve.Add(tHx, tHy, sHx, sHy) 224 225 // H2(G, H, [k]G, VRF, [t]G + [s]([k]G), [t]H + [s]VRF) 226 // = H2(G, H, [k]G, VRF, [t+ks]G, [t+ks]H) 227 // = H2(G, H, [k]G, VRF, [r]G, [r]H) 228 var b bytes.Buffer 229 b.Write(curve.Marshal(params.Gx, params.Gy)) 230 b.Write(curve.Marshal(Hx, Hy)) 231 b.Write(curve.Marshal(pk.X, pk.Y)) 232 b.Write(vrf) 233 b.Write(curve.Marshal(tksGx, tksGy)) 234 b.Write(curve.Marshal(tksHx, tksHy)) 235 h2 := H2(b.Bytes()) 236 237 // Left pad h2 with zeros if needed. This will ensure that h2 is padded 238 // the same way s is. 239 var buf bytes.Buffer 240 buf.Write(make([]byte, 32-len(h2.Bytes()))) 241 buf.Write(h2.Bytes()) 242 243 if !hmac.Equal(s, buf.Bytes()) { 244 return nilIndex, ErrInvalidVRF 245 } 246 return sha256.Sum256(vrf), nil 247 } 248 249 func H1(m []byte) (x, y *big.Int) { 250 h := sha512.New() 251 var i uint32 252 byteLen := (params.BitSize + 7) >> 3 253 for x == nil && i < 100 { 254 // TODO: Use a NIST specified DRBG. 255 h.Reset() 256 binary.Write(h, binary.BigEndian, i) 257 h.Write(m) 258 r := []byte{2} // Set point encoding to "compressed", y=0. 259 r = h.Sum(r) 260 x, y = Unmarshal(curve, r[:byteLen+1]) 261 i++ 262 } 263 264 return 265 } 266 267 // H2 hashes to an integer [1,N-1] 268 func H2(m []byte) *big.Int { 269 // NIST SP 800-90A § A.5.1: Simple discard method. 270 byteLen := (params.BitSize + 7) >> 3 271 h := sha512.New() 272 for i := uint32(0); ; i++ { 273 // TODO: Use a NIST specified DRBG. 274 h.Reset() 275 binary.Write(h, binary.BigEndian, i) 276 h.Write(m) 277 b := h.Sum(nil) 278 k := new(big.Int).SetBytes(b[:byteLen]) 279 if k.Cmp(new(big.Int).Sub(params.N, one)) == -1 { 280 return k.Add(k, one) 281 } 282 } 283 } 284 285 // Unmarshal a compressed point in the form specified in section 4.3.6 of ANSI X9.62. 286 func Unmarshal(curve elliptic.Curve, data []byte) (x, y *big.Int) { 287 byteLen := (curve.Params().BitSize + 7) >> 3 288 if (data[0] &^ 1) != 2 { 289 return // unrecognized point encoding 290 } 291 if len(data) != 1+byteLen { 292 return 293 } 294 295 // Based on Routine 2.2.4 in NIST Mathematical routines paper 296 params := curve.Params() 297 tx := new(big.Int).SetBytes(data[1 : 1+byteLen]) 298 y2 := y2(params, tx) 299 sqrt := defaultSqrt 300 ty := sqrt(y2, params.P) 301 if ty == nil { 302 return // "y^2" is not a square: invalid point 303 } 304 var y2c big.Int 305 y2c.Mul(ty, ty).Mod(&y2c, params.P) 306 if y2c.Cmp(y2) != 0 { 307 return // sqrt(y2)^2 != y2: invalid point 308 } 309 if ty.Bit(0) != uint(data[0]&1) { 310 ty.Sub(params.P, ty) 311 } 312 313 x, y = tx, ty // valid point: return it 314 return 315 } 316 317 // Use the curve equation to calculate y² given x. 318 // only applies to curves of the form y² = x³ - 3x + b. 319 func y2(curve *elliptic.CurveParams, x *big.Int) *big.Int { 320 321 // y² = x³ - 3x + b 322 //x3 := new(big.Int).Mul(x, x) 323 //x3.Mul(x3, x) 324 // 325 //threeX := new(big.Int).Lsh(x, 1) 326 //threeX.Add(threeX, x) 327 // 328 //x3.Sub(x3, threeX) 329 //x3.Add(x3, curve.B) 330 //x3.Mod(x3, curve.P) 331 332 // change to bitelliptic : y² = x³ + b 333 x3 := new(big.Int).Mul(x, x) 334 x3.Mul(x3, x) 335 336 x3.Add(x3, curve.B) 337 x3.Mod(x3, curve.P) 338 return x3 339 } 340 341 func defaultSqrt(x, p *big.Int) *big.Int { 342 var r big.Int 343 if nil == r.ModSqrt(x, p) { 344 return nil // x is not a square 345 } 346 return &r 347 }