diff options
Diffstat (limited to 'packages/meshbay-common/tests/test_js_python_parity.py')
| -rw-r--r-- | packages/meshbay-common/tests/test_js_python_parity.py | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/packages/meshbay-common/tests/test_js_python_parity.py b/packages/meshbay-common/tests/test_js_python_parity.py index 3887414..5bf34aa 100644 --- a/packages/meshbay-common/tests/test_js_python_parity.py +++ b/packages/meshbay-common/tests/test_js_python_parity.py @@ -22,7 +22,11 @@ from pathlib import Path import pytest from meshbay_common.adminop import admin_transcript -from meshbay_common.handshake import handshake_transcript, webrtc_binding +from meshbay_common.handshake import ( + challenge_transcript, + handshake_transcript, + webrtc_binding, +) from meshbay_common.join import join_transcript CRYPTO_JS = (Path(__file__).resolve().parents[2] @@ -76,7 +80,7 @@ globalThis.crypto = globalThis.crypto || {}; const src = fs.readFileSync(process.argv[2], 'utf8'); const load = new Function( - src + '\nreturn { handshakeTranscript, adminTranscript, joinTranscript, ' + src + '\nreturn { handshakeTranscript, challengeTranscript, adminTranscript, joinTranscript, ' + 'webrtcBinding, b64encode };'); const M = load(); @@ -89,7 +93,7 @@ const toHex = (u8) => Array.from(u8).map(b => b.toString(16).padStart(2, '0')).join(''); const input = JSON.parse(fs.readFileSync(process.argv[3], 'utf8')); -const out = { handshake: [], admin: [], join: [] }; +const out = { handshake: [], challenge: [], admin: [], join: [] }; for (const v of input.handshake) { const binding = M.webrtcBinding(hex(v.offer_fp), hex(v.answer_fp)); @@ -97,6 +101,12 @@ for (const v of input.handshake) { v.role, v.group_id, hex(v.nonce_c), hex(v.nonce_s), binding))); } +for (const v of input.handshake) { + const binding = M.webrtcBinding(hex(v.offer_fp), hex(v.answer_fp)); + out.challenge.push(toHex(M.challengeTranscript( + v.group_id, hex(v.nonce_c), hex(v.nonce_s), binding))); +} + for (const v of input.admin) { out.admin.push(toHex(M.adminTranscript( v.op, v.node_pk, v.group_id, v.subject, M.b64encode(hex(v.nonce)), v.ts))); @@ -167,6 +177,20 @@ def test_handshake_transcript_parity(idx, vector, js_output): ) +@pytest.mark.parametrize("idx,vector", list(enumerate(HANDSHAKE_VECTORS))) +def test_challenge_transcript_parity(idx, vector, js_output): + """ + MNP 3.4. A mismatch means every browser refuses every node that signs its + challenge — the signature is checked, and a wrong one is a refusal. + """ + _, group_id, nonce_c, nonce_s, offer_fp, answer_fp = vector + expected = challenge_transcript( + group_id, bytes.fromhex(nonce_c), bytes.fromhex(nonce_s), + webrtc_binding(bytes.fromhex(offer_fp), bytes.fromhex(answer_fp))) + assert js_output["challenge"][idx] == expected.hex(), ( + f"crypto.js and meshbay_common.handshake disagree for group={group_id!r}") + + @pytest.mark.parametrize("idx,vector", list(enumerate(ADMIN_VECTORS))) def test_admin_transcript_parity(idx, vector, js_output): """ |