Skip to content

Commit ff92bbc

Browse files
committed
Support for analysis of 512-bit seeds
1 parent 685e9cd commit ff92bbc

File tree

3 files changed

+162
-97
lines changed

3 files changed

+162
-97
lines changed

slip39/gui/main.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -460,15 +460,15 @@ def update_seed_data( event, window, values ):
460460
461461
"""
462462
SD_CONTROLS = [
463-
'-SD-128-RND-',
464-
'-SD-256-RND-',
465-
'-SD-512-RND-',
466-
'-SD-128-FIX-',
467-
'-SD-256-FIX-',
468-
'-SD-512-FIX-',
469-
'-SD-BIP-', # Recover 128- to 256-bit Mnemonic Seed Entropy
470-
'-SD-BIP-SEED-', # Recover 512-bit Generated Seed w/ passphrase
471-
'-SD-SLIP-',
463+
'-SD-128-RND-',
464+
'-SD-256-RND-',
465+
'-SD-512-RND-',
466+
'-SD-128-FIX-',
467+
'-SD-256-FIX-',
468+
'-SD-512-FIX-',
469+
'-SD-BIP-', # Recover 128- to 256-bit Mnemonic Seed Entropy
470+
'-SD-BIP-SEED-', # Recover 512-bit Generated Seed w/ passphrase
471+
'-SD-SLIP-',
472472
]
473473
changed = False
474474
# Some system event (eg. __TIMEOUT__ immediately after a new main window is created, or due to
@@ -626,7 +626,6 @@ def update_seed_data( event, window, values ):
626626
elif changed:
627627
log.info( f"Seed Data requests __TIMEOUT__ w/ current source: {update_seed_data.src!r}" )
628628
values['__TIMEOUT__'] = .5
629-
630629
# Since a window[...].update() doesn't show up to a .get() 'til the next cycle of the display,
631630
# we'll communicate updates to successive functions via values.
632631
values['-SD-SEED-'] = seed
@@ -989,7 +988,6 @@ def app(
989988
if timeout:
990989
logging.debug( f"A __TIMEOUT__ was requested: {timeout!r}" )
991990
event, values = window.read( timeout=timeout )
992-
assert '__TIMEOUT__' not in values
993991
logging.debug( f"{event}, {values}" )
994992
if not values or event in events_termination or event in events_ignored:
995993
continue

slip39/recovery/entropy.py

Lines changed: 151 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def idft( y: List[complex] ) -> List[complex]:
120120
r /= N+0j
121121
result.append( r )
122122
return result
123-
idft.e_sk = {}
123+
idft.e_sk = {} # noqa: E305
124124

125125

126126
def dft_magnitude( bins: Sequence[complex] ) -> List[float]:
@@ -604,108 +604,160 @@ def signal_entropy(
604604
False: {
605605
128: {
606606
3: {
607-
40: 3.779553809989789,
608-
42: 3.6582015804751173
607+
40: 3.8319094573028787,
608+
42: 3.685476090240114
609609
},
610610
4: {
611-
30: 3.864175213324604,
612-
32: 3.7281165117299206
611+
30: 3.8615459602092157,
612+
32: 3.7345780303889
613613
},
614614
5: {
615-
22: 4.005349951974719,
616-
24: 3.893953614890763
615+
22: 4.031452452745891,
616+
24: 3.8701046211838714
617617
},
618618
6: {
619-
18: 4.007243202023137,
620-
20: 3.92360269970991
619+
18: 4.064703542354124,
620+
20: 3.9093236736709005
621621
},
622622
7: {
623-
16: 3.986243329154203,
624-
18: 3.7923882736495313
623+
16: 3.9888900383171633,
624+
18: 3.782751595015048
625625
},
626626
8: {
627-
14: 3.9779694518291775,
628-
16: 3.8078741036532975
627+
14: 4.0080294733416375,
628+
16: 3.8109570140209534
629629
}
630630
},
631631
256: {
632632
3: {
633-
82: 3.7821406893905065,
634-
84: 3.74491340662642
633+
82: 3.806370027613541,
634+
84: 3.7619493887697253
635635
},
636636
4: {
637-
62: 3.8625572889282025,
638-
64: 3.7211817044872535
637+
62: 3.82382599149047,
638+
64: 3.722971212374251
639639
},
640640
5: {
641-
48: 3.8863128330861434,
642-
50: 3.81055666520842
641+
48: 3.8777324591228752,
642+
50: 3.785035016049928
643643
},
644644
6: {
645-
40: 3.869756892470617,
646-
42: 3.7138432243636106
645+
40: 3.890868347621533,
646+
42: 3.7178010712693417
647647
},
648648
7: {
649-
34: 3.8862814461705026,
650-
36: 3.7494375569780742
649+
34: 3.9103459886442242,
650+
36: 3.749124828108034
651651
},
652652
8: {
653-
30: 3.894317031804912,
654-
32: 3.79302529999739
653+
30: 3.9381720284801585,
654+
32: 3.7641419877677595
655+
}
656+
},
657+
512: {
658+
3: {
659+
168: 3.8449196204941507,
660+
170: 3.7631094408144254
661+
},
662+
4: {
663+
126: 3.8423190039357342,
664+
128: 3.7808902262362367
665+
},
666+
5: {
667+
100: 3.8542627650321903,
668+
102: 3.773865897440794
669+
},
670+
6: {
671+
82: 3.861724791171357,
672+
84: 3.8341045873987407
673+
},
674+
7: {
675+
70: 3.864141100963424,
676+
72: 3.828268979559758
677+
},
678+
8: {
679+
62: 3.8294157442190024,
680+
64: 3.7911866343172504
655681
}
656682
}
657683
},
658684
True: {
659685
128: {
660686
3: {
661-
40: 4.096864856750294,
662-
42: 3.96179382463156
687+
40: 4.059035156857346,
688+
42: 3.971692401025817
663689
},
664690
4: {
665-
30: 4.184712704481273,
666-
32: 3.783496759341616
691+
30: 4.1483024026668245,
692+
32: 3.7402592967867974
667693
},
668694
5: {
669-
22: 4.388882309944768,
670-
24: 4.2630754274445435
695+
22: 4.423526762039983,
696+
24: 4.252455864761521
671697
},
672698
6: {
673-
18: 4.534449724948289,
674-
20: 4.260079513566362
699+
18: 4.4658432794693415,
700+
20: 4.289839205249114
675701
},
676702
7: {
677-
16: 4.436262931432051,
678-
18: 4.052609747334644
703+
16: 4.4553188372289965,
704+
18: 4.080751220352483
679705
},
680706
8: {
681-
14: 4.4251917906201,
682-
16: 3.809023390691769
707+
14: 4.4394858537956905,
708+
16: 3.833429098349592
683709
}
684710
},
685711
256: {
686712
3: {
687-
82: 4.017068697706907,
688-
84: 3.9584783677441404
713+
82: 3.9867064854795853,
714+
84: 3.9474715330931964
715+
},
716+
4: {
717+
62: 4.091221861282323,
718+
64: 3.713189488198916
719+
},
720+
5: {
721+
48: 4.223821618652512,
722+
50: 4.112120735986639
723+
},
724+
6: {
725+
40: 4.286900236436957,
726+
42: 4.108363556032139
727+
},
728+
7: {
729+
34: 4.321051333229571,
730+
36: 4.120419486034919
731+
},
732+
8: {
733+
30: 4.3296525828892936,
734+
32: 3.7116192695666363
735+
}
736+
},
737+
512: {
738+
3: {
739+
168: 4.056315711850857,
740+
170: 3.9672213350986323
689741
},
690742
4: {
691-
62: 4.064042071188059,
692-
64: 3.7895572866750977
743+
126: 4.048192882854876,
744+
128: 3.7647648876385684
693745
},
694746
5: {
695-
48: 4.205915379850079,
696-
50: 4.109476784958747
747+
100: 4.09557380634852,
748+
102: 3.9936613966057357
697749
},
698750
6: {
699-
40: 4.245888029950601,
700-
42: 4.101003336750678
751+
82: 4.1778482028326875,
752+
84: 4.112025388076531
701753
},
702754
7: {
703-
34: 4.355691864063873,
704-
36: 4.1038794966102285
755+
70: 4.246425467555282,
756+
72: 4.176159483504127
705757
},
706758
8: {
707-
30: 4.358020918945955,
708-
32: 3.801241943274308
759+
62: 4.2326162869241735,
760+
64: 3.702981814071318
709761
}
710762
}
711763
}
@@ -847,16 +899,13 @@ def shannon_entropy(
847899
most = interesting[0][1]
848900
least = min( interesting[-1][1], most - 1 )
849901
scale = 255 // ( most - least )
850-
pos = ''
851-
neg = ''
902+
wav = ''
852903
for s in range( symbols ):
853904
i = offset + s * stride
854905
symbol = entropy_bin[i:i+stride]
855906
signal = ( frequency[symbol] - least ) * scale - 128
856-
pos += stride * signal_draw( signal ) #, pos=True )
857-
#neg += stride * signal_draw( signal, neg=True )
858-
details += f"{offpref}{pos}\n"
859-
details += f"{offpref}{neg}\n"
907+
wav += stride * signal_draw( signal )
908+
details += f"{offpref}{wav}\n"
860909

861910
strongest = Signal(
862911
dB = snr_dB,
@@ -869,38 +918,54 @@ def shannon_entropy(
869918
shannon_entropy.shannon_limits = { # noqa: E305
870919
False: {
871920
128: {
872-
3: 0.13482541813448376,
873-
4: 0.2084287719652665,
874-
5: 0.2524549185131357,
875-
6: 0.17519406401074272,
876-
7: 0.12835311162216362,
877-
8: 0.10428980513816934
921+
3: 0.14019101211428098,
922+
4: 0.2171524340774941,
923+
5: 0.30713834645661736,
924+
6: 0.1816854359968526,
925+
7: 0.13342390650130254,
926+
8: 0.10552310877642387
878927
},
879928
256: {
880-
3: 0.06878284042482098,
881-
4: 0.10593352474465785,
882-
5: 0.17017668215643436,
883-
6: 0.17539760834795967,
884-
7: 0.11541666075618831,
885-
8: 0.07979246189910372
929+
3: 0.07899726657064883,
930+
4: 0.10986451280885183,
931+
5: 0.17685089046815017,
932+
6: 0.18089586818651493,
933+
7: 0.12034741739974093,
934+
8: 0.0868358375224554
935+
},
936+
512: {
937+
3: 0.07790480669136064,
938+
4: 0.07790480669136064,
939+
5: 0.09071156437595747,
940+
6: 0.1528917619447544,
941+
7: 0.13006695660607703,
942+
8: 0.08296364156731802
886943
}
887944
},
888945
True: {
889946
128: {
890-
3: 0.1490241221291312,
891-
4: 0.2321604213173531,
892-
5: 0.3116859874053549,
893-
6: 0.20291992944894158,
894-
7: 0.15496704898123123,
895-
8: 0.1243923516123256
947+
3: 0.15550747522807437,
948+
4: 0.24661163176093312,
949+
5: 0.3523433565963667,
950+
6: 0.21534352560263997,
951+
7: 0.16411100479228236,
952+
8: 0.136414702002971
896953
},
897954
256: {
898-
3: 0.07370900693149794,
899-
4: 0.11726611942995595,
900-
5: 0.18715942996873902,
901-
6: 0.1888715883067866,
902-
7: 0.13139004807666896,
903-
8: 0.09591513938521387
955+
3: 0.08168351670153086,
956+
4: 0.12141626752694244,
957+
5: 0.1967404982010119,
958+
6: 0.2397004855223926,
959+
7: 0.13609286793923406,
960+
8: 0.09979325030179034
961+
},
962+
512: {
963+
3: 0.07790480669136064,
964+
4: 0.07790480669136064,
965+
5: 0.09869307232869345,
966+
6: 0.1826087090056934,
967+
7: 0.13963588440239252,
968+
8: 0.09058107616905901
904969
}
905970
}
906971
}
@@ -999,13 +1064,13 @@ def analyze_entropy(
9991064
report += f" {'-'.join( f'{dB:.1f}' for dB in dBr )}dB non-random energy patterns in"
10001065
report += f" {commas( sorted( set( s.stride for s in signals )), final_and=True)}-bit symbols\n"
10011066
for s,summary in sorted(
1002-
[
1003-
(s, f"{s.dB:5.1f}dB Signal harmonic feature at offset {s.offset} in {s.symbols}x {s.stride}-bit symbols")
1004-
for s in signals
1005-
] + [
1006-
(s, f"{s.dB:5.1f}dB Shannon entropy reduced at offset {s.offset} in {s.symbols}x {s.stride}-bit symbols")
1007-
for s in shannons
1008-
], reverse=True ):
1067+
[
1068+
(s, f"{s.dB:5.1f}dB Signal harmonic feature at offset {s.offset} in {s.symbols}x {s.stride}-bit symbols")
1069+
for s in signals
1070+
] + [
1071+
(s, f"{s.dB:5.1f}dB Shannon entropy reduced at offset {s.offset} in {s.symbols}x {s.stride}-bit symbols")
1072+
for s in shannons
1073+
], reverse=True ):
10091074
report += f"-{summary}{': ' if s.details else ''}\n"
10101075
if s.details:
10111076
report += f"{s.details}\n"

slip39/recovery_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ def test_recover_bip39_vectors():
320320
assert address in addresses, \
321321
f"row {i+1}: BTC account {address} not in {addresses!r} for entropy {entropy} ==> {master_secret}"
322322

323+
323324
def test_util():
324325
assert commas( range(10) ) == '0-9'
325326
assert commas( [1,2,3,5,6,7] ) == '1-3, 5-7'
@@ -329,6 +330,7 @@ def test_util():
329330
assert commas( [1,3,5], final_and=True ) == '1, 3 and 5'
330331
assert commas( [1,2,5], final_and=True ) == '1, 2 and 5'
331332

333+
332334
def test_dft_smoke():
333335
"""Test some basic assumptions on DFTs"""
334336
print()

0 commit comments

Comments
 (0)