6 typedef struct ldint ldint;
13 ldint _ldzero = {1, (u8int*)"\0"};
14 ldint _ldone = {2, (u8int*)"\1\0"};
15 ldint *ldzero = &_ldzero;
16 ldint *ldone = &_ldone;
19 ldget(ldint *a, int n)
22 if(n >= a->n) return a->b[a->n - 1]&1;
27 ldbits(ldint *a, int n)
29 a->b = realloc(a->b, n);
39 for(i = a->n - 2; i >= 0; i--)
40 if(a->b[i] != a->b[a->n-1])
53 for(i = 0; i < a->n; i++){
71 a = malloc(sizeof(ldint));
90 for(i = 0; i < a->n; i++)
95 ldrand(int n, ldint *a)
103 for(i = 0; i < n; i++)
104 a->b[i] = rand() & 1;
109 ldtomp(ldint *a, mpint *b)
116 s = a->b[a->n - 1] & 1;
119 memset(b->p, 0, (a->n + Dbits - 1) / Dbits * Dbytes);
120 for(i = 0; i < a->n; i++){
121 c += s ^ a->b[i] & 1;
122 b->p[i / Dbits] |= (mpdigit)(c & 1) << (i & Dbits - 1);
125 b->top = (a->n + Dbits - 1) / Dbits;
131 mptold(mpint *b, ldint *a)
138 for(i = 0; i <= b->top; i++)
139 for(j = 0; j < Dbits; j++)
140 if(Dbits * i + j < n)
141 a->b[Dbits * i + j] = b->p[i] >> j & 1;
144 for(i = 0; i < a->n; i++){
145 c += 1 ^ a->b[i] & 1;
153 itold(int n, ldint *a)
158 a = ldnew(sizeof(n)*8);
160 ldbits(a, sizeof(n)*8);
161 for(i = 0; i < sizeof(n)*8; i++)
162 a->b[i] = n >> i & 1;
168 pow2told(int n, ldint *a)
177 memset(a->b, 0, k+2);
190 a = va_arg(f->args, ldint *);
192 b = calloc(1, d + 1);
193 c = s = a->b[a->n - 1];
194 for(i = 0; i < a->n; i++){
196 b[d - 1 - (i >> 2)] |= (c & 1) << (i & 3);
199 for(i = 0; i < d; i++)
200 b[i] = "0123456789ABCDEF"[b[i]];
202 while(*p == '0' && p[1] != 0) p++;
203 if(a->b[a->n - 1]) fmtrune(f, '-');
204 fmtprint(f, "0x%s", p);
210 ldmpeq(ldint *a, mpint *b)
215 for(i = 0; i < b->top * Dbits; i++)
216 if(ldget(a, i) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
224 for(i = 0; i < b->top * Dbits; i++){
226 if((c & 1) != (b->p[i / Dbits] >> (i & Dbits - 1) & 1))
245 mpbits(r, n * Dbits);
247 prng((void *) r->p, n * Dbytes);
248 r->sign = 1 - 2 * (rand() & 1);
253 ldadd(ldint *a, ldint *b, ldint *q)
257 r = max(a->n, b->n) + 1;
260 for(i = 0; i < r; i++){
261 c += ldget(a, i) + ldget(b, i);
269 ldsub(ldint *a, ldint *b, ldint *q)
273 r = max(a->n, b->n) + 1;
276 for(i = 0; i < r; i++){
277 c += ldget(a, i) + (1^ldget(b, i));
285 ldmul(ldint *a, ldint *b, ldint *q)
287 int c1, c2, co, s1, s2, so, i, j;
289 c1 = s1 = a->b[a->n - 1] & 1;
290 s2 = b->b[b->n - 1] & 1;
292 ldbits(q, a->n + b->n + 1);
293 memset(q->b, 0, a->n + b->n + 1);
294 for(i = 0; i < a->n; i++){
295 c1 += s1 ^ a->b[i] & 1;
298 for(j = 0; j < b->n; j++){
299 c2 += (s2 ^ b->b[j] & 1) + q->b[i + j];
300 q->b[i + j] = c2 & 1;
304 assert(i + j < q->n);
305 q->b[i + j] = c2 & 1;
312 for(i = 0; i < q->n; i++){
320 lddiv(ldint *a, ldint *b, ldint *q, ldint *r)
322 int n, i, j, c, s, k;
324 n = max(a->n, b->n) + 1;
328 c = s = a->b[a->n-1];
329 for(i = 0; i < n; i++){
330 c += s ^ ldget(a, i);
334 for(i = 0; i < n; i++){
335 for(j = n-1; --j >= 0; )
336 r->b[j + 1] = r->b[j];
337 r->b[0] = q->b[n - 1];
338 for(j = n-1; --j >= 0; )
339 q->b[j + 1] = q->b[j];
340 q->b[0] = !r->b[n - 1];
341 c = s = r->b[n - 1] == b->b[b->n - 1];
342 for(j = 0; j < n; j++){
343 c += r->b[j] + (s ^ ldget(b, j));
348 for(j = n-1; --j >= 0; )
349 q->b[j + 1] = q->b[j];
353 for(j = 0; j < n; j++){
358 c = s = b->b[b->n - 1];
359 for(j = 0; j < n; j++){
360 c += r->b[j] + (s ^ ldget(b, j));
365 c = s = a->b[a->n-1] ^ b->b[b->n-1];
366 for(j = 0; j < n; j++){
371 c = s = a->b[a->n-1];
372 for(j = 0; j < n; j++){
382 lddivq(ldint *a, ldint *b, ldint *q)
386 if(ldmpeq(b, mpzero)){
387 memset(q->b, 0, q->n);
396 mpdivq(mpint *a, mpint *b, mpint *q)
398 if(mpcmp(b, mpzero) == 0){
406 lddivr(ldint *a, ldint *b, ldint *r)
410 if(ldmpeq(b, mpzero)){
411 memset(r->b, 0, r->n);
420 mpdivr(mpint *a, mpint *b, mpint *r)
422 if(mpcmp(b, mpzero) == 0){
430 ldand(ldint *a, ldint *b, ldint *q)
436 for(i = 0; i < r; i++)
437 q->b[i] = ldget(a, i) & ldget(b, i);
442 ldbic(ldint *a, ldint *b, ldint *q)
448 for(i = 0; i < r; i++)
449 q->b[i] = ldget(a, i) & ~ldget(b, i);
454 ldor(ldint *a, ldint *b, ldint *q)
460 for(i = 0; i < r; i++)
461 q->b[i] = ldget(a, i) | ldget(b, i);
466 ldxor(ldint *a, ldint *b, ldint *q)
472 for(i = 0; i < r; i++)
473 q->b[i] = ldget(a, i) ^ ldget(b, i);
477 typedef struct Test2 Test2;
480 void (*dut)(mpint *, mpint *, mpint *);
481 void (*ref)(ldint *, ldint *, ldint *);
485 validate(char *name, ldint *ex, mpint *res, char *str)
490 if(res->top == 0 && res->sign < 0){
491 fprint(2, "FAIL: %s: %s: got -0, shouldn't happen\n", name, str);
493 }else if(!ldmpeq(ex, res)){
494 fprint(2, "FAIL: %s: %s: got %#B, expected %L\n", name, str, res, ex);
502 test2(Test2 *t, ldint *a, ldint *b)
517 rv = validate(t->name, c, rc, smprint("%L and %L", a, b));
521 rv = validate(t->name, c, mb, smprint("%L and %L (aliased to result)", a, b));
525 rv = validate(t->name, c, ma, smprint("%L (aliased to result) and %L", a, b));
534 test2x(Test2 *t, ldint *a)
547 rv = validate(t->name, c, rc, smprint("%L and %L (aliased to each other)", a, a));
550 rv = validate(t->name, c, ma, smprint("%L and %L (both aliased to result)", a, a));
567 for(i = -128; i <= 128; i++)
568 for(j = -128; j <= 128; j++){
571 ok &= test2(t, a, b);
574 ok &= test2(t, a, b);
575 ok &= test2(t, b, a);
578 ok &= test2(t, a, b);
580 for(i = 1; i <= 4; i++)
581 for(j = 1; j <= 4; j++){
582 ldrand(i * Dbits, a);
583 ldrand(j * Dbits, b);
584 ok &= test2(t, a, b);
586 for(i = -128; i <= 128; i++){
595 fprint(2, "%s: passed\n", t->name);
599 "mpdiv(q)", mpdivq, lddivq,
600 "mpdiv(r)", mpdivr, lddivr,
601 "mpmul", mpmul, ldmul,
602 "mpadd", mpadd, ldadd,
603 "mpsub", mpsub, ldsub,
604 "mpand", mpand, ldand,
606 "mpbic", mpbic, ldbic,
607 "mpxor", mpxor, ldxor,
615 for(t = tests2; t < tests2 + nelem(tests2); t++)
622 fmtinstall('B', mpfmt);
623 fmtinstall('L', ldfmt);