/* init a new mp_int */ int mp_init (mp_int * a) { #ifdef __UHC_BUILDS_RTS__ // all allocation is assumed to be done outside library mp_zero(a) ; printf( "WARNING: mp_init (%p used=%x alc=%x)\n", a, USED(a), ALLOC(a) ) ; // prLTM(a,"mp_init") ; #else int i; /* allocate memory required and clear it */ SET_DIGITS(a, OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC)); if (DIGITS(a) == NULL) { return MP_MEM; } /* set the digits to zero */ for (i = 0; i < MP_PREC; i++) { SET_DIGIT(a,i,0); } /* set the used to zero, allocated digits to the default precision * and sign to positive */ SET_USED(a,0); SET_ALLOC(a,MP_PREC); SET_SIGN(a,MP_ZPOS); #endif return MP_OKAY; }
void *malloc(ssize_t size_) { void *at = mem_ptr; uint32_t size = (uint32_t)ROUNDUP(size_, BYTES_PER_LONG) + BYTES_PER_LONG; int looped = 0; uint32_t expand_size; void *expanded; /* Scan the current heap for an opening. */ while (!looped || at < mem_ptr) { uint32_t at_size = BLOCK_SIZE(at); if (!IS_USED(at) && at_size >= size && at_size - size != BYTES_PER_LONG) { /* We can use this block. */ void *leftover = at + size; SET_SIZE(at, size); SET_USED(at); SET_SIZE(leftover, at_size - size); SET_UNUSED(leftover); mem_ptr = leftover; return PTR(at); } at += at_size; if (at >= curr_brk) { at = orig_brk; looped = 1; } } /* Expand the heap. */ expand_size = size + BUFFER_SIZE; expanded = mbrk(curr_brk + expand_size); if (expanded != at + expand_size) return NULL; at = curr_brk; curr_brk = expanded; SET_SIZE(at, size); SET_USED(at); SET_SIZE(at + size, expand_size - size); SET_UNUSED(at + size); return PTR(at); }
/* b = a/2 */ int mp_div_2(mp_int * a, mp_int * b) { int x, res, oldused; /* copy */ if (ALLOC(b) < USED(a)) { if ((res = mp_grow (b, USED(a))) != MP_OKAY) { return res; } } oldused = USED(b); SET_USED(b,USED(a)); { register mp_digit r, rr, *tmpa, *tmpb; /* source alias */ tmpa = DIGITS(a) + USED(b) - 1; /* dest alias */ tmpb = DIGITS(b) + USED(b) - 1; /* carry */ r = 0; for (x = USED(b) - 1; x >= 0; x--) { /* get the carry for the next iteration */ rr = *tmpa & 1; /* shift the current digit, add in carry and store */ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); /* forward carry to next iteration */ r = rr; } /* zero excess digits */ tmpb = DIGITS(b) + USED(b); for (x = USED(b); x < oldused; x++) { *tmpb++ = 0; } } SET_SIGN(b,SIGN(a)); mp_clamp (b); return MP_OKAY; }
/* Karatsuba squaring, computes b = a*a using three * half size squarings * * See comments of karatsuba_mul for details. It * is essentially the same algorithm but merely * tuned to perform recursive squarings. */ int mp_karatsuba_sqr (mp_int * a, mp_int * b) { mp_int x0, x1, t1, t2, x0x0, x1x1; int B, err; err = MP_MEM; /* min # of digits */ B = USED(a); /* now divide in two */ B = B >> 1; /* init copy all the temps */ if (mp_init_size (&x0, B) != MP_OKAY) goto ERR; if (mp_init_size (&x1, USED(a) - B) != MP_OKAY) goto X0; /* init temps */ if (mp_init_size (&t1, USED(a) * 2) != MP_OKAY) goto X1; if (mp_init_size (&t2, USED(a) * 2) != MP_OKAY) goto T1; if (mp_init_size (&x0x0, B * 2) != MP_OKAY) goto T2; if (mp_init_size (&x1x1, (USED(a) - B) * 2) != MP_OKAY) goto X0X0; { register int x; register mp_digit *dst, *src; src = DIGITS(a); /* now shift the digits */ dst = DIGITS(&x0); for (x = 0; x < B; x++) { *dst++ = *src++; } dst = DIGITS(&x1); for (x = B; x < USED(a); x++) { *dst++ = *src++; } } SET_USED(&x0,B); SET_USED(&x1,USED(a) - B); mp_clamp (&x0); /* now calc the products x0*x0 and x1*x1 */ if (mp_sqr (&x0, &x0x0) != MP_OKAY) goto X1X1; /* x0x0 = x0*x0 */ if (mp_sqr (&x1, &x1x1) != MP_OKAY) goto X1X1; /* x1x1 = x1*x1 */ /* now calc (x1+x0)**2 */ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY) goto X1X1; /* t1 = x1 - x0 */ if (mp_sqr (&t1, &t1) != MP_OKAY) goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */ /* add x0y0 */ if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY) goto X1X1; /* t2 = x0x0 + x1x1 */ if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY) goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */ /* shift by B */ if (mp_lshd (&t1, B) != MP_OKAY) goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */ if (mp_lshd (&x1x1, B * 2) != MP_OKAY) goto X1X1; /* x1x1 = x1x1 << 2*B */ if (mp_add (&x0x0, &t1, &t1) != MP_OKAY) goto X1X1; /* t1 = x0x0 + t1 */ if (mp_add (&t1, &x1x1, b) != MP_OKAY) goto X1X1; /* t1 = x0x0 + t1 + x1x1 */ err = MP_OKAY; X1X1:mp_clear (&x1x1); X0X0:mp_clear (&x0x0); T2:mp_clear (&t2); T1:mp_clear (&t1); X1:mp_clear (&x1); X0:mp_clear (&x0); ERR: return err; }