rfc6979/ecdsa.go

56 lines
1.3 KiB
Go
Raw Normal View History

2013-08-21 00:35:15 +00:00
package rfc6979
import (
"crypto/ecdsa"
"crypto/elliptic"
"math/big"
)
2013-08-27 02:48:12 +00:00
// copied from crypto/ecdsa
2013-08-21 00:35:15 +00:00
func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
orderBits := c.Params().N.BitLen()
orderBytes := (orderBits + 7) / 8
if len(hash) > orderBytes {
hash = hash[:orderBytes]
}
ret := new(big.Int).SetBytes(hash)
excess := len(hash)*8 - orderBits
if excess > 0 {
ret.Rsh(ret, uint(excess))
}
return ret
}
// SignECDSA signs an arbitrary length hash (which should be the result of
// hashing a larger message) using the private key, priv. It returns the
// signature as a pair of integers.
2013-08-21 00:35:15 +00:00
//
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
// to the byte-length of the subgroup. This function does not perform that
// truncation itself.
func SignECDSA(priv *ecdsa.PrivateKey, hash []byte, alg HashFunc) (r, s *big.Int, err error) {
2013-08-21 00:35:15 +00:00
c := priv.PublicKey.Curve
N := c.Params().N
generateSecret(N, priv.D, alg, hash, func(k *big.Int) bool {
inv := new(big.Int).ModInverse(k, N)
2013-08-21 00:35:15 +00:00
r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
r.Mod(r, N)
if r.Sign() == 0 {
return false
}
e := hashToInt(hash, c)
s = new(big.Int).Mul(priv.D, r)
s.Add(s, e)
s.Mul(s, inv)
2013-08-21 00:35:15 +00:00
s.Mod(s, N)
return s.Sign() != 0
})
return
}