Enforce low S values, by negating the value (modulo the order) if above order/2.

Reference implementation: b7bba43a14/src/key.cpp (L235-L238)

ht @oleganza
This commit is contained in:
Yurii Rashkovskii 2014-07-31 22:04:14 +02:00
parent 22014931d4
commit b19d0a0232
2 changed files with 13 additions and 2 deletions

View file

@ -25,6 +25,12 @@ type Signature struct {
S *big.Int
}
// curve order and halforder, used to tame ECDSA malleability (see BIP-0062)
var (
order = new(big.Int).Set(S256().N)
halforder = new(big.Int).Rsh(order, 1)
)
// Serialize returns the ECDSA signature in the more strict DER format. Note
// that the serialized bytes returned do not include the appended hash type
// used in Bitcoin signature scripts.
@ -33,10 +39,15 @@ type Signature struct {
//
// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
func (sig *Signature) Serialize() []byte {
// low 'S' malleability breaker
sigS := sig.S
if sigS.Cmp(halforder) == 1 {
sigS = new(big.Int).Sub(order, sigS)
}
// Ensure the encoded bytes for the r and s values are canonical and
// thus suitable for DER encoding.
rb := canonicalizeInt(sig.R)
sb := canonicalizeInt(sig.S)
sb := canonicalizeInt(sigS)
// total length of returned signature is 1 byte for each magic and
// length (6 total), plus lengths of r and s

View file

@ -391,7 +391,7 @@ func TestSignatureSerialize(t *testing.T) {
"valid 3 - s most significant bit is one",
&btcec.Signature{
R: fromHex("1cadddc2838598fee7dc35a12b340c6bde8b389f7bfd19a1252a17c4b5ed2d71"),
S: fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"),
S: new(big.Int).Add(fromHex("00c1a251bbecb14b058a8bd77f65de87e51c47e95904f4c0e9d52eddc21c1415ac"), btcec.S256().N),
},
[]byte{
0x30, 0x45, 0x02, 0x20, 0x1c, 0xad, 0xdd, 0xc2,