c71fde7b |
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); \ |
5892fd39 |
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); \ |
c71fde7b |
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 | } |