Commit | Line | Data |
---|---|---|
ee39a683 MW |
1 | #! /usr/bin/python |
2 | ||
3 | from sys import argv | |
4 | import catacomb as C | |
5 | ||
6 | TESTS = {} | |
7 | NTEST = 20 | |
8 | ||
9 | def test(arg): | |
10 | def reg(fn, name): | |
11 | TESTS[name] = fn | |
12 | return fn | |
13 | if isinstance(arg, str): return lambda fn: reg(fn, arg) | |
14 | else: return reg(arg, arg.__name__.replace('_', '-')) | |
15 | ||
16 | FIELDS = {} | |
17 | ||
18 | class FieldElt (object): | |
19 | def __init__(me, k, n): | |
20 | me.k = k | |
21 | me.v = (C.MP(n)%k.p).storel(k.len) | |
22 | def __str__(me): return hex(me.v) | |
23 | @property | |
24 | def n(me): return C.MP.loadl(me.v) | |
25 | def __pos__(me): return FieldElt(me.k, me.n) | |
26 | def __neg__(me): return FieldElt(me.k, -me.n) | |
27 | def __nonzero__(me): return me.n != 0 | |
28 | def __add__(me, you): return FieldElt(me.k, me.n + me.k(you).n) | |
29 | def __radd__(me, you): return FieldElt(me.k, me.k(you).n + me.n) | |
30 | def __sub__(me, you): return FieldElt(me.k, me.n - me.k(you).n) | |
31 | def __rsub__(me, you): return FieldElt(me.k, me.k(you).n - me.n) | |
32 | def __mul__(me, you): return FieldElt(me.k, me.n*me.k(you).n) | |
33 | def __rmul__(me, you): return FieldElt(me.k, me.k(you).n*me.n) | |
34 | def __div__(me, you): return FieldElt(me.k, me.n*me.k(you).inv().n) | |
35 | def __rdiv__(me, you): return FieldElt(me.k, me.k(you).n*me.inv().n) | |
36 | def inv(me): return FieldElt(me.k, me.k.p.modinv(me.n)) | |
37 | def sqrt(me): return FieldElt(me.k, me.k.p.modsqrt(me.n)) | |
38 | @classmethod | |
39 | def rand(cls, k): | |
40 | me = cls(k, 0) | |
41 | me.v = C.rand.block(k. len) | |
42 | return me | |
43 | ||
44 | class Field (object): | |
45 | def __init__(me, p, len = None): | |
46 | me.p = C.MP(p) | |
47 | me.len = len is None and me.p.noctets or len | |
48 | @classmethod | |
49 | def register(cls, name, *args, **kw): | |
50 | FIELDS[name] = cls(*args, **kw) | |
51 | def rand(me): return FieldElt.rand(me) | |
52 | def __call__(me, n): | |
53 | if isinstance(n, FieldElt): | |
54 | assert n.k is me | |
55 | return n | |
56 | else: | |
57 | return FieldElt(me, n) | |
58 | ||
59 | Field.register('f25519', C.MP(0).setbit(255) - 19) | |
643eb1bb | 60 | Field.register('fgoldi', C.MP(0).setbit(448) - C.MP(0).setbit(224) - 1) |
ee39a683 MW |
61 | |
62 | def binop(k, op): | |
63 | x = k.rand(); y = k.rand() | |
64 | print ' %s\n %s\n %s;' % (x, y, op(x, y)) | |
65 | ||
66 | def unop(k, op): | |
67 | x = k.rand() | |
68 | print ' %s\n %s;' % (x, op(x)) | |
69 | ||
70 | @test | |
71 | def add(k): binop(k, lambda x, y: x + y) | |
72 | ||
73 | @test | |
74 | def sub(k): binop(k, lambda x, y: x - y) | |
75 | ||
76 | @test | |
25f67362 MW |
77 | def neg(k): unop(k, lambda x: -x) |
78 | ||
79 | @test | |
ee39a683 MW |
80 | def mul(k): binop(k, lambda x, y: x*y) |
81 | ||
82 | @test | |
83 | def sqr(k): unop(k, lambda x: x*x) | |
84 | ||
85 | @test | |
86 | def inv(k): unop(k, lambda x: x and x.inv() or k(0)) | |
87 | ||
88 | @test | |
25f67362 MW |
89 | def quosqrt(k): |
90 | x = k.rand(); y = k.rand() | |
91 | yy = +y | |
92 | u = yy and x/y or k(0) | |
93 | try: zz = u.sqrt() | |
94 | except ValueError: print ' %s\n %s\n "" "";' % (x, y) | |
95 | else: print ' %s\n %s\n %s\n %s;' % (x, y, zz, -zz) | |
96 | ||
97 | @test | |
ee39a683 MW |
98 | def mulconst(k): |
99 | x = k.rand() | |
100 | a = C.rand.range(1 << 20) - (1 << 19) | |
101 | print ' %s %d\n %s;' % (x, a, a*x) | |
102 | ||
103 | def mask(): return C.rand.range(2)*0xffffffff | |
104 | ||
105 | @test | |
25f67362 MW |
106 | def pick2(k): |
107 | x = k.rand(); y = k.rand(); m = mask() | |
108 | print ' %s\n %s\n 0x%08x\n %s;' % (x, y, m, +(m and x or y)) | |
109 | ||
110 | @test | |
111 | def condneg(k): | |
112 | x = k.rand(); m = mask() | |
113 | print ' %s\n 0x%08x\n %s;' % (x, m, x*(m and -1 or +1)) | |
114 | ||
115 | @test | |
116 | def pickn(k): | |
117 | n = C.rand.range(31) + 1 | |
118 | v = [k.rand() for i in xrange(n)] | |
119 | i = C.rand.range(n) | |
120 | print ' "%s"\n %d\n %s;' % ('\n '.join(map(str, v)), i, +v[i]) | |
121 | ||
122 | @test | |
ee39a683 MW |
123 | def condswap(k): |
124 | x = k.rand(); y = k.rand(); m = mask() | |
125 | xx, yy = m and (+y, +x) or (+x, +y) | |
126 | print ' %s\n %s\n 0x%08x\n %s\n %s;' % (x, y, m, xx, yy) | |
127 | ||
128 | @test | |
129 | def sub_mulc_add_sub_mul(k): | |
130 | u = k.rand(); v = k.rand(); w = k.rand(); x = k.rand(); y = k.rand(); | |
131 | a = C.rand.range(1 << 20) - (1 << 19) | |
132 | print ' %s\n %s %d\n %s\n %s\n %s\n %s;' % \ | |
133 | (u, v, a, w, x, y, ((u - v)*a + w)*(x - y)) | |
134 | ||
135 | k = FIELDS[argv[1]] | |
136 | for t in argv[2:]: | |
137 | print '%s {' % t | |
138 | for i in xrange(NTEST): TESTS[t](k) | |
139 | print '}' |