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) | |
60 | ||
61 | def binop(k, op): | |
62 | x = k.rand(); y = k.rand() | |
63 | print ' %s\n %s\n %s;' % (x, y, op(x, y)) | |
64 | ||
65 | def unop(k, op): | |
66 | x = k.rand() | |
67 | print ' %s\n %s;' % (x, op(x)) | |
68 | ||
69 | @test | |
70 | def add(k): binop(k, lambda x, y: x + y) | |
71 | ||
72 | @test | |
73 | def sub(k): binop(k, lambda x, y: x - y) | |
74 | ||
75 | @test | |
25f67362 MW |
76 | def neg(k): unop(k, lambda x: -x) |
77 | ||
78 | @test | |
ee39a683 MW |
79 | def mul(k): binop(k, lambda x, y: x*y) |
80 | ||
81 | @test | |
82 | def sqr(k): unop(k, lambda x: x*x) | |
83 | ||
84 | @test | |
85 | def inv(k): unop(k, lambda x: x and x.inv() or k(0)) | |
86 | ||
87 | @test | |
25f67362 MW |
88 | def quosqrt(k): |
89 | x = k.rand(); y = k.rand() | |
90 | yy = +y | |
91 | u = yy and x/y or k(0) | |
92 | try: zz = u.sqrt() | |
93 | except ValueError: print ' %s\n %s\n "" "";' % (x, y) | |
94 | else: print ' %s\n %s\n %s\n %s;' % (x, y, zz, -zz) | |
95 | ||
96 | @test | |
ee39a683 MW |
97 | def mulconst(k): |
98 | x = k.rand() | |
99 | a = C.rand.range(1 << 20) - (1 << 19) | |
100 | print ' %s %d\n %s;' % (x, a, a*x) | |
101 | ||
102 | def mask(): return C.rand.range(2)*0xffffffff | |
103 | ||
104 | @test | |
25f67362 MW |
105 | def pick2(k): |
106 | x = k.rand(); y = k.rand(); m = mask() | |
107 | print ' %s\n %s\n 0x%08x\n %s;' % (x, y, m, +(m and x or y)) | |
108 | ||
109 | @test | |
110 | def condneg(k): | |
111 | x = k.rand(); m = mask() | |
112 | print ' %s\n 0x%08x\n %s;' % (x, m, x*(m and -1 or +1)) | |
113 | ||
114 | @test | |
115 | def pickn(k): | |
116 | n = C.rand.range(31) + 1 | |
117 | v = [k.rand() for i in xrange(n)] | |
118 | i = C.rand.range(n) | |
119 | print ' "%s"\n %d\n %s;' % ('\n '.join(map(str, v)), i, +v[i]) | |
120 | ||
121 | @test | |
ee39a683 MW |
122 | def condswap(k): |
123 | x = k.rand(); y = k.rand(); m = mask() | |
124 | xx, yy = m and (+y, +x) or (+x, +y) | |
125 | print ' %s\n %s\n 0x%08x\n %s\n %s;' % (x, y, m, xx, yy) | |
126 | ||
127 | @test | |
128 | def sub_mulc_add_sub_mul(k): | |
129 | u = k.rand(); v = k.rand(); w = k.rand(); x = k.rand(); y = k.rand(); | |
130 | a = C.rand.range(1 << 20) - (1 << 19) | |
131 | print ' %s\n %s %d\n %s\n %s\n %s\n %s;' % \ | |
132 | (u, v, a, w, x, y, ((u - v)*a + w)*(x - y)) | |
133 | ||
134 | k = FIELDS[argv[1]] | |
135 | for t in argv[2:]: | |
136 | print '%s {' % t | |
137 | for i in xrange(NTEST): TESTS[t](k) | |
138 | print '}' |