Nonce exfiltration defense

Hi guys,

just wanted to check: does foundation passport core enforce deterministic nonces (RFC 6979) to guard against seed exfiltration?

If it does, is it feasible to verify this as follows:

  1. create a test seed and import into passport core and say coldcard
  2. create a spend transaction in sparrow and use both hardware wallets to sign and create a psbt each.
  3. compare both psbt files. If the seed and transaction are identical, the psbt files should be identical.

Being truthful I had to lean on an agent pointed to our codebase for this one, it’s a little outside of my technical wheel house. If you have any follow ups, let me know and I can ask our engineering team.

The answer is yes for ECDSA.

Passport Core signs ECDSA inputs using libsecp256k1’s default nonce function, which is RFC 6979. No auxiliary randomness is mixed in. Sign the same input with the same key twice and you get the identical signature every time.

Taproot is deliberately different. For Schnorr signatures we follow the BIP-340 recommendation and mix in auxiliary randomness, so those signatures are not reproducible and will differ on each signing. That is intentional, it is a defence against fault injection and side channel attacks. So exclude taproot inputs from any test of this kind.

On your test method, the idea is sound but the execution has two problems.

First, the PSBT files will never be byte identical. Different signers include different optional fields, order them differently, and retain different amounts of the original data. Compare the DER signature inside PSBT_IN_PARTIAL_SIG rather than the file.

Second, and more importantly, comparing against another vendor’s device only works if that device also produces a plain RFC 6979 signature with nothing added. Some wallets grind the nonce to obtain a low R value, which saves a byte in the final transaction. A device doing that will produce a different, equally valid signature from the same key and the same sighash. A mismatch would tell you nothing.

A cleaner test only needs one device. Take your test seed, pull the sighash out of the PSBT, and compute the expected RFC 6979 signature yourself with any standard library. Then compare that against what Passport produced. If they match byte for byte, the nonce was derived exactly as specified and there is no room in it to hide key material. Sign the same transaction a second time as a sanity check, and you should get the same bytes again.

That is worth stressing generally. Determinism on its own is not the protection, since a malicious device could still bias its nonce and nothing would look wrong. The protection is that determinism makes the signature externally reproducible, so anyone can check it. If you are going to do this, do the independent computation rather than a device to device comparison.

Use a throwaway seed and do not reuse it afterwards, which I see you were already planning.

hi qna, thank you very much for such a detailed response. I’ll give it a go.

thanks again.

Hi qna,

so i did the following:

  1. using a throwaway seed, created a single sig native segwit testnet transaction
  2. manually assembled the transaction and determined the RFC 6979 signature which perfectly matched the hex value in the txn file produced by passport core.
  3. decoded the psbt file that passport core produced and confirmed it essentially contained the same data as the txn file.
  4. signed the unsigned psbt file in passport core a second time and confirmed the files produced were identical to those created the first time round.

All good :+1:

Awesome, thanks for circling back on this!