Skip to content

Commit

Permalink
Modify the function of SignCanonical in btcec, do makeCompact after i…
Browse files Browse the repository at this point in the history
…sCanonicalSig.

Since function recoverKeyFromSignature is called inside function makeCompact, the performance loss calculated by function recoverKeyFromSignature is relatively large.
So do makeCompact after isCanonicalSig can reduce the number of times it is executed, when isCanonicalSig is false then continue the next loop.
The average performance improvement after modification is nearly 40%-50%.
  • Loading branch information
yjwxfq authored Sep 2, 2024
1 parent 54ee017 commit 480235a
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions btcsuite/btcd/btcec/privkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,23 @@ func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {

// SignCanonical goes through signatures and returns only a canonical
// representations. This matches the EOS blockchain expectations.
// do isCanonical before compactSig, for performance improvement
func (p *PrivateKey) SignCanonical(curve *KoblitzCurve, hash []byte) ([]byte, error) {
for i := 0; i < 25; i++ {
sig, err := signRFC6979(p, hash, i)
if err != nil {
return nil, err
}

compactSig, err := makeCompact(curve, sig, p, hash, true)
if err != nil {
if !isCanonicalSig(sig.R.Bytes(), sig.S.Bytes()) {
continue
}

if isCanonical(compactSig) {
return compactSig, nil
compactSig, err := makeCompact(curve, sig, p, hash, true)
if err != nil {
continue
}
return compactSig, nil
}
return nil, errors.New("couldn't find a canonical signature")
}
Expand Down Expand Up @@ -110,3 +112,14 @@ func isCanonical(compactSig []byte) bool {
t4 := !(d[33] == 0 && ((d[34] & 0x80) == 0))
return t1 && t2 && t3 && t4
}

// add function for original signature, do isCanonical before compactSig
func isCanonicalSig(r []byte, s []byte) bool {
rlen := len(r)
slen := len(s)
t1 := rlen < 32 || (r[0] & 0x80) == 0
t2 := !( (rlen < 32 || r[0] == 0) && ((rlen >= 31 && (r[rlen-31] & 0x80) == 0) || rlen < 31) )
t3 := slen < 32 || (s[0] & 0x80) == 0
t4 := !( (slen < 32 || s[0] == 0) && ((slen >= 31 && (s[slen-31] & 0x80) == 0) || slen < 31) )
return t1 && t2 && t3 && t4
}

0 comments on commit 480235a

Please sign in to comment.