1 /* makes a bignum test harness with NUM tests per operation 2 * 3 * the output is made in the following format [one parameter per line] 4 5 operation 6 operand1 7 operand2 8 [... operandN] 9 result1 10 result2 11 [... resultN] 12 13 So for example "a * b mod n" would be 14 15 mulmod 16 a 17 b 18 n 19 a*b mod n 20 21 e.g. if a=3, b=4 n=11 then 22 23 mulmod 24 3 25 4 26 11 27 1 28 29 */ 30 31 #ifdef MP_8BIT 32 #define THE_MASK 127 33 #else 34 #define THE_MASK 32767 35 #endif 36 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <time.h> 40 #include "mpi.c" 41 42 FILE *rng; 43 44 void rand_num(mp_int *a) 45 { 46 int n, size; 47 unsigned char buf[2048]; 48 49 size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; 50 buf[0] = (fgetc(rng)&1)?1:0; 51 fread(buf+1, 1, size, rng); 52 while (buf[1] == 0) buf[1] = fgetc(rng); 53 mp_read_raw(a, buf, 1+size); 54 } 55 56 void rand_num2(mp_int *a) 57 { 58 int n, size; 59 unsigned char buf[2048]; 60 61 size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101; 62 buf[0] = (fgetc(rng)&1)?1:0; 63 fread(buf+1, 1, size, rng); 64 while (buf[1] == 0) buf[1] = fgetc(rng); 65 mp_read_raw(a, buf, 1+size); 66 } 67 68 #define mp_to64(a, b) mp_toradix(a, b, 64) 69 70 int main(void) 71 { 72 int n, tmp; 73 mp_int a, b, c, d, e; 74 clock_t t1; 75 char buf[4096]; 76 77 mp_init(&a); 78 mp_init(&b); 79 mp_init(&c); 80 mp_init(&d); 81 mp_init(&e); 82 83 84 /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */ 85 /* 86 mp_set(&a, 1); 87 for (n = 1; n < 8192; n++) { 88 mp_mul(&a, &a, &c); 89 printf("mul\n"); 90 mp_to64(&a, buf); 91 printf("%s\n%s\n", buf, buf); 92 mp_to64(&c, buf); 93 printf("%s\n", buf); 94 95 mp_add_d(&a, 1, &a); 96 mp_mul_2(&a, &a); 97 mp_sub_d(&a, 1, &a); 98 } 99 */ 100 101 rng = fopen("/dev/urandom", "rb"); 102 if (rng == NULL) { 103 rng = fopen("/dev/random", "rb"); 104 if (rng == NULL) { 105 fprintf(stderr, "\nWarning: stdin used as random source\n\n"); 106 rng = stdin; 107 } 108 } 109 110 t1 = clock(); 111 for (;;) { 112 #if 0 113 if (clock() - t1 > CLOCKS_PER_SEC) { 114 sleep(2); 115 t1 = clock(); 116 } 117 #endif 118 n = fgetc(rng) % 15; 119 120 if (n == 0) { 121 /* add tests */ 122 rand_num(&a); 123 rand_num(&b); 124 mp_add(&a, &b, &c); 125 printf("add\n"); 126 mp_to64(&a, buf); 127 printf("%s\n", buf); 128 mp_to64(&b, buf); 129 printf("%s\n", buf); 130 mp_to64(&c, buf); 131 printf("%s\n", buf); 132 } else if (n == 1) { 133 /* sub tests */ 134 rand_num(&a); 135 rand_num(&b); 136 mp_sub(&a, &b, &c); 137 printf("sub\n"); 138 mp_to64(&a, buf); 139 printf("%s\n", buf); 140 mp_to64(&b, buf); 141 printf("%s\n", buf); 142 mp_to64(&c, buf); 143 printf("%s\n", buf); 144 } else if (n == 2) { 145 /* mul tests */ 146 rand_num(&a); 147 rand_num(&b); 148 mp_mul(&a, &b, &c); 149 printf("mul\n"); 150 mp_to64(&a, buf); 151 printf("%s\n", buf); 152 mp_to64(&b, buf); 153 printf("%s\n", buf); 154 mp_to64(&c, buf); 155 printf("%s\n", buf); 156 } else if (n == 3) { 157 /* div tests */ 158 rand_num(&a); 159 rand_num(&b); 160 mp_div(&a, &b, &c, &d); 161 printf("div\n"); 162 mp_to64(&a, buf); 163 printf("%s\n", buf); 164 mp_to64(&b, buf); 165 printf("%s\n", buf); 166 mp_to64(&c, buf); 167 printf("%s\n", buf); 168 mp_to64(&d, buf); 169 printf("%s\n", buf); 170 } else if (n == 4) { 171 /* sqr tests */ 172 rand_num(&a); 173 mp_sqr(&a, &b); 174 printf("sqr\n"); 175 mp_to64(&a, buf); 176 printf("%s\n", buf); 177 mp_to64(&b, buf); 178 printf("%s\n", buf); 179 } else if (n == 5) { 180 /* mul_2d test */ 181 rand_num(&a); 182 mp_copy(&a, &b); 183 n = fgetc(rng) & 63; 184 mp_mul_2d(&b, n, &b); 185 mp_to64(&a, buf); 186 printf("mul2d\n"); 187 printf("%s\n", buf); 188 printf("%d\n", n); 189 mp_to64(&b, buf); 190 printf("%s\n", buf); 191 } else if (n == 6) { 192 /* div_2d test */ 193 rand_num(&a); 194 mp_copy(&a, &b); 195 n = fgetc(rng) & 63; 196 mp_div_2d(&b, n, &b, NULL); 197 mp_to64(&a, buf); 198 printf("div2d\n"); 199 printf("%s\n", buf); 200 printf("%d\n", n); 201 mp_to64(&b, buf); 202 printf("%s\n", buf); 203 } else if (n == 7) { 204 /* gcd test */ 205 rand_num(&a); 206 rand_num(&b); 207 a.sign = MP_ZPOS; 208 b.sign = MP_ZPOS; 209 mp_gcd(&a, &b, &c); 210 printf("gcd\n"); 211 mp_to64(&a, buf); 212 printf("%s\n", buf); 213 mp_to64(&b, buf); 214 printf("%s\n", buf); 215 mp_to64(&c, buf); 216 printf("%s\n", buf); 217 } else if (n == 8) { 218 /* lcm test */ 219 rand_num(&a); 220 rand_num(&b); 221 a.sign = MP_ZPOS; 222 b.sign = MP_ZPOS; 223 mp_lcm(&a, &b, &c); 224 printf("lcm\n"); 225 mp_to64(&a, buf); 226 printf("%s\n", buf); 227 mp_to64(&b, buf); 228 printf("%s\n", buf); 229 mp_to64(&c, buf); 230 printf("%s\n", buf); 231 } else if (n == 9) { 232 /* exptmod test */ 233 rand_num2(&a); 234 rand_num2(&b); 235 rand_num2(&c); 236 // if (c.dp[0]&1) mp_add_d(&c, 1, &c); 237 a.sign = b.sign = c.sign = 0; 238 mp_exptmod(&a, &b, &c, &d); 239 printf("expt\n"); 240 mp_to64(&a, buf); 241 printf("%s\n", buf); 242 mp_to64(&b, buf); 243 printf("%s\n", buf); 244 mp_to64(&c, buf); 245 printf("%s\n", buf); 246 mp_to64(&d, buf); 247 printf("%s\n", buf); 248 } else if (n == 10) { 249 /* invmod test */ 250 rand_num2(&a); 251 rand_num2(&b); 252 b.sign = MP_ZPOS; 253 a.sign = MP_ZPOS; 254 mp_gcd(&a, &b, &c); 255 if (mp_cmp_d(&c, 1) != 0) continue; 256 if (mp_cmp_d(&b, 1) == 0) continue; 257 mp_invmod(&a, &b, &c); 258 printf("invmod\n"); 259 mp_to64(&a, buf); 260 printf("%s\n", buf); 261 mp_to64(&b, buf); 262 printf("%s\n", buf); 263 mp_to64(&c, buf); 264 printf("%s\n", buf); 265 } else if (n == 11) { 266 rand_num(&a); 267 mp_mul_2(&a, &a); 268 mp_div_2(&a, &b); 269 printf("div2\n"); 270 mp_to64(&a, buf); 271 printf("%s\n", buf); 272 mp_to64(&b, buf); 273 printf("%s\n", buf); 274 } else if (n == 12) { 275 rand_num2(&a); 276 mp_mul_2(&a, &b); 277 printf("mul2\n"); 278 mp_to64(&a, buf); 279 printf("%s\n", buf); 280 mp_to64(&b, buf); 281 printf("%s\n", buf); 282 } else if (n == 13) { 283 rand_num2(&a); 284 tmp = abs(rand()) & THE_MASK; 285 mp_add_d(&a, tmp, &b); 286 printf("add_d\n"); 287 mp_to64(&a, buf); 288 printf("%s\n%d\n", buf, tmp); 289 mp_to64(&b, buf); 290 printf("%s\n", buf); 291 } else if (n == 14) { 292 rand_num2(&a); 293 tmp = abs(rand()) & THE_MASK; 294 mp_sub_d(&a, tmp, &b); 295 printf("sub_d\n"); 296 mp_to64(&a, buf); 297 printf("%s\n%d\n", buf, tmp); 298 mp_to64(&b, buf); 299 printf("%s\n", buf); 300 } 301 } 302 fclose(rng); 303 return 0; 304 } 305 306 /* $Source: /cvs/libtom/libtommath/mtest/mtest.c,v $ */ 307 /* $Revision: 1.2 $ */ 308 /* $Date: 2005/05/05 14:38:47 $ */ 309