chiark / gitweb /
rand/rand-x86ish.S: Hoist argument register allocation outside.
[catacomb] / utils / qfarith-test
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 Field.register('fgoldi', C.MP(0).setbit(448) - C.MP(0).setbit(224) - 1)
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
77 def neg(k): unop(k, lambda x: -x)
78
79 @test
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
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
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
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
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 '}'