github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/crypto/ecdsa/ecdsa.go (about) 1 // Copyright 2011 The Go Authors. 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 // Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as 6 // defined in FIPS 186-3. 7 package ecdsa 8 9 // References: 10 // [NSA]: Suite B implementer's guide to FIPS 186-3, 11 // http://www.nsa.gov/ia/_files/ecdsa.pdf 12 // [SECG]: SECG, SEC1 13 // http://www.secg.org/download/aid-780/sec1-v2.pdf 14 15 import ( 16 "crypto" 17 "crypto/elliptic" 18 "encoding/asn1" 19 "io" 20 "math/big" 21 ) 22 23 // PublicKey represents an ECDSA public key. 24 type PublicKey struct { 25 elliptic.Curve 26 X, Y *big.Int 27 } 28 29 // PrivateKey represents a ECDSA private key. 30 type PrivateKey struct { 31 PublicKey 32 D *big.Int 33 } 34 35 type ecdsaSignature struct { 36 R, S *big.Int 37 } 38 39 // Public returns the public key corresponding to priv. 40 func (priv *PrivateKey) Public() crypto.PublicKey { 41 return &priv.PublicKey 42 } 43 44 // Sign signs msg with priv, reading randomness from rand. This method is 45 // intended to support keys where the private part is kept in, for example, a 46 // hardware module. Common uses should use the Sign function in this package 47 // directly. 48 func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) { 49 r, s, err := Sign(rand, priv, msg) 50 if err != nil { 51 return nil, err 52 } 53 54 return asn1.Marshal(ecdsaSignature{r, s}) 55 } 56 57 var one = new(big.Int).SetInt64(1) 58 59 // randFieldElement returns a random element of the field underlying the given 60 // curve using the procedure given in [NSA] A.2.1. 61 func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) { 62 params := c.Params() 63 b := make([]byte, params.BitSize/8+8) 64 _, err = io.ReadFull(rand, b) 65 if err != nil { 66 return 67 } 68 69 k = new(big.Int).SetBytes(b) 70 n := new(big.Int).Sub(params.N, one) 71 k.Mod(k, n) 72 k.Add(k, one) 73 return 74 } 75 76 // GenerateKey generates a public and private key pair. 77 func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) { 78 k, err := randFieldElement(c, rand) 79 if err != nil { 80 return 81 } 82 83 priv = new(PrivateKey) 84 priv.PublicKey.Curve = c 85 priv.D = k 86 priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) 87 return 88 } 89 90 // hashToInt converts a hash value to an integer. There is some disagreement 91 // about how this is done. [NSA] suggests that this is done in the obvious 92 // manner, but [SECG] truncates the hash to the bit-length of the curve order 93 // first. We follow [SECG] because that's what OpenSSL does. Additionally, 94 // OpenSSL right shifts excess bits from the number if the hash is too large 95 // and we mirror that too. 96 func hashToInt(hash []byte, c elliptic.Curve) *big.Int { 97 orderBits := c.Params().N.BitLen() 98 orderBytes := (orderBits + 7) / 8 99 if len(hash) > orderBytes { 100 hash = hash[:orderBytes] 101 } 102 103 ret := new(big.Int).SetBytes(hash) 104 excess := len(hash)*8 - orderBits 105 if excess > 0 { 106 ret.Rsh(ret, uint(excess)) 107 } 108 return ret 109 } 110 111 // fermatInverse calculates the inverse of k in GF(P) using Fermat's method. 112 // This has better constant-time properties than Euclid's method (implemented 113 // in math/big.Int.ModInverse) although math/big itself isn't strictly 114 // constant-time so it's not perfect. 115 func fermatInverse(k, N *big.Int) *big.Int { 116 two := big.NewInt(2) 117 nMinus2 := new(big.Int).Sub(N, two) 118 return new(big.Int).Exp(k, nMinus2, N) 119 } 120 121 // Sign signs an arbitrary length hash (which should be the result of hashing a 122 // larger message) using the private key, priv. It returns the signature as a 123 // pair of integers. The security of the private key depends on the entropy of 124 // rand. 125 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) { 126 // See [NSA] 3.4.1 127 c := priv.PublicKey.Curve 128 N := c.Params().N 129 130 var k, kInv *big.Int 131 for { 132 for { 133 k, err = randFieldElement(c, rand) 134 if err != nil { 135 r = nil 136 return 137 } 138 139 kInv = fermatInverse(k, N) 140 r, _ = priv.Curve.ScalarBaseMult(k.Bytes()) 141 r.Mod(r, N) 142 if r.Sign() != 0 { 143 break 144 } 145 } 146 147 e := hashToInt(hash, c) 148 s = new(big.Int).Mul(priv.D, r) 149 s.Add(s, e) 150 s.Mul(s, kInv) 151 s.Mod(s, N) 152 if s.Sign() != 0 { 153 break 154 } 155 } 156 157 return 158 } 159 160 // Verify verifies the signature in r, s of hash using the public key, pub. Its 161 // return value records whether the signature is valid. 162 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { 163 // See [NSA] 3.4.2 164 c := pub.Curve 165 N := c.Params().N 166 167 if r.Sign() == 0 || s.Sign() == 0 { 168 return false 169 } 170 if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 171 return false 172 } 173 e := hashToInt(hash, c) 174 w := new(big.Int).ModInverse(s, N) 175 176 u1 := e.Mul(e, w) 177 u1.Mod(u1, N) 178 u2 := w.Mul(r, w) 179 u2.Mod(u2, N) 180 181 x1, y1 := c.ScalarBaseMult(u1.Bytes()) 182 x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes()) 183 x, y := c.Add(x1, y1, x2, y2) 184 if x.Sign() == 0 && y.Sign() == 0 { 185 return false 186 } 187 x.Mod(x, N) 188 return x.Cmp(r) == 0 189 }