From f049a713c1ba6749bd7155ce7fb5e1da7271096f Mon Sep 17 00:00:00 2001 From: yjwxfq <112159687+yjwxfq@users.noreply.github.com> Date: Tue, 27 Aug 2024 10:57:16 +0800 Subject: [PATCH] Modify the function of SignCanonical in btcec, do makeCompact after isCanonicalSig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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%. --- btcsuite/btcd/btcec/privkey.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/btcsuite/btcd/btcec/privkey.go b/btcsuite/btcd/btcec/privkey.go index d8c6417f..1a371253 100644 --- a/btcsuite/btcd/btcec/privkey.go +++ b/btcsuite/btcd/btcec/privkey.go @@ -72,14 +72,15 @@ func (p *PrivateKey) SignCanonical(curve *KoblitzCurve, hash []byte) ([]byte, er 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") } @@ -110,3 +111,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 +}