int sha1Reset(register sha1Param* p) { memcpy(p->h, hinit, 5 * sizeof(uint32_t)); memset(p->data, 0, 80 * sizeof(uint32_t)); #if (MP_WBITS == 64) mpzero(1, p->length); #elif (MP_WBITS == 32) mpzero(2, p->length); #else # error #endif p->offset = 0; return 0; }
int sha384Reset(register sha384Param* sp) { memcpy(sp->h, hinit, 8 * sizeof(uint64_t)); memset(sp->data, 0, 80 * sizeof(uint64_t)); #if (MP_WBITS == 64) mpzero(2, sp->length); #elif (MP_WBITS == 32) mpzero(4, sp->length); #else # error #endif sp->offset = 0; return 0; }
int md4Reset(md4Param* mp) { /*@-sizeoftype@*/ memcpy(mp->h, md4hinit, 4 * sizeof(uint32_t)); memset(mp->data, 0, 16 * sizeof(uint32_t)); /*@=sizeoftype@*/ #if (MP_WBITS == 64) mpzero(1, mp->length); #elif (MP_WBITS == 32) mpzero(2, mp->length); #else # error #endif mp->offset = 0; return 0; }
int ripemd256Reset(register ripemd256Param* mp) { /*@-sizeoftype@*/ memcpy(mp->h, ripemd256hinit, 8 * sizeof(uint32_t)); memset(mp->data, 0, 16 * sizeof(uint32_t)); /*@=sizeoftype@*/ #if (MP_WBITS == 64) mpzero(1, mp->length); #elif (MP_WBITS == 32) mpzero(2, mp->length); #else # error #endif mp->offset = 0; return 0; }
int md2Reset(md2Param *mp) { /* MD2 uses a zero'ed state... */ memset(mp->X, 0, sizeof(mp->X)); memset(mp->chksum, 0, sizeof(mp->chksum)); memset(mp->buf, 0, sizeof(mp->buf)); #if (MP_WBITS == 64) mpzero(1, mp->length); #elif (MP_WBITS == 32) mpzero(2, mp->length); #else # error #endif mp->offset = 0; return 0; }
/* * mpbsqrmod_w * computes the square (modulo b) of x * needs a workspace of (4*size+2) words */ void mpbsqrmod_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp) { /* xsize must be <= b->size */ register size_t size = b->size; register mpw* temp = wksp + size*2+2; register mpw fill = 2*(size-xsize); if (fill) mpzero(fill, temp); mpsqr(temp+fill, xsize, xdata); mpbmod_w(b, temp, result, wksp); }
/* * mpmulmod_w * computes the product (modulo b) of x and y * needs a workspace of (4*size+2) words */ void mpbmulmod_w(const mpbarrett* b, size_t xsize, const mpw* xdata, size_t ysize, const mpw* ydata, mpw* result, mpw* wksp) { /* xsize and ysize must be <= b->size */ register size_t size = b->size; register mpw* temp = wksp + size*2+2; register mpw fill = size*2-xsize-ysize; if (fill) mpzero(fill, temp); mpmul(temp+fill, xsize, xdata, ysize, ydata); mpbmod_w(b, temp, result, wksp); }
void mpbnsqrmod(const mpbarrett* b, const mpnumber* x, mpnumber* result) { register size_t size = b->size; register mpw* temp = (mpw*) malloc(size * sizeof(mpw)); /* xsize must be <= b->size */ register size_t fill = 2*(size-x->size); register mpw* opnd = temp + size*2+2; if (fill) mpzero(fill, opnd); mpsqr(opnd+fill, x->size, x->data); mpnsize(result, size); mpbmod_w(b, opnd, result->data, temp); free(temp); }
/* * mpbmu_w * computes the Barrett 'mu' coefficient * needs workspace of (6*size+4) words */ void mpbmu_w(mpbarrett* b, mpw* wksp) { register size_t size = b->size; register size_t shift; register mpw* divmod = wksp; register mpw* dividend = divmod+(size*2+2); register mpw* workspace = dividend+(size*2+1); /* normalize modulus before division */ shift = mpnorm(size, b->modl); /* make the dividend, initialize first word to 1 (shifted); the rest is zero */ *dividend = ((mpw) MP_LSBMASK << shift); mpzero(size*2, dividend+1); mpndivmod(divmod, size*2+1, dividend, size, b->modl, workspace); mpcopy(size+1, b->mu, divmod+1); /* de-normalize */ mprshift(size, b->modl, shift); }
/* * needs workspace of (size*2) words */ static void mpprndbits(mpbarrett* p, size_t bits, size_t lsbset, const mpnumber* min, const mpnumber* max, randomGeneratorContext* rc, mpw* wksp) { register size_t size = p->size; register size_t msbclr = MP_WORDS_TO_BITS(size) - bits; /* assume that mpbits(max) == bits */ /* calculate k=max-min; generate q such that 0 <= q <= k; then set p = q + min */ /* for the second step, set the appropriate number of bits */ if (max) { mpsetx(size, wksp, max->size, max->data); } else { mpfill(size, wksp, MP_ALLMASK); wksp[0] &= (MP_ALLMASK >> msbclr); } if (min) { mpsetx(size, wksp+size, min->size, min->data); } else { mpzero(size, wksp+size); wksp[size] |= (MP_MSBMASK >> msbclr); } mpsub(size, wksp, wksp+size); rc->rng->next(rc->param, (byte*) p->modl, MP_WORDS_TO_BYTES(size)); p->modl[0] &= (MP_ALLMASK >> msbclr); while (mpgt(size, p->modl, wksp)) mpsub(size, p->modl, wksp); mpadd(size, p->modl, wksp+size); if (lsbset) p->modl[size-1] |= (MP_ALLMASK >> (MP_WBITS - lsbset)); }
void mpbnmulmod(const mpbarrett* b, const mpnumber* x, const mpnumber* y, mpnumber* result) { register size_t size = b->size; register mpw* temp = (mpw*) malloc((4*size+2) * sizeof(mpw)); /* xsize and ysize must be <= b->size */ register size_t fill = 2*size-x->size-y->size; register mpw* opnd = temp+size*2+2; mpnfree(result); mpnsize(result, size); if (fill) mpzero(fill, opnd); mpmul(opnd+fill, x->size, x->data, y->size, y->data); mpbmod_w(b, opnd, result->data, temp); free(temp); }
static int Zmpbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp) { size_t ysize = b->size+1; size_t ubits, vbits; int k = 0; mpw* u = wksp; mpw* v = u+ysize; mpw* A = v+ysize; mpw* B = A+ysize; mpw* C = B+ysize; mpw* D = C+ysize; mpsetx(ysize, u, xsize, xdata); mpsetx(ysize, v, b->size, b->modl); mpsetw(ysize, A, 1); mpzero(ysize, B); mpzero(ysize, C); mpsetw(ysize, D, 1); for (k = 0; mpeven(ysize, u) && mpeven(ysize, v); k++) { mpdivtwo(ysize, u); mpdivtwo(ysize, v); } if (mpeven(ysize, u)) (void) mpadd(ysize, u, v); if (_debug < 0) fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); if (_debug < 0) fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); if (_debug < 0) fprintf(stderr, " A: "), mpfprintln(stderr, ysize, A); if (_debug < 0) fprintf(stderr, " B: "), mpfprintln(stderr, ysize, B); if (_debug < 0) fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); if (_debug < 0) fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); ubits = vbits = MP_WORDS_TO_BITS(ysize); do { while (mpeven(ysize, v)) { mpsdivtwo(ysize, v); vbits -= 1; if (mpodd(ysize, C)) { (void) mpaddx(ysize, C, b->size, b->modl); (void) mpsubx(ysize, D, xsize, xdata); } mpsdivtwo(ysize, C); mpsdivtwo(ysize, D); if (_debug < 0) fprintf(stderr, "-->> v: "), mpfprintln(stderr, ysize, v); } if (ubits >= vbits) { mpw* swapu; size_t swapi; if (_debug < 0) fprintf(stderr, "--> (swap u <-> v)\n"); swapu = u; u = v; v = swapu; swapi = ubits; ubits = vbits; vbits = swapi; swapu = A; A = C; C = swapu; swapu = B; B = D; D = swapu; } if (!((u[ysize-1] + v[ysize-1]) & 0x3)) { if (_debug < 0) fprintf(stderr, "--> (even parity)\n"); mpadd(ysize, v, u); mpadd(ysize, C, A); mpadd(ysize, D, B); } else { if (_debug < 0) fprintf(stderr, "--> (odd parity)\n"); mpsub(ysize, v, u); mpsub(ysize, C, A); mpsub(ysize, D, B); } if (_debug < 0) fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); if (_debug < 0) fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); if (_debug < 0) fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); vbits++; } while (mpnz(ysize, v)); #ifdef NOTYET if (!mpisone(ysize, u)) return 0; #endif if (result) { mpsetx(b->size, result, ysize, A); /*@-usedef@*/ if (*A & 0x80000000) (void) mpneg(b->size, result); /*@=usedef@*/ while (--k > 0) mpadd(b->size, result, result); } fprintf(stderr, "=== EXIT: "), mpfprintln(stderr, b->size, result); fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); fprintf(stderr, " A: "), mpfprintln(stderr, ysize, A); fprintf(stderr, " B: "), mpfprintln(stderr, ysize, B); fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); return 1; }
/** * Computes the inverse (modulo b) of x, and returns 1 if x was invertible. * needs workspace of (6*size+6) words * @note xdata and result cannot point to the same area */ static int Xmpbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp) { /* * Fact: if a element of Zn, then a is invertible if and only if gcd(a,n) = 1 * Hence: if b->modl is even, then x must be odd, otherwise the gcd(x,n) >= 2 * * The calling routine must guarantee this condition. */ size_t ysize = b->size+1; mpw* u = wksp; mpw* v = u+ysize; mpw* A = v+ysize; mpw* B = A+ysize; mpw* C = B+ysize; mpw* D = C+ysize; mpsetx(ysize, u, b->size, b->modl); mpsetx(ysize, v, xsize, xdata); mpsetw(ysize, A, 1); mpzero(ysize, B); mpzero(ysize, C); mpsetw(ysize, D, 1); if (_debug < 0) fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); if (_debug < 0) fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); if (_debug < 0) fprintf(stderr, " A: "), mpfprintln(stderr, ysize, A); if (_debug < 0) fprintf(stderr, " B: "), mpfprintln(stderr, ysize, B); if (_debug < 0) fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); if (_debug < 0) fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); do { while (mpeven(ysize, u)) { mpdivtwo(ysize, u); if (mpodd(ysize, A) || mpodd(ysize, B)) { (void) mpaddx(ysize, A, xsize, xdata); (void) mpsubx(ysize, B, b->size, b->modl); } mpsdivtwo(ysize, A); mpsdivtwo(ysize, B); } while (mpeven(ysize, v)) { mpdivtwo(ysize, v); if (mpodd(ysize, C) || mpodd(ysize, D)) { (void) mpaddx(ysize, C, xsize, xdata); (void) mpsubx(ysize, D, b->size, b->modl); } mpsdivtwo(ysize, C); mpsdivtwo(ysize, D); } if (mpge(ysize, u, v)) { if (_debug < 0) fprintf(stderr, "--> 5 (u >= v)\n"); (void) mpsub(ysize, u, v); (void) mpsub(ysize, A, C); (void) mpsub(ysize, B, D); if (_debug < 0) fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); if (_debug < 0) fprintf(stderr, " A: "), mpfprintln(stderr, ysize, A); if (_debug < 0) fprintf(stderr, " B: "), mpfprintln(stderr, ysize, B); } else { if (_debug < 0) fprintf(stderr, "--> 5 (u < v)\n"); (void) mpsub(ysize, v, u); (void) mpsub(ysize, C, A); (void) mpsub(ysize, D, B); if (_debug < 0) fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); if (_debug < 0) fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); if (_debug < 0) fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); } } while (mpnz(ysize, u)); if (!mpisone(ysize, v)) return 0; if (result) { mpsetx(b->size, result, ysize, D); /*@-usedef@*/ if (*D & 0x80000000) (void) mpadd(b->size, result, b->modl); /*@=usedef@*/ } fprintf(stderr, "=== EXIT: "), mpfprintln(stderr, b->size, result); fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); fprintf(stderr, " A: "), mpfprintln(stderr, ysize, A); fprintf(stderr, " B: "), mpfprintln(stderr, ysize, B); fprintf(stderr, " C: "), mpfprintln(stderr, ysize, C); fprintf(stderr, " D: "), mpfprintln(stderr, ysize, D); return 1; }
static int Ympbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp) { size_t ysize = b->size+1; int k; mpw* u1 = wksp; mpw* u2 = u1+ysize; mpw* u3 = u2+ysize; mpw* v1 = u3+ysize; mpw* v2 = v1+ysize; mpw* v3 = v2+ysize; mpw* t1 = v3+ysize; mpw* t2 = t1+ysize; mpw* t3 = t2+ysize; mpw* u = t3+ysize; mpw* v = u+ysize; mpsetx(ysize, u, xsize, xdata); mpsetx(ysize, v, b->size, b->modl); /* Y1. Find power of 2. */ for (k = 0; mpeven(ysize, u) && mpeven(ysize, v); k++) { mpdivtwo(ysize, u); mpdivtwo(ysize, v); } if (_debug < 0) fprintf(stderr, " u: "), mpfprintln(stderr, ysize, u); if (_debug < 0) fprintf(stderr, " v: "), mpfprintln(stderr, ysize, v); /* Y2. Initialize. */ mpsetw(ysize, u1, 1); if (_debug < 0) fprintf(stderr, " u1: "), mpfprintln(stderr, ysize, u1); mpzero(ysize, u2); if (_debug < 0) fprintf(stderr, " u2: "), mpfprintln(stderr, ysize, u2); mpsetx(ysize, u3, ysize, u); if (_debug < 0) fprintf(stderr, " u3: "), mpfprintln(stderr, ysize, u3); mpsetx(ysize, v1, ysize, v); if (_debug < 0) fprintf(stderr, " v1: "), mpfprintln(stderr, ysize, v1); mpsetw(ysize, v2, 1); (void) mpsub(ysize, v2, u); if (_debug < 0) fprintf(stderr, " v2: "), mpfprintln(stderr, ysize, v2); mpsetx(ysize, v3, ysize, v); if (_debug < 0) fprintf(stderr, " v3: "), mpfprintln(stderr, ysize, v3); if (mpodd(ysize, u)) { mpzero(ysize, t1); if (_debug < 0) fprintf(stderr, " t1: "), mpfprintln(stderr, ysize, t1); mpzero(ysize, t2); mpsubw(ysize, t2, 1); if (_debug < 0) fprintf(stderr, " t2: "), mpfprintln(stderr, ysize, t2); mpzero(ysize, t3); mpsub(ysize, t3, v); if (_debug < 0) fprintf(stderr, " t3: "), mpfprintln(stderr, ysize, t3); goto Y4; } else { mpsetw(ysize, t1, 1); if (_debug < 0) fprintf(stderr, " t1: "), mpfprintln(stderr, ysize, t1); mpzero(ysize, t2); if (_debug < 0) fprintf(stderr, " t2: "), mpfprintln(stderr, ysize, t2); mpsetx(ysize, t3, ysize, u); if (_debug < 0) fprintf(stderr, " t3: "), mpfprintln(stderr, ysize, t3); } do { do { if (mpodd(ysize, t1) || mpodd(ysize, t2)) { mpadd(ysize, t1, v); mpsub(ysize, t2, u); } mpsdivtwo(ysize, t1); mpsdivtwo(ysize, t2); mpsdivtwo(ysize, t3); Y4: if (_debug < 0) fprintf(stderr, " Y4 t3: "), mpfprintln(stderr, ysize, t3); } while (mpeven(ysize, t3)); /* Y5. Reset max(u3,v3). */ if (!(*t3 & 0x80000000)) { if (_debug < 0) fprintf(stderr, "--> Y5 (t3 > 0)\n"); mpsetx(ysize, u1, ysize, t1); if (_debug < 0) fprintf(stderr, " u1: "), mpfprintln(stderr, ysize, u1); mpsetx(ysize, u2, ysize, t2); if (_debug < 0) fprintf(stderr, " u2: "), mpfprintln(stderr, ysize, u2); mpsetx(ysize, u3, ysize, t3); if (_debug < 0) fprintf(stderr, " u3: "), mpfprintln(stderr, ysize, u3); } else { if (_debug < 0) fprintf(stderr, "--> Y5 (t3 <= 0)\n"); mpsetx(ysize, v1, ysize, v); mpsub(ysize, v1, t1); if (_debug < 0) fprintf(stderr, " v1: "), mpfprintln(stderr, ysize, v1); mpsetx(ysize, v2, ysize, u); mpneg(ysize, v2); mpsub(ysize, v2, t2); if (_debug < 0) fprintf(stderr, " v2: "), mpfprintln(stderr, ysize, v2); mpzero(ysize, v3); mpsub(ysize, v3, t3); if (_debug < 0) fprintf(stderr, " v3: "), mpfprintln(stderr, ysize, v3); } /* Y6. Subtract. */ mpsetx(ysize, t1, ysize, u1); mpsub(ysize, t1, v1); mpsetx(ysize, t2, ysize, u2); mpsub(ysize, t2, v2); mpsetx(ysize, t3, ysize, u3); mpsub(ysize, t3, v3); if (*t1 & 0x80000000) { mpadd(ysize, t1, v); mpsub(ysize, t2, u); } if (_debug < 0) fprintf(stderr, "-->Y6 t1: "), mpfprintln(stderr, ysize, t1); if (_debug < 0) fprintf(stderr, " t2: "), mpfprintln(stderr, ysize, t2); if (_debug < 0) fprintf(stderr, " t3: "), mpfprintln(stderr, ysize, t3); } while (mpnz(ysize, t3)); if (!(mpisone(ysize, u3) && mpisone(ysize, v3))) return 0; if (result) { while (--k > 0) mpadd(ysize, u1, u1); mpsetx(b->size, result, ysize, u1); } fprintf(stderr, "=== EXIT: "), mpfprintln(stderr, b->size, result); fprintf(stderr, " u1: "), mpfprintln(stderr, ysize, u1); fprintf(stderr, " u2: "), mpfprintln(stderr, ysize, u2); fprintf(stderr, " u3: "), mpfprintln(stderr, ysize, u3); fprintf(stderr, " v1: "), mpfprintln(stderr, ysize, v1); fprintf(stderr, " v2: "), mpfprintln(stderr, ysize, v2); fprintf(stderr, " v3: "), mpfprintln(stderr, ysize, v3); fprintf(stderr, " t1: "), mpfprintln(stderr, ysize, t1); fprintf(stderr, " t2: "), mpfprintln(stderr, ysize, t2); fprintf(stderr, " t3: "), mpfprintln(stderr, ysize, t3); return 1; }
void mpbwipe(mpbarrett* b) { if (b->modl != (mpw*) 0) mpzero(2*(b->size)+1, b->modl); }