| 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 | fputs("}\n", stdout); \ |
| 67 | } |
| 68 | |
| 69 | #define GEN_ARITH(op) \ |
| 70 | \ |
| 71 | static void gen_##op(void) \ |
| 72 | { \ |
| 73 | unsigned i; \ |
| 74 | fputs("\n" #op "64 {\n", stdout); \ |
| 75 | for (i = 0; i < NVEC; i++) { \ |
| 76 | mp *x = mprand_range(MP_NEW, m64, r, 0); \ |
| 77 | mp *y = mprand_range(MP_NEW, m64, r, 0); \ |
| 78 | mp *z = mp_##op(MP_NEW, x, y); \ |
| 79 | mp_div(0, &z, z, m64); \ |
| 80 | \ |
| 81 | fputs(" ", stdout); \ |
| 82 | putmp(x); putmp(y); putmp(z); \ |
| 83 | fputs(";\n", stdout); \ |
| 84 | mp_drop(x); mp_drop(y); mp_drop(z); \ |
| 85 | } \ |
| 86 | fputs("}\n", stdout); \ |
| 87 | } |
| 88 | |
| 89 | GEN_SHIFT(lsl) |
| 90 | GEN_SHIFT(lsr) |
| 91 | GEN_SHIFT(rol) |
| 92 | GEN_SHIFT(ror) |
| 93 | GEN_ARITH(add) |
| 94 | GEN_ARITH(sub) |
| 95 | |
| 96 | int main(void) |
| 97 | { |
| 98 | m64 = mp_lsl(MP_NEW, MP_ONE, 64); |
| 99 | r = fibrand_create(0); |
| 100 | fputs("# Test vectors for 64-bit operations [generated]\n", stdout); |
| 101 | |
| 102 | gen_lsl(); |
| 103 | gen_lsr(); |
| 104 | gen_rol(); |
| 105 | gen_ror(); |
| 106 | gen_add(); |
| 107 | gen_sub(); |
| 108 | return (0); |
| 109 | } |