int sha1Update(sha1Param* sp, const byte* data, size_t size) { register uint32_t proclength; #if (MP_WBITS == 64) mpw add[1]; mpsetw(1, add, size); mplshift(1, add, 3); (void) mpadd(1, sp->length, add); #elif (MP_WBITS == 32) mpw add[2]; mpsetw(2, add, size); mplshift(2, add, 3); (void) mpadd(2, sp->length, add); #else # error #endif while (size > 0) { proclength = ((sp->offset + size) > 64U) ? (64U - sp->offset) : size; memcpy(((byte *) sp->data) + sp->offset, data, proclength); size -= proclength; data += proclength; sp->offset += proclength; if (sp->offset == 64U) { sha1Process(sp); sp->offset = 0; } } return 0; }
int sha384Update(register sha384Param* sp, const byte* data, size_t size) { register size_t proclength; #if (MP_WBITS == 64) mpw add[2]; mpsetw(2, add, size); mplshift(2, add, 3); mpadd(2, sp->length, add); #elif (MP_WBITS == 32) mpw add[4]; mpsetws(4, add, size); mplshift(4, add, 3); mpadd(4, sp->length, add); #else # error #endif while (size > 0) { proclength = ((sp->offset + size) > 128U) ? (128U - sp->offset) : size; memcpy(((byte *) sp->data) + sp->offset, data, proclength); size -= proclength; data += proclength; sp->offset += proclength; if (sp->offset == 128U) { sha384Process(sp); sp->offset = 0; } } return 0; }
int ripemd256Update(ripemd256Param* mp, const byte* data, size_t size) { register uint32_t proclength; #if (MP_WBITS == 64) mpw add[1]; mpsetw(1, add, size); mplshift(1, add, 3); mpadd(1, mp->length, add); #elif (MP_WBITS == 32) mpw add[2]; mpsetw(2, add, size); mplshift(2, add, 3); (void) mpadd(2, mp->length, add); #else # error #endif while (size > 0) { proclength = ((mp->offset + size) > 64U) ? (64U - mp->offset) : size; /*@-mayaliasunique@*/ memcpy(((byte *) mp->data) + mp->offset, data, proclength); /*@=mayaliasunique@*/ size -= proclength; data += proclength; mp->offset += proclength; if (mp->offset == 64U) { ripemd256Process(mp); mp->offset = 0; } } return 0; }
int md2Update(md2Param *mp, const byte *data, size_t size) { uint32_t proclength; #if (MP_WBITS == 64) mpw add[1]; mpsetw(1, add, size); mplshift(1, add, 3); mpadd(1, mp->length, add); #elif (MP_WBITS == 32) mpw add[2]; mpsetw(2, add, size); mplshift(2, add, 3); (void) mpadd(2, mp->length, add); #else # error #endif while (size > 0) { proclength = ((mp->offset + size) > 16U) ? (16U - mp->offset) : size; /*@-mayaliasunique@*/ memcpy(((byte *)mp->buf) + mp->offset, data, proclength); /*@=mayaliasunique@*/ size -= proclength; data += proclength; mp->offset += proclength; /* is 16 bytes full? */ if (mp->offset == 16U) { md2_compress(mp); md2_update_chksum(mp); mp->offset = 0; } } return 0; }
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; }
/* * mpbtwopowmod_w * needs workspace of (4*size+2) words */ void mpbtwopowmod_w(const mpbarrett* b, size_t psize, const mpw* pdata, mpw* result, mpw* wksp) { /* * Modular exponention, 2^p mod modulus, special optimization * * Uses left-to-right exponentiation; needs no extra storage * */ /* this routine calls mpbmod, which needs (size*2+2), this routine needs (size*2) for sdata */ register size_t size = b->size; register mpw temp = 0; mpsetw(size, result, 1); while (psize) { if ((temp = *(pdata++))) /* break when first non-zero word found */ break; psize--; } /* if temp is still zero, then we're trying to raise x to power zero, and result stays one */ if (temp) { register int count = MP_WBITS; /* first skip bits until we reach a one */ while (count) { if (temp & MP_MSBMASK) break; temp <<= 1; count--; } while (psize--) { while (count) { /* always square */ mpbsqrmod_w(b, size, result, result, wksp); /* multiply by two if bit is 1 */ if (temp & MP_MSBMASK) { if (mpadd(size, result, result) || mpge(size, result, b->modl)) { /* there was carry, or the result is greater than the modulus, so we need to adjust */ mpsub(size, result, b->modl); } } temp <<= 1; count--; } count = MP_WBITS; temp = *(pdata++); } } }
void mpbpowmodsld_w(const mpbarrett* b, const mpw* slide, size_t psize, const mpw* pdata, mpw* result, mpw* wksp) { /* * Modular exponentiation with precomputed sliding window table, so no x is required * */ size_t size = b->size; mpw temp; mpsetw(size, result, 1); while (psize) { if ((temp = *(pdata++))) /* break when first non-zero word found in power */ break; psize--; } /* if temp is still zero, then we're trying to raise x to power zero, and result stays one */ if (temp) { short l = 0, n = 0, count = MP_WBITS; /* first skip bits until we reach a one */ while (count) { if (temp & MP_MSBMASK) break; temp <<= 1; count--; } while (psize) { while (count) { byte bit = (temp & MP_MSBMASK) ? 1 : 0; n <<= 1; n += bit; if (n) { if (l) l++; else if (bit) l = 1; if (l == 4) { byte s = mpbslide_presq[n]; while (s--) mpbsqrmod_w(b, size, result, result, wksp); mpbmulmod_w(b, size, result, size, slide+mpbslide_mulg[n]*size, result, wksp); s = mpbslide_postsq[n]; while (s--) mpbsqrmod_w(b, size, result, result, wksp); l = n = 0; } } else mpbsqrmod_w(b, size, result, result, wksp); temp <<= 1; count--; } if (--psize) { count = MP_WBITS; temp = *(pdata++); } } if (n) { byte s = mpbslide_presq[n]; while (s--) mpbsqrmod_w(b, size, result, result, wksp); mpbmulmod_w(b, size, result, size, slide+mpbslide_mulg[n]*size, result, wksp); s = mpbslide_postsq[n]; while (s--) mpbsqrmod_w(b, size, result, result, wksp); } } }