btcec: Prevent static initialization of S256
This is achieved by introducing a new variable `halfOrder` on the KoblitzCurve struct that is half the order.
This commit is contained in:
parent
64d60f2ef2
commit
79445fbd97
2 changed files with 10 additions and 11 deletions
|
@ -36,8 +36,9 @@ var (
|
||||||
// interface from crypto/elliptic.
|
// interface from crypto/elliptic.
|
||||||
type KoblitzCurve struct {
|
type KoblitzCurve struct {
|
||||||
*elliptic.CurveParams
|
*elliptic.CurveParams
|
||||||
q *big.Int
|
q *big.Int
|
||||||
H int // cofactor of the curve.
|
H int // cofactor of the curve.
|
||||||
|
halfOrder *big.Int // half the order N
|
||||||
|
|
||||||
// byteSize is simply the bit size / 8 and is provided for convenience
|
// byteSize is simply the bit size / 8 and is provided for convenience
|
||||||
// since it is calculated repeatedly.
|
// since it is calculated repeatedly.
|
||||||
|
@ -912,9 +913,10 @@ func initS256() {
|
||||||
secp256k1.Gx = fromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")
|
secp256k1.Gx = fromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")
|
||||||
secp256k1.Gy = fromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")
|
secp256k1.Gy = fromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")
|
||||||
secp256k1.BitSize = 256
|
secp256k1.BitSize = 256
|
||||||
secp256k1.H = 1
|
|
||||||
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
|
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
|
||||||
big.NewInt(1)), big.NewInt(4))
|
big.NewInt(1)), big.NewInt(4))
|
||||||
|
secp256k1.H = 1
|
||||||
|
secp256k1.halfOrder = new(big.Int).Rsh(secp256k1.N, 1)
|
||||||
|
|
||||||
// Provided for convenience since this gets computed repeatedly.
|
// Provided for convenience since this gets computed repeatedly.
|
||||||
secp256k1.byteSize = secp256k1.BitSize / 8
|
secp256k1.byteSize = secp256k1.BitSize / 8
|
||||||
|
|
|
@ -29,10 +29,6 @@ type Signature struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Curve order and halforder, used to tame ECDSA malleability (see BIP-0062)
|
|
||||||
order = new(big.Int).Set(S256().N)
|
|
||||||
halforder = new(big.Int).Rsh(order, 1)
|
|
||||||
|
|
||||||
// Used in RFC6979 implementation when testing the nonce for correctness
|
// Used in RFC6979 implementation when testing the nonce for correctness
|
||||||
one = big.NewInt(1)
|
one = big.NewInt(1)
|
||||||
|
|
||||||
|
@ -51,8 +47,8 @@ var (
|
||||||
func (sig *Signature) Serialize() []byte {
|
func (sig *Signature) Serialize() []byte {
|
||||||
// low 'S' malleability breaker
|
// low 'S' malleability breaker
|
||||||
sigS := sig.S
|
sigS := sig.S
|
||||||
if sigS.Cmp(halforder) == 1 {
|
if sigS.Cmp(S256().halfOrder) == 1 {
|
||||||
sigS = new(big.Int).Sub(order, sigS)
|
sigS = new(big.Int).Sub(S256().N, sigS)
|
||||||
}
|
}
|
||||||
// Ensure the encoded bytes for the r and s values are canonical and
|
// Ensure the encoded bytes for the r and s values are canonical and
|
||||||
// thus suitable for DER encoding.
|
// thus suitable for DER encoding.
|
||||||
|
@ -420,7 +416,8 @@ func RecoverCompact(curve *KoblitzCurve, signature,
|
||||||
func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
|
func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
|
||||||
|
|
||||||
privkey := privateKey.ToECDSA()
|
privkey := privateKey.ToECDSA()
|
||||||
N := order
|
N := S256().N
|
||||||
|
halfOrder := S256().halfOrder
|
||||||
k := nonceRFC6979(privkey.D, hash)
|
k := nonceRFC6979(privkey.D, hash)
|
||||||
inv := new(big.Int).ModInverse(k, N)
|
inv := new(big.Int).ModInverse(k, N)
|
||||||
r, _ := privkey.Curve.ScalarBaseMult(k.Bytes())
|
r, _ := privkey.Curve.ScalarBaseMult(k.Bytes())
|
||||||
|
@ -438,7 +435,7 @@ func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
|
||||||
s.Mul(s, inv)
|
s.Mul(s, inv)
|
||||||
s.Mod(s, N)
|
s.Mod(s, N)
|
||||||
|
|
||||||
if s.Cmp(halforder) == 1 {
|
if s.Cmp(halfOrder) == 1 {
|
||||||
s.Sub(N, s)
|
s.Sub(N, s)
|
||||||
}
|
}
|
||||||
if s.Sign() == 0 {
|
if s.Sign() == 0 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue