Component: lockbox/src/enclave.cpp, lockbox/src/db_manager.cpp, lockbox/src/sqlite_db_manager.cpp
Severity: Open question (potential MuSig nonce reuse → server key-share extraction if the same secnonce signs twice)
Summary
The lockbox partial-sign path (enclave.cpp ~L150-190) decrypts a stored encrypted_secnonce with the seed and calls secp256k1_blinded_musig_partial_sign_without_keyaggcoeff. MuSig nonce reuse across two different challenges leaks the server's key share.
Mercury-side defenses exist (per-signing_id nonce leases, challenge pinning per record, replay classifiers in bip448_sign.rs), but the review did not confirm the enclave-side lifecycle:
- After a successful partial sign, is the
encrypted_secnonce row deleted/marked consumed in the lockbox DB?
- If Mercury replays
sign/second with the same signing_id but a different blinded session (the Mercury endpoint currently 409-Conflicts this — does the lockbox additionally enforce it?), does the lockbox refuse before decrypting the nonce?
- On crash between partial-sign and DB commit, can the nonce be reused?
If any answer is "no", a compromised Mercury (or a retry race) could extract the server key share.
Suggested direction
Single-use nonce semantics inside the lockbox DB (consume-on-read in the same transaction as the sign), independent of Mercury's lease layer. Add an adversarial test: two sign/second calls, same signing_id, different challenges → second must fail without producing a signature.
Found during security review of feature/bip448-web-wallet-mutinynet @ 64d2423.
Component:
lockbox/src/enclave.cpp,lockbox/src/db_manager.cpp,lockbox/src/sqlite_db_manager.cppSeverity: Open question (potential MuSig nonce reuse → server key-share extraction if the same secnonce signs twice)
Summary
The lockbox partial-sign path (
enclave.cpp~L150-190) decrypts a storedencrypted_secnoncewith the seed and callssecp256k1_blinded_musig_partial_sign_without_keyaggcoeff. MuSig nonce reuse across two different challenges leaks the server's key share.Mercury-side defenses exist (per-signing_id nonce leases, challenge pinning per record, replay classifiers in
bip448_sign.rs), but the review did not confirm the enclave-side lifecycle:encrypted_secnoncerow deleted/marked consumed in the lockbox DB?sign/secondwith the same signing_id but a different blinded session (the Mercury endpoint currently 409-Conflicts this — does the lockbox additionally enforce it?), does the lockbox refuse before decrypting the nonce?If any answer is "no", a compromised Mercury (or a retry race) could extract the server key share.
Suggested direction
Single-use nonce semantics inside the lockbox DB (consume-on-read in the same transaction as the sign), independent of Mercury's lease layer. Add an adversarial test: two sign/second calls, same signing_id, different challenges → second must fail without producing a signature.
Found during security review of
feature/bip448-web-wallet-mutinynet@ 64d2423.