-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_dammsum.py
108 lines (86 loc) · 2.58 KB
/
test_dammsum.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
from dammsum import *
from typing import List
import pytest
from random import randrange
k = 11 # word list contains 2**11 == 2048 words
m = 12 # number of words in a seed (excluding checksum)
words_path = 'words.txt' # relative path to word list
# Fetch the word list
def get_words() -> List[str]:
words = []
try:
words_file = open(words_path,'r')
for line in words_file:
words.append(line.strip())
return words
except:
raise IOError
# Test that generated seeds are not obviously broken
def test_generate():
d = DammSum(k, m, get_words())
seed_1 = d.generate()
seed_2 = d.generate()
# Seeds should be of the correct length
assert len(seed_1) == m + 1
assert len(seed_2) == m + 1
# Seeds should verify
assert d.verify(seed_1)
assert d.verify(seed_2)
# Seeds should contain at least some unique values with high probability
assert len(set(seed_1)) > 1
# Seeds should be unique with high probability
assert seed_1 != seed_2
# Test that substitutions are detected
def test_substitution_detect():
d = DammSum(k, m, get_words())
seed = d.generate()
# Check all substitutions in all positions
for j in range(m+1):
seed_ = seed.copy()
for i in range(1 << k):
if seed[j] == d.words[i]:
continue
seed_[j] = d.words[i]
# Substitutions should always fail
assert not d.verify(seed_)
# Test that transpositions are detected
def test_transpositions():
d = DammSum(k, m, get_words())
seed = d.generate()
# Check all transpositions
for j in range(m):
if seed[j] == seed[j+1]:
continue
seed_ = seed.copy()
seed_[j], seed_[j+1] = seed_[j+1], seed_[j]
# Transpositions should always fail
assert not d.verify(seed_)
# Test some corrections
def test_corrections():
d = DammSum(k, m, get_words())
seed = d.generate()
# Test the correct seed
with pytest.raises(ValueError):
d.correct(seed)
# Perform a random substitution in all positions
for j in range(m+1):
evil_seed = seed.copy()
# If the subtitution is trivial, ignore
evil_seed[j] = d.words[randrange(0, 1 << k)]
if evil_seed == seed:
continue
# Check the correction
seeds = d.correct(evil_seed)
assert seed in seeds # we should get the original seed...
assert len(seeds) >= m + 1 # ... and other valid seeds
# Perform all transpositions
for j in range(m):
evil_seed = seed.copy()
# If the transposition is trivial, ignore
evil_seed[j], evil_seed[j+1] = seed[j+1], seed[j]
if evil_seed == seed:
continue
# Check the correction
seeds = d.correct(evil_seed)
assert seed in seeds # we should get the original seed...
assert len(seeds) > 0 # ... and may get other valid seeds