optimize: drop DER encoding from signature grinding

This commit is contained in:
scgbckbone 2024-07-18 12:22:20 +02:00 committed by doc-hex
parent 4a1628f9d5
commit ec27f410ea
3 changed files with 18 additions and 10 deletions

View File

@ -6,6 +6,7 @@ This lists the new changes that have not yet been published in a normal release.
- Enhancement: Allow JSON files in `NFC File Share`
- Enhancement: latest [0.5.0](https://github.com/bitcoin-core/secp256k1/releases/tag/v0.5.0) libsecp256k1
- Enhancement: Signature grinding optimizations
- Bugfix: UI ordered list alignment in Seed Vault menu
- Bugfix: Do not alow to import multisig wallet duplicate with only keys shuffled
- Bugfix: Do not read whole PSBT into memory when writing finalized transaction

View File

@ -1960,22 +1960,28 @@ class psbtObject(psbtProxy):
# value that will encode (after DER) into a shorter string.
# - saves on miner's fee (which might be expected/required)
# - blends in with Bitcoin Core signatures which do this from 0.17.0
for retry in range(100):
result = ngu.secp256k1.sign(pk, digest, retry).to_bytes()
# convert signature to DER format
n = 0 # retry num
while True:
# time to produce signature on stm32: ~25100 microseconds
result = ngu.secp256k1.sign(pk, digest, n).to_bytes()
#assert len(result) == 65
r = result[1:33]
s = result[33:65]
der_sig = ser_sig_der(r, s, inp.sighash)
if len(der_sig) <= 71:
if result[1] < 0x80:
# no need to check for low S value as those are generated by default by secp256k1 lib
# to produce 71 bytes long signature (low S low R value) we need on average 2 retries
# worst case ~25 grinding iterations need to be performed totaling
break
n += 1
# wait with der serialization after we have low S and low R sig
r = result[1:33]
s = result[33:65]
der_sig = ser_sig_der(r, s, inp.sighash)
# private key no longer required
stash.blank_object(pk)
stash.blank_object(node)
del pk, node, pu, skp
del pk, node, pu, skp, n
inp.added_sig = (which_key, der_sig)

View File

@ -3000,6 +3000,7 @@ def test_low_R_grinding(dev, goto_home, microsd_path, press_select, offer_ms_imp
reset_seed_words()
clear_ms()
desc = "sh(sortedmulti(2,[6ba6cfd0/45h]tpubD9429UXFGCTKJ9NdiNK4rC5ygqSUkginycYHccqSg5gkmyQ7PZRHNjk99M6a6Y3NY8ctEUUJvCu6iCCui8Ju3xrHRu3Ez1CKB4ZFoRZDdP9/0/*,[747b698e/45h]tpubD97nVL37v5tWyMf9ofh5rznwhh1593WMRg6FT4o6MRJkKWANtwAMHYLrcJFsFmPfYbY1TE1LLQ4KBb84LBPt1ubvFwoosvMkcWJtMwvXgSc/0/*,[7bb026be/45h]tpubD9ArfXowvGHnuECKdGXVKDMfZVGdephVWg8fWGWStH3VKHzT4ph3A4ZcgXWqFu1F5xGTfxncmrnf3sLC86dup2a8Kx7z3xQ3AgeNTQeFxPa/0/*,[0f056943/45h]tpubD8NXmKsmWp3a3DXhbihAYbYLGaRNVdTnr6JoSxxfXYQcmwVtW2hv8QoDwng6JtEonmJoL3cNEwfd2cLXMpGezwZ2vL2dQ7259bueNKj9C8n/0/*))#up0sw2xp"
# PSBT created via fake_ms_txn, grinded in test_ms_sign_myself
psbt_fname = "myself-72sig.psbt"
with open(f"data/{psbt_fname}", "r") as f:
b64psbt = f.read()