gabriel / muse public
test_seed_zeroing.py python
87 lines 3.3 KB
Raw
sha256:e8214e0062ef8ef0af999937df2731655b6082781fc22bc563f58db2f42b1de9 Merge 'bump/muse-v0.2.1' into 'dev' — proposal: chore: bump… Human 5 days ago
1 """Tests for mnemonic_to_seed memory zeroing.
2
3 mnemonic_to_seed previously returned immutable ``bytes`` — the 64-byte root
4 seed lingered in the Python heap indefinitely with no way for callers to wipe
5 it. Because the seed is the master secret from which *every* derived key
6 flows, this is a critical residual-memory exposure.
7
8 Fix:
9 - mnemonic_to_seed now returns bytearray so callers can zero it after use.
10 - All call sites in auth.py zero the seed bytearray immediately after the
11 last use (operator_seed, agent_sub_seed, seed).
12
13 Coverage
14 --------
15 I Return type is bytearray
16 I1 mnemonic_to_seed returns bytearray, not bytes
17
18 II Callers can zero the returned value
19 II1 returned bytearray can be overwritten in-place
20
21 III Correctness unaffected
22 III1 same inputs → same 64-byte output (determinism preserved)
23 III2 output length is always 64 bytes
24 III3 passphrase variant produces different seed (BIP39 spec)
25 """
26
27 from __future__ import annotations
28
29 import pytest
30
31 from muse.core.bip39 import mnemonic_to_seed
32
33 _MNEMONIC = (
34 "abandon abandon abandon abandon abandon abandon abandon abandon "
35 "abandon abandon abandon about"
36 )
37
38
39 # ---------------------------------------------------------------------------
40 # I Return type is bytearray
41 # ---------------------------------------------------------------------------
42
43 class TestReturnType:
44 def test_I1_returns_bytearray(self) -> None:
45 """I1: mnemonic_to_seed must return bytearray so callers can zero it."""
46 result = mnemonic_to_seed(_MNEMONIC)
47 assert isinstance(result, bytearray), (
48 f"Expected bytearray, got {type(result).__name__}"
49 )
50
51
52 # ---------------------------------------------------------------------------
53 # II Callers can zero the returned value
54 # ---------------------------------------------------------------------------
55
56 class TestCallerCanZero:
57 def test_II1_returned_bytearray_is_mutable(self) -> None:
58 """II1: the returned bytearray can be overwritten in place."""
59 result = mnemonic_to_seed(_MNEMONIC)
60 assert any(b != 0 for b in result), "pre-condition: seed must not be all-zero"
61 result[:] = b"\x00" * len(result)
62 assert result == bytearray(64), "caller must be able to zero the returned bytearray"
63
64
65 # ---------------------------------------------------------------------------
66 # III Correctness unaffected
67 # ---------------------------------------------------------------------------
68
69 class TestCorrectness:
70 def test_III1_deterministic(self) -> None:
71 """III1: same inputs always produce the same 64 bytes."""
72 r1 = mnemonic_to_seed(_MNEMONIC)
73 r2 = mnemonic_to_seed(_MNEMONIC)
74 assert bytes(r1) == bytes(r2), "mnemonic_to_seed must be deterministic"
75
76 def test_III2_length_64(self) -> None:
77 """III2: output is always exactly 64 bytes."""
78 result = mnemonic_to_seed(_MNEMONIC)
79 assert len(result) == 64
80
81 def test_III3_passphrase_produces_different_seed(self) -> None:
82 """III3: a non-empty passphrase produces a completely different seed (BIP39 spec)."""
83 r1 = mnemonic_to_seed(_MNEMONIC)
84 r2 = mnemonic_to_seed(_MNEMONIC, passphrase="TREZOR")
85 assert bytes(r1) != bytes(r2), (
86 "BIP39: different passphrases must produce different seeds"
87 )
File History 4 commits
sha256:e8214e0062ef8ef0af999937df2731655b6082781fc22bc563f58db2f42b1de9 Merge 'bump/muse-v0.2.1' into 'dev' — proposal: chore: bump… Human 5 days ago
sha256:8de4334a98c945aace420969d389ad678aa926d4ab4e886b2ac4c4241cb3bf2b revert: keep pyproject.toml in canonical PEP 440 form Sonnet 4.6 patch 63 days ago
sha256:a317886dc0496c4af7b285b3e41c86c4c34ea2e79afc63b8829aadb1ada7903f chore: bump version to 0.2.0rc15 to match musehub#113 fix release Sonnet 4.6 patch 63 days ago
sha256:f3b726b50f0aee3622bba751e0a67aa7ae4cf75a798477dbce581940b6a9cf70 feat: migrate invariants cache to .muse/cache/invariants.ms… Sonnet 4.6 patch 130 days ago