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:
parent
22014931d4
commit
b19d0a0232
2 changed files with 13 additions and 2 deletions
13
signature.go
13
signature.go
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue