Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/utxo-lib/bip-0327/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__pycache__/
31 changes: 31 additions & 0 deletions modules/utxo-lib/bip-0327/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,37 @@ The test suite runs:
4. BitGo legacy p2tr tests
5. BitGo standard p2trMusig2 tests

### TypeScript Cross-Validation Tests

The `test_typescript_fixtures.py` script validates that the Python reference implementation produces identical results to the TypeScript implementation:

```bash
cd modules/utxo-lib/bip-0327
python3 test_typescript_fixtures.py
```

These tests read JSON fixtures from the `musig2/` directory, which are generated by the TypeScript test suite in `test/bitgo/psbt/Musig2Methods.ts`. The fixtures contain:

- **createTapInternalKey.json** - Key aggregation results
- **createTapOutputKey.json** - Tweaked aggregate key results
- **createTapTweak.json** - Taproot tweak computation
- **createAggregateNonce.json** - Nonce aggregation results
- **createMusig2SigningSession.json** - Session context creation
- **musig2PartialSignAndVerify.json** - Partial signature verification
- **musig2AggregateSigs.json** - Signature aggregation and final verification
- **fullSigningFlow.json** - Complete end-to-end signing workflow

The cross-validation tests ensure that:
1. Key aggregation produces identical aggregate public keys
2. Taproot tweaking produces identical output keys
3. Deterministic nonce generation produces identical nonces (using session IDs `0x0101...` and `0x0202...`)
4. Partial signature generation produces identical signatures
5. Partial signature verification works identically
6. Signature aggregation produces identical results
7. Final Schnorr signature verification succeeds in both implementations

The tests use fully deterministic nonce generation with fixed session IDs to ensure bit-for-bit identical outputs between Python and TypeScript. This provides strong confidence that the TypeScript and Python implementations are compatible and produce identical cryptographic outputs at every step of the MuSig2 protocol.

## References

- [BIP327 Specification](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki)
Expand Down
412 changes: 412 additions & 0 deletions modules/utxo-lib/bip-0327/test_typescript_fixtures.py

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions modules/utxo-lib/bip-0327/tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ set -e
cd "$(dirname "$0")"
mypy --no-error-summary reference.py
python3 reference.py
python3 test_typescript_fixtures.py
python3 gen_vectors_helper.py > /dev/null
1 change: 1 addition & 0 deletions modules/utxo-lib/bip-0327/utxolibMusig2
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"inputs": {
"pubNonces": [
"027389d7aa456cbe418467f42928601462d77000c3b260e5127f1111b57588b35e036f13a501e1708aa7288a313d71975324e0de1d129acff61e40e1c96ae5976c29",
"02949960a953f58a5bad40d8c6161bac10a52a971a37cfe858ba4a1452524b1691026dca4ba06a76389621d0d5a6965976120eb9dac6b861cf32d674c65e080a7c13"
]
},
"output": {
"aggregateNonce": "0233086bdf4150163179ef61beed827f55b073563e8bde58755ed8bcddc00635a902418bed8a65d3ee02007694fb18b5a1ec202d8b69ece07e2d54dd193ef7373b88"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"inputs": {
"pubNonces": [
"027389d7aa456cbe418467f42928601462d77000c3b260e5127f1111b57588b35e036f13a501e1708aa7288a313d71975324e0de1d129acff61e40e1c96ae5976c29",
"02949960a953f58a5bad40d8c6161bac10a52a971a37cfe858ba4a1452524b1691026dca4ba06a76389621d0d5a6965976120eb9dac6b861cf32d674c65e080a7c13"
],
"txHash": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"pubKeys": [
"03e9fc8f605f59d6a4f5ceb0d27852151013f2bf1965f9adf44ce9ba9821c7f106",
"030710ec162d2199bb828e5d8760f16d65412bbb2c85ec13fe027f77d83a349c62"
],
"internalPubKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapTreeRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"output": {
"sessionKey": {
"aggNonce": "0233086bdf4150163179ef61beed827f55b073563e8bde58755ed8bcddc00635a902418bed8a65d3ee02007694fb18b5a1ec202d8b69ece07e2d54dd193ef7373b88",
"msg": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"publicKey": "04e5406bdcc45b02e86b30c446fd57375e8bfc8144238d61033d353c8a3641a43d5bc152f290f28255baf6bf18c5de0d67f81921fc4e1c05c3c5625eb7784eab01"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"inputs": {
"pubKeys": [
"03e9fc8f605f59d6a4f5ceb0d27852151013f2bf1965f9adf44ce9ba9821c7f106",
"030710ec162d2199bb828e5d8760f16d65412bbb2c85ec13fe027f77d83a349c62"
]
},
"output": {
"tapInternalKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"inputs": {
"internalPubKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapTreeRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"output": {
"tapOutputKey": "e5406bdcc45b02e86b30c446fd57375e8bfc8144238d61033d353c8a3641a43d"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"inputs": {
"tapInternalKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapMerkleRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"output": {
"tapTweak": "c990a77a31b07eea9d1a616bfe80bd33ba2a7e2a22db0e900a168d87a5e01a2c"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"staticInputs": {
"pubKeys": [
"03e9fc8f605f59d6a4f5ceb0d27852151013f2bf1965f9adf44ce9ba9821c7f106",
"030710ec162d2199bb828e5d8760f16d65412bbb2c85ec13fe027f77d83a349c62"
],
"privateKeys": [
"210169d3bfff26ee7e1f3a22ba61e3d37186b195a2445a66c36adcc987c80e1c",
"b88806edcd0d7446c8d12f8566874ec1ab38fc4a051a477275086800809245da"
],
"txHash": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"tapTreeRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"step1_tapKeys": {
"internalPubKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapOutputKey": "e5406bdcc45b02e86b30c446fd57375e8bfc8144238d61033d353c8a3641a43d",
"tapTweak": "c990a77a31b07eea9d1a616bfe80bd33ba2a7e2a22db0e900a168d87a5e01a2c"
},
"step2_nonces": {
"pubNonce1": "027389d7aa456cbe418467f42928601462d77000c3b260e5127f1111b57588b35e036f13a501e1708aa7288a313d71975324e0de1d129acff61e40e1c96ae5976c29",
"pubNonce2": "02949960a953f58a5bad40d8c6161bac10a52a971a37cfe858ba4a1452524b1691026dca4ba06a76389621d0d5a6965976120eb9dac6b861cf32d674c65e080a7c13"
},
"step3_aggregateNonce": {
"aggregateNonce": "0233086bdf4150163179ef61beed827f55b073563e8bde58755ed8bcddc00635a902418bed8a65d3ee02007694fb18b5a1ec202d8b69ece07e2d54dd193ef7373b88"
},
"step4_sessionKey": {
"aggNonce": "0233086bdf4150163179ef61beed827f55b073563e8bde58755ed8bcddc00635a902418bed8a65d3ee02007694fb18b5a1ec202d8b69ece07e2d54dd193ef7373b88",
"msg": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"publicKey": "04e5406bdcc45b02e86b30c446fd57375e8bfc8144238d61033d353c8a3641a43d5bc152f290f28255baf6bf18c5de0d67f81921fc4e1c05c3c5625eb7784eab01"
},
"step5_partialSigs": {
"partialSig1": "218f2cb5d0b24927b11094d2c78da7a4e1d0de9ba29d59e49312c48f216570c4",
"partialSig2": "53d90faeb634bc5f2f9c3bceb303b958b8f4cf5054b3fb55c8b35dc662bd15e4"
},
"step6_verification": {
"isValid1": true,
"isValid2": true
},
"step7_aggregation": {
"aggregatedSig": "1d6242dc3116fbb280482a2ad57f4167c3843d397df5da02fc6235030e0bbe24758f2be5356e937c5f4ecee1b0dd632f0a1615974065e4a89bdc385006f41b9b"
},
"step8_finalVerification": {
"isValidFinal": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"inputs": {
"partialSigs": [
"218f2cb5d0b24927b11094d2c78da7a4e1d0de9ba29d59e49312c48f216570c4",
"53d90faeb634bc5f2f9c3bceb303b958b8f4cf5054b3fb55c8b35dc662bd15e4"
],
"pubKeys": [
"03e9fc8f605f59d6a4f5ceb0d27852151013f2bf1965f9adf44ce9ba9821c7f106",
"030710ec162d2199bb828e5d8760f16d65412bbb2c85ec13fe027f77d83a349c62"
],
"txHash": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"internalPubKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapTreeRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"output": {
"aggregatedSig": "1d6242dc3116fbb280482a2ad57f4167c3843d397df5da02fc6235030e0bbe24758f2be5356e937c5f4ecee1b0dd632f0a1615974065e4a89bdc385006f41b9b",
"tapOutputKey": "e5406bdcc45b02e86b30c446fd57375e8bfc8144238d61033d353c8a3641a43d",
"isValidAggregated": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"inputs": {
"privateKeys": [
"210169d3bfff26ee7e1f3a22ba61e3d37186b195a2445a66c36adcc987c80e1c",
"b88806edcd0d7446c8d12f8566874ec1ab38fc4a051a477275086800809245da"
],
"pubNonces": [
"027389d7aa456cbe418467f42928601462d77000c3b260e5127f1111b57588b35e036f13a501e1708aa7288a313d71975324e0de1d129acff61e40e1c96ae5976c29",
"02949960a953f58a5bad40d8c6161bac10a52a971a37cfe858ba4a1452524b1691026dca4ba06a76389621d0d5a6965976120eb9dac6b861cf32d674c65e080a7c13"
],
"pubKeys": [
"03e9fc8f605f59d6a4f5ceb0d27852151013f2bf1965f9adf44ce9ba9821c7f106",
"030710ec162d2199bb828e5d8760f16d65412bbb2c85ec13fe027f77d83a349c62"
],
"txHash": "d11d3b06a83bb14c95fad947da2192ad9f6faee3c0fb36ad197a05f943aa7acd",
"internalPubKey": "6d767a69e03d4611485407d777711ee4d1321a84cf82f591db0cd3e179c49821",
"tapTreeRoot": "63a3684763dca2d4bb5d412d01f5ce73214af3d7816b52d7ad549562cc4cd890"
},
"output": {
"partialSigs": [
"218f2cb5d0b24927b11094d2c78da7a4e1d0de9ba29d59e49312c48f216570c4",
"53d90faeb634bc5f2f9c3bceb303b958b8f4cf5054b3fb55c8b35dc662bd15e4"
],
"verificationResults": [
true,
true
]
}
}
Loading