Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/test/test_hnp.py
2587 views
1
import os
2
import sys
3
from random import getrandbits
4
from random import randrange
5
from unittest import TestCase
6
7
path = os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__))))
8
if sys.path[1] != path:
9
sys.path.insert(1, path)
10
11
from attacks.hnp import extended_hnp
12
from attacks.hnp import lattice_attack
13
from shared.partial_integer import PartialInteger
14
15
16
class TestHNP(TestCase):
17
def _dsa(self, p, g, x):
18
h = getrandbits(p.bit_length())
19
k = randrange(1, p)
20
r = pow(g, k, p)
21
s = (pow(k, -1, p) * (h + x * r)) % p
22
return h, r, s, k
23
24
def test_extended_hnp(self):
25
# Not a safe prime, but it doesn't really matter.
26
p = 299182277398782807472682876223275635417
27
g = 5
28
x = randrange(1, p)
29
30
k_bit_length = p.bit_length()
31
lsb_unknown = 50
32
msb_unknown = 50
33
n_signatures = 5
34
h = []
35
r = []
36
s = []
37
k = []
38
partial_k = []
39
for i in range(n_signatures):
40
hi, ri, si, ki = self._dsa(p, g, x)
41
h.append(hi)
42
r.append(ri)
43
s.append(si)
44
k.append(ki)
45
partial_k.append(PartialInteger.middle_of(ki, k_bit_length, lsb_unknown, msb_unknown))
46
47
x_ = next(extended_hnp.dsa_known_bits(p, h, r, s, PartialInteger.unknown(k_bit_length), partial_k))
48
self.assertIsInstance(x_, int)
49
self.assertEqual(x, x_)
50
51
def test_lattice_attack(self):
52
# Not a safe prime, but it doesn't really matter.
53
p = 299182277398782807472682876223275635417
54
g = 5
55
x = randrange(1, p)
56
57
k_bit_length = p.bit_length()
58
msb_known = 7
59
n_signatures = 25
60
h = []
61
r = []
62
s = []
63
k = []
64
partial_k = []
65
for i in range(n_signatures):
66
hi, ri, si, ki = self._dsa(p, g, x)
67
h.append(hi)
68
r.append(ri)
69
s.append(si)
70
k.append(ki)
71
partial_k.append(PartialInteger.msb_of(ki, k_bit_length, msb_known))
72
73
x_, k_ = next(lattice_attack.dsa_known_msb(p, h, r, s, partial_k))
74
self.assertIsInstance(x_, int)
75
self.assertIsInstance(k_, list)
76
self.assertEqual(x, x_)
77
for i in range(n_signatures):
78
self.assertIsInstance(k_[i], int)
79
self.assertEqual(k[i], k_[i])
80
81
k_bit_length = p.bit_length()
82
lsb_known = 7
83
n_signatures = 25
84
h = []
85
r = []
86
s = []
87
k = []
88
partial_k = []
89
for i in range(n_signatures):
90
hi, ri, si, ki = self._dsa(p, g, x)
91
h.append(hi)
92
r.append(ri)
93
s.append(si)
94
k.append(ki)
95
partial_k.append(PartialInteger.lsb_of(ki, k_bit_length, lsb_known))
96
97
x_, k_ = next(lattice_attack.dsa_known_lsb(p, h, r, s, partial_k))
98
self.assertIsInstance(x_, int)
99
self.assertIsInstance(k_, list)
100
self.assertEqual(x, x_)
101
for i in range(n_signatures):
102
self.assertIsInstance(k_[i], int)
103
self.assertEqual(k[i], k_[i])
104
105
k_bit_length = p.bit_length()
106
lsb_unknown = 20
107
msb_unknown = 10
108
h1, r1, s1, k1 = self._dsa(p, g, x)
109
partial_k1 = PartialInteger.middle_of(k1, k_bit_length, lsb_unknown, msb_unknown)
110
h2, r2, s2, k2 = self._dsa(p, g, x)
111
partial_k2 = PartialInteger.middle_of(k2, k_bit_length, lsb_unknown, msb_unknown)
112
113
x_, k1_, k2_ = lattice_attack.dsa_known_middle(p, h1, r1, s1, partial_k1, h2, r2, s2, partial_k2)
114
self.assertIsInstance(x_, int)
115
self.assertIsInstance(k1_, int)
116
self.assertIsInstance(k2_, int)
117
self.assertEqual(x, x_)
118
self.assertEqual(k1, k1_)
119
self.assertEqual(k2, k2_)
120
121