3 ### Testing cyclic-group functionality
5 ### (c) 2019 Straylight/Edgeware
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the Python interface to Catacomb.
12 ### Catacomb/Python is free software: you can redistribute it and/or
13 ### modify it under the terms of the GNU General Public License as
14 ### published by the Free Software Foundation; either version 2 of the
15 ### License, or (at your option) any later version.
17 ### Catacomb/Python is distributed in the hope that it will be useful, but
18 ### WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ### General Public License for more details.
22 ### You should have received a copy of the GNU General Public License
23 ### along with Catacomb/Python. If not, write to the Free Software
24 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 ###--------------------------------------------------------------------------
34 ###--------------------------------------------------------------------------
35 class TestGroups (T.GenericTestMixin):
36 """Test cyclic groups."""
38 def _test_group(me, G):
40 ## Some initial values.
46 ## Check that they're all different.
48 for i in T.range(len(v)):
49 for j in T.range(len(v)):
50 if i == j: me.assertEqual(v[i], v[j])
51 else: me.assertNotEqual(v[i], v[j])
53 ## Basic arithmetic. Knowing the answers is too hard. For now, just
54 ## check that the field laws hold.
55 t = x*y; me.assertEqual(t/x, y); me.assertEqual(t/y, x)
56 me.assertEqual(x*x.inv(), id)
57 me.assertEqual(x.sqr(), x*x)
58 me.assertEqual(x/x, id)
61 me.assertEqual(x**G.r, id)
62 me.assertEqual(G.mexp((x, 5), (y, 7)), g**15120884511)
64 ## Comparisons. We've already done equality and inequality, and nothing
66 me.assertRaises(TypeError, T.lt, x, y)
67 me.assertRaises(TypeError, T.le, x, y)
68 me.assertRaises(TypeError, T.ge, x, y)
69 me.assertRaises(TypeError, T.gt, x, y)
71 if isinstance(G, C.ECGroup):
74 me.assertEqual(G.noctets, 2*G.info.curve.field.noctets + 1)
75 me.assertEqual(G.nbits, 2*G.info.curve.field.nbits)
77 ## Conversion to integer.
78 i = y.toint(); me.assertEqual(type(i), C.MP)
79 t = G(i); me.assertTrue(t == y or t == y.inv())
81 ## Conversion to elliptic curve.
83 me.assertTrue(isinstance(Q, C.ECPtCurve))
84 me.assertEqual(G(Q), y)
88 me.assertEqual(t, Q.tobuf())
89 me.assertEqual(G.frombuf(t)[0], y)
90 me.assertEqual(id.tobuf(), C.ByteString.zero(2))
92 me.assertEqual(t, Q.ec2osp())
93 me.assertEqual(G.fromraw(t)[0], y)
94 me.assertEqual(id.toraw(), C.ByteString.zero(1))
99 me.assertEqual(G.noctets, G.info.p.noctets)
100 if isinstance(G.info, C.BinDHInfo):
101 me.assertEqual(G.nbits, G.info.p.degree)
103 me.assertEqual(G.nbits, G.info.p.nbits)
105 ## Conversion to integer.
106 i = y.toint(); me.assertEqual(type(i), C.MP)
107 me.assertTrue(G(i) == y)
109 ## Conversion to elliptic curve.
110 me.assertRaises(TypeError, G.toec, x)
114 me.assertEqual(t, C.WriteBuffer().putmp(i).contents)
115 me.assertEqual(G.frombuf(t)[0], y)
116 me.assertEqual(id.tobuf(), C.bytes("000101"))
118 me.assertEqual(t, i.storeb(G.noctets))
119 me.assertEqual(G.fromraw(t)[0], y)
120 me.assertEqual(id.toraw(),
121 C.WriteBuffer().zero(G.noctets - 1).putu8(1).contents)
123 ## String conversion.
125 me.assertEqual(G.fromstring(ystr), (y, ""))
127 ## Checking operations.
128 me.assertRaises(ValueError, id.check)
134 dhinfo = C.DHInfo.parse("127, 7, 2")
135 me.assertEqual(dhinfo.p, 127)
136 me.assertEqual(dhinfo.r, 7)
137 me.assertEqual(dhinfo.g, 2)
138 dhinfo.group().checkgroup()
140 def test_bindhinfo(me):
141 bindhinfo = C.BinDHInfo.parse("0x805, 89, 0x22")
142 me.assertEqual(bindhinfo.p, C.GF(0x805))
143 me.assertEqual(bindhinfo.r, 89)
144 me.assertEqual(bindhinfo.g, C.GF(0x22))
145 bindhinfo.group().checkgroup()
149 G = C.Group.parse("prime 127, 7, 2")
150 me.assertEqual(G.info.p, 127)
151 me.assertEqual(G.r, 7)
152 me.assertEqual(G.info.g, 2)
155 G = C.Group.parse("bin 0x805, 89, 0x22")
156 me.assertEqual(G.info.p, C.GF(0x805))
157 me.assertEqual(G.r, 89)
158 me.assertEqual(G.info.g, C.GF(0x22))
161 def test_gen_schnorr(me):
162 ev = T.EventRecorder()
163 dhinfo = C.DHInfo.generate(512, 64, event = ev,
164 rng = T.detrand("schnorr"))
165 me.assertEqual(dhinfo.p.nbits, 512)
166 me.assertEqual(dhinfo.r.nbits, 64)
167 me.assertTrue(dhinfo.p.primep())
168 me.assertTrue(dhinfo.r.primep())
169 me.assertEqual(dhinfo.p%dhinfo.r, 1)
170 me._test_group(dhinfo.group())
171 me.assertEqual(ev.events, "[q:F4/P26/D][p:F5/P5/D][g:D]")
173 def test_gen_limlee(me):
174 ev = T.EventRecorder()
175 dhinfo, ff = C.DHInfo.genlimlee(512, 64, event = ev, ievent = ev,
176 rng = T.detrand("limlee"))
177 me.assertEqual(dhinfo.p.nbits, 512)
178 me.assertEqual(dhinfo.r.nbits, 64)
179 me.assertTrue(dhinfo.p.primep())
180 me.assertTrue(dhinfo.r.primep())
182 me.assertTrue(f.primep())
183 me.assertTrue(f.nbits >= 64)
184 me.assertEqual(C.MPMul().factor(2).factor(ff).done() + 1, dhinfo.p)
185 me._test_group(dhinfo.group())
186 me.assertEqual(ev.events,
234 def test_gen_kcdsa(me):
235 ev = T.EventRecorder()
236 dhinfo, h = C.DHInfo.genkcdsa(512, 64, event = ev,
237 rng = T.detrand("kcdsa"))
238 me.assertEqual(dhinfo.p.nbits, 512)
239 me.assertEqual(dhinfo.r.nbits, 64)
240 me.assertTrue(dhinfo.p.primep())
241 me.assertTrue(dhinfo.r.primep())
242 me.assertTrue(h.primep())
243 me.assertEqual(2*h*dhinfo.r + 1, dhinfo.p)
244 me._test_group(dhinfo.group())
245 me.assertEqual(ev.events, "[v:F23/P6/D][p:F86/P26/D][g:D]")
247 TestGroups.generate_testcases((name, map[name].group()) for name, map in
248 [("nist-p256", C.eccurves),
249 ("nist-b283", C.eccurves),
250 ("catacomb-ll-128-512", C.primegroups),
251 ("p1363-64", C.bingroups)])
253 ###----- That's all, folks --------------------------------------------------
255 if __name__ == "__main__": U.main()