chiark / gitweb /
Fix README and mLib.3 a bit.
[mLib] / bits-testgen.c
1 /*
2  * Generate random test vectors for 64-bit operations.
3  *
4  * As an independent reference, we use the Catacomb multiprecision integer
5  * library.
6  */
7
8 #include <stdio.h>
9
10 #include <catacomb/mp.h>
11 #include <catacomb/mprand.h>
12 #include <catacomb/fibrand.h>
13
14 static mp *m64;
15 static grand *r;
16
17 #define NVEC 64
18
19 static mp *mp_rol(mp *d, mp *x, unsigned s)
20 {
21   mp *l = mp_lsl(MP_NEW, x, s);
22   mp *r = mp_lsr(MP_NEW, x, 64 - s);
23   d = mp_add(d, l, r);
24   mp_drop(l);
25   mp_drop(r);
26   return (d);
27 }
28
29 static mp *mp_ror(mp *d, mp *x, unsigned s)
30 {
31   mp *l = mp_lsl(MP_NEW, x, 64 - s);
32   mp *r = mp_lsr(MP_NEW, x, s);
33   d = mp_add(d, l, r);
34   mp_drop(l);
35   mp_drop(r);
36   return (d);
37 }
38
39 static void putmp(mp *x)
40 {
41   octet buf[8];
42   unsigned i;
43   fputc(' ', stdout);
44   mp_storeb(x, buf, sizeof(buf));
45   for (i = 0; i < sizeof(buf); i++)
46     printf("%02x", buf[i]);
47 }
48
49 #define GEN_SHIFT(op)                                                   \
50                                                                         \
51 static void gen_##op(void)                                              \
52 {                                                                       \
53   unsigned i;                                                           \
54   fputs("\n" #op "64 {\n", stdout);                                     \
55   for (i = 0; i < NVEC; i++) {                                          \
56     mp *x = mprand_range(MP_NEW, m64, r, 0);                            \
57     unsigned s = r->ops->range(r, 70), ss = s & 63;                     \
58     mp *y = mp_##op(MP_NEW, x, ss);                                     \
59     mp_div(0, &y, y, m64);                                              \
60                                                                         \
61     fputs(" ", stdout);                                                 \
62     putmp(x); printf(" %2u", s); putmp(y);                              \
63     fputs(";\n", stdout);                                               \
64     mp_drop(x); mp_drop(y);                                             \
65   }                                                                     \
66   for (i = 0; i < 4; i++) {                                             \
67     mp *x = mprand_range(MP_NEW, m64, r, 0);                            \
68     mp *y = mp_##op(MP_NEW, x, 32);                                     \
69     mp_div(0, &y, y, m64);                                              \
70                                                                         \
71     fputs(" ", stdout);                                                 \
72     putmp(x); printf(" 32"); putmp(y);                                  \
73     fputs(";\n", stdout);                                               \
74     mp_drop(x); mp_drop(y);                                             \
75   }                                                                     \
76   fputs("}\n", stdout);                                                 \
77 }
78
79 #define GEN_ARITH(op)                                                   \
80                                                                         \
81 static void gen_##op(void)                                              \
82 {                                                                       \
83   unsigned i;                                                           \
84   fputs("\n" #op "64 {\n", stdout);                                     \
85   for (i = 0; i < NVEC; i++) {                                          \
86     mp *x = mprand_range(MP_NEW, m64, r, 0);                            \
87     mp *y = mprand_range(MP_NEW, m64, r, 0);                            \
88     mp *z = mp_##op(MP_NEW, x, y);                                      \
89     mp_div(0, &z, z, m64);                                              \
90                                                                         \
91     fputs(" ", stdout);                                                 \
92     putmp(x); putmp(y); putmp(z);                                       \
93     fputs(";\n", stdout);                                               \
94     mp_drop(x); mp_drop(y); mp_drop(z);                                 \
95   }                                                                     \
96   fputs("}\n", stdout);                                                 \
97 }
98
99 GEN_SHIFT(lsl)
100 GEN_SHIFT(lsr)
101 GEN_SHIFT(rol)
102 GEN_SHIFT(ror)
103 GEN_ARITH(add)
104 GEN_ARITH(sub)
105
106 int main(void)
107 {
108   m64 = mp_lsl(MP_NEW, MP_ONE, 64);
109   r = fibrand_create(0);
110   fputs("# Test vectors for 64-bit operations [generated]\n", stdout);
111
112   gen_lsl();
113   gen_lsr();
114   gen_rol();
115   gen_ror();
116   gen_add();
117   gen_sub();
118   return (0);
119 }