-
Notifications
You must be signed in to change notification settings - Fork 0
/
tests.py
154 lines (140 loc) · 5.54 KB
/
tests.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
from modp import ModP
from group import MultIntModP, EC
from pippenger import Pippenger
from random import randint
from ecdsa import SECP256k1, NIST192p, NIST224p, NIST256p, NIST384p, NIST521p
from ecdsa.ellipticcurve import Point
from sympy import isprime
import time
import unittest
from math import log2, floor
def naive_multi_exp(gs, es, p):
tmp = ModP(1, p)
for i in range(len(gs)):
tmp *= gs[i]**es[i]
return tmp
def naive_multi_exp_ec(gs, es):
tmp = Point(None, None, None)
for i in range(len(gs)):
tmp += es[i] * gs[i]
return tmp
def get_good_primes(start):
p = start
while True:
if isprime(p) and isprime(2*p+1):
gen = 2
while True:
if pow(gen, p, 2*p+1) == 1:
return p, 2*p+1, gen
gen += 1
p += 1
class StupidTests(unittest.TestCase):
def test_different_length(self):
order, p = 11, 23
G = MultIntModP(p, order)
Pip = Pippenger(G)
g = ModP(3, p)
with self.assertRaisesRegex(Exception, 'Different number of group elements and exponents'):
Pip.multiexp([g, g**2],[1])
with self.assertRaisesRegex(Exception, 'Different number of group elements and exponents'):
Pip.multiexp([g],[1, 2])
def test_zero_int_modp(self):
order, p = 11, 23
G = MultIntModP(p, order)
Pip = Pippenger(G)
g = ModP(3, p)
for i in range(order):
with self.subTest(i=i):
self.assertEqual(Pip.multiexp([g**i],[0]), G.unit)
self.assertEqual(
Pip.multiexp([g**i for i in range(order)],[0 for i in range(order)]), G.unit
)
def test_zero_ec(self):
CURVE = NIST192p
G = EC(CURVE)
order_cyclic_subgroup = CURVE.order
g = CURVE.generator
Pip = Pippenger(G)
for i in [randint(0,order_cyclic_subgroup) for _ in range(10)]:
with self.subTest(i=i):
self.assertEqual(Pip.multiexp([i*g],[0]), G.unit)
self.assertEqual(
Pip.multiexp([i*g for i in [randint(0,order_cyclic_subgroup) for _ in range(10)]],
[0 for i in range(10)]),
G.unit
)
def test_one_int_modp(self):
order, p = 11, 23
G = MultIntModP(p, order)
Pip = Pippenger(G)
g = ModP(3, p)
for i in range(order):
with self.subTest(i=i):
self.assertEqual(Pip.multiexp([g**i],[1]), g**i)
self.assertEqual(
Pip.multiexp([g for i in range(order)],[1 for i in range(order)]), G.unit
)
def test_one_ec(self):
CURVE = NIST192p
G = EC(CURVE)
order_cyclic_subgroup = CURVE.order
g = CURVE.generator
Pip = Pippenger(G)
for i in [randint(0,order_cyclic_subgroup) for _ in range(10)]:
with self.subTest(i=i):
self.assertEqual(Pip.multiexp([i*g],[1]), i*g)
self.assertEqual(
Pip.multiexp([g for i in range(10)], [1 for i in range(10)]),
10*g
)
class TestsIntModP(unittest.TestCase):
def test_all_values_of_N(self):
order_cyclic_subgroup, p, gen = get_good_primes(2**32)
G = MultIntModP(p, order_cyclic_subgroup)
Pip = Pippenger(G)
g = ModP(gen, p)
for N in range(order_cyclic_subgroup.bit_length()):
gs = [g**randint(1, order_cyclic_subgroup) for _ in range(N)]
es = [randint(1,order_cyclic_subgroup) for _ in range(N)]
with self.subTest(N=N):
self.assertEqual(Pip.multiexp(gs, es), naive_multi_exp(gs, es, p))
def test_all_values_of_p(self):
start = 5
for _ in range(50):
order_cyclic_subgroup, p, gen = get_good_primes(start)
G = MultIntModP(p, order_cyclic_subgroup)
Pip = Pippenger(G)
g = ModP(gen, p)
for N in range(order_cyclic_subgroup.bit_length()):
gs = [g**randint(1, order_cyclic_subgroup) for _ in range(N)]
es = [randint(1,order_cyclic_subgroup) for _ in range(N)]
with self.subTest(N=N, order=order_cyclic_subgroup):
self.assertEqual(Pip.multiexp(gs, es), naive_multi_exp(gs, es,p))
start = order_cyclic_subgroup + 1
class TestsEC(unittest.TestCase):
def test_all_values_of_N(self):
CURVE = NIST192p
G = EC(CURVE)
order_cyclic_subgroup = CURVE.order
g = CURVE.generator
Pip = Pippenger(G)
for N in range(0, order_cyclic_subgroup.bit_length(), 20):
gs = [g*randint(1, order_cyclic_subgroup) for _ in range(N)]
es = [randint(1,order_cyclic_subgroup) for _ in range(N)]
with self.subTest(N=N):
self.assertEqual(Pip.multiexp(gs, es), naive_multi_exp_ec(gs, es))
def test_all_curves(self):
curves = [SECP256k1, NIST192p, NIST224p, NIST256p, NIST384p, NIST521p]
for curve in curves:
G = EC(curve)
order_cyclic_subgroup = curve.order
g = curve.generator
Pip = Pippenger(G)
for _ in range(2):
N = randint(0, order_cyclic_subgroup.bit_length())
gs = [g*randint(1, order_cyclic_subgroup) for _ in range(N)]
es = [randint(1,order_cyclic_subgroup) for _ in range(N)]
with self.subTest(curve=curve, N=N):
self.assertEqual(Pip.multiexp(gs, es), naive_multi_exp_ec(gs, es))
if __name__ == '__main__':
unittest.main()