fwatch: Include <string.h> for declaration of memset(3).
[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 }