static int ltm_rsa_private_calculate(mp_int * in, mp_int * p, mp_int * q, mp_int * dmp1, mp_int * dmq1, mp_int * iqmp, mp_int * out) { mp_int vp, vq, u; mp_init_multi(&vp, &vq, &u, NULL); /* vq = c ^ (d mod (q - 1)) mod q */ /* vp = c ^ (d mod (p - 1)) mod p */ mp_mod(in, p, &u); mp_exptmod(&u, dmp1, p, &vp); mp_mod(in, q, &u); mp_exptmod(&u, dmq1, q, &vq); /* C2 = 1/q mod p (iqmp) */ /* u = (vp - vq)C2 mod p. */ mp_sub(&vp, &vq, &u); if (mp_isneg(&u)) mp_add(&u, p, &u); mp_mul(&u, iqmp, &u); mp_mod(&u, p, &u); /* c ^ d mod n = vq + u q */ mp_mul(&u, q, &u); mp_add(&u, &vq, out); mp_clear_multi(&vp, &vq, &u, NULL); return 0; }
/* this function is less generic than mp_n_root, simpler and faster */ int mp_sqrt(mp_int *arg, mp_int *ret) { int res; mp_int t1,t2; /* must be positive */ if (arg->sign == MP_NEG) { return MP_VAL; } /* easy out */ if (mp_iszero(arg) == MP_YES) { mp_zero(ret); return MP_OKAY; } if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { return res; } if ((res = mp_init(&t2)) != MP_OKAY) { goto E2; } /* First approx. (not very bad for large arg) */ mp_rshd (&t1,t1.used/2); /* t1 > 0 */ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { goto E1; } if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { goto E1; } if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { goto E1; } /* And now t1 > sqrt(arg) */ do { if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { goto E1; } if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { goto E1; } if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { goto E1; } /* t1 >= sqrt(arg) >= t2 at this point */ } while (mp_cmp_mag(&t1,&t2) == MP_GT); mp_exch(&t1,ret); E1: mp_clear(&t2); E2: mp_clear(&t1); return res; }
/* c = a mod b, 0 <= c < b */ int mp_mod (mp_int * a, mp_int * b, mp_int * c) { mp_int t; int res; if ((res = mp_init (&t)) != MP_OKAY) { return res; } if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) { mp_clear (&t); return res; } if (t.sign != b->sign) { res = mp_add (b, &t, c); } else { res = MP_OKAY; mp_exch (&t, c); } mp_clear (&t); return res; }
/* c = a mod b, 0 <= c < b */ int mp_mod (mp_int * a, mp_int * b, mp_int * c) { MP_LOCAL_DEF(t); int res; mp_local_init(t,USED(b),res) ; if (res != MP_OKAY) { return res; } if ((res = mp_div (a, b, NULL, MP_LOCAL_REF(t))) != MP_OKAY) { mp_local_clear(t); return res; } if (SIGN(MP_LOCAL_REF(t)) != SIGN(b)) { res = mp_add (b, MP_LOCAL_REF(t), c); } else { res = MP_OKAY; mp_local_assignfrom(c, t) ; } mp_local_clear(t); return res; }
void bn_add (mp_int *a, mp_int *b, mp_int *c) { int ret = mp_add (a, b, c); if (ret != MP_OKAY) Fatal (1, error, "Error adding numbers"); };
/* add */ static int add(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_add(a, b, c)); }
static int is_point(ecc_key *key) { void *prime, *b, *t1, *t2; int err; if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) { return err; } /* load prime and b */ if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; } if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; } /* compute y^2 */ if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; } /* compute x^3 */ if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; } if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; } if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; } /* compute y^2 - x^3 */ if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; } /* compute y^2 - x^3 + 3x */ if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; } while (mp_cmp_d(t1, 0) == LTC_MP_LT) { if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; } } while (mp_cmp(t1, prime) != LTC_MP_LT) { if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; } } /* compare to b */ if (mp_cmp(t1, b) != LTC_MP_EQ) { err = CRYPT_INVALID_PACKET; } else { err = CRYPT_OK; } error: mp_clear_multi(prime, b, t1, t2, NULL); return err; }
/* ** RSA Private key operation using CRT. */ static SECStatus rsa_PrivateKeyOpCRTNoCheck(RSAPrivateKey *key, mp_int *m, mp_int *c) { mp_int p, q, d_p, d_q, qInv; mp_int m1, m2, h, ctmp; mp_err err = MP_OKAY; SECStatus rv = SECSuccess; MP_DIGITS(&p) = 0; MP_DIGITS(&q) = 0; MP_DIGITS(&d_p) = 0; MP_DIGITS(&d_q) = 0; MP_DIGITS(&qInv) = 0; MP_DIGITS(&m1) = 0; MP_DIGITS(&m2) = 0; MP_DIGITS(&h) = 0; MP_DIGITS(&ctmp) = 0; CHECK_MPI_OK( mp_init(&p) ); CHECK_MPI_OK( mp_init(&q) ); CHECK_MPI_OK( mp_init(&d_p) ); CHECK_MPI_OK( mp_init(&d_q) ); CHECK_MPI_OK( mp_init(&qInv) ); CHECK_MPI_OK( mp_init(&m1) ); CHECK_MPI_OK( mp_init(&m2) ); CHECK_MPI_OK( mp_init(&h) ); CHECK_MPI_OK( mp_init(&ctmp) ); /* copy private key parameters into mp integers */ SECITEM_TO_MPINT(key->prime1, &p); /* p */ SECITEM_TO_MPINT(key->prime2, &q); /* q */ SECITEM_TO_MPINT(key->exponent1, &d_p); /* d_p = d mod (p-1) */ SECITEM_TO_MPINT(key->exponent2, &d_q); /* d_q = d mod (q-1) */ SECITEM_TO_MPINT(key->coefficient, &qInv); /* qInv = q**-1 mod p */ /* 1. m1 = c**d_p mod p */ CHECK_MPI_OK( mp_mod(c, &p, &ctmp) ); CHECK_MPI_OK( mp_exptmod(&ctmp, &d_p, &p, &m1) ); /* 2. m2 = c**d_q mod q */ CHECK_MPI_OK( mp_mod(c, &q, &ctmp) ); CHECK_MPI_OK( mp_exptmod(&ctmp, &d_q, &q, &m2) ); /* 3. h = (m1 - m2) * qInv mod p */ CHECK_MPI_OK( mp_submod(&m1, &m2, &p, &h) ); CHECK_MPI_OK( mp_mulmod(&h, &qInv, &p, &h) ); /* 4. m = m2 + h * q */ CHECK_MPI_OK( mp_mul(&h, &q, m) ); CHECK_MPI_OK( mp_add(m, &m2, m) ); cleanup: mp_clear(&p); mp_clear(&q); mp_clear(&d_p); mp_clear(&d_q); mp_clear(&qInv); mp_clear(&m1); mp_clear(&m2); mp_clear(&h); mp_clear(&ctmp); if (err) { MP_TO_SEC_ERROR(err); rv = SECFailure; } return rv; }
/** * bignum_add - c = a + b * @a: Bignum from bignum_init() * @b: Bignum from bignum_init() * @c: Bignum from bignum_init(); used to store the result of a + b * Returns: 0 on success, -1 on failure */ int bignum_add(const struct bignum *a, const struct bignum *b, struct bignum *c) { if (mp_add((mp_int *) a, (mp_int *) b, (mp_int *) c) != MP_OKAY) { wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); return -1; } return 0; }
int main() { unsigned int a, b, r; r = mp_add(a, b); __VERIFIER_assert(r == a + b); return 0; }
int main() { unsigned int a = input(); unsigned int b = input(), r; r = mp_add(a, b); assert(r == a + b); return 0; }
static int mp_add1(mp_int *a, mp_int *b) { mp_int one; int ret = MP_OKAY; if((ret = mp_init(&one)) != MP_OKAY) return ret; mp_set(&one, 1); ret = mp_add(a, &one, b); mp_clear(&one); return ret; }
/* Subtracts two field elements. Assumes that 0 <= a, b < meth->irr */ mp_err ec_GFp_sub(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth) { mp_err res = MP_OKAY; /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a - b (mod p) */ res = mp_sub(a, b, r); if (res == MP_RANGE) { MP_CHECKOK(mp_sub(b, a, r)); if (mp_cmp_z(r) < 0) { MP_CHECKOK(mp_add(r, &meth->irr, r)); } MP_CHECKOK(ec_GFp_neg(r, r, meth)); } if (mp_cmp_z(r) < 0) { MP_CHECKOK(mp_add(r, &meth->irr, r)); } CLEANUP: return res; }
/* Converts a possibly-signed digit string into a large binary number. Returns assumed radix, derived from suffix 'h','o',b','.' */ int str2reg(unitptr reg, string digitstr) { unit temp[MAX_UNIT_PRECISION], base[MAX_UNIT_PRECISION]; int c, i; boolean minus = FALSE; short radix; /* base 2-16 */ mp_init(reg, 0); i = string_length(digitstr); if (i == 0) return (10); /* empty string, assume radix 10 */ c = digitstr[i - 1]; /* get last char in string */ switch (c) { /* classify radix select suffix character */ case '.': radix = 10; break; case 'H': case 'h': radix = 16; break; case 'O': case 'o': radix = 8; break; case 'B': /* caution! 'b' is a hex digit! */ case 'b': radix = 2; break; default: radix = 10; break; } mp_init(base, radix); if ((minus = (*digitstr == '-')) != 0) digitstr++; while ((c = *digitstr++) != 0) { if (c == ',') continue; /* allow commas in number */ c = ctox(c); if ((c < 0) || (c >= radix)) break; /* scan terminated by any non-digit */ mp_mult(temp, reg, base); mp_move(reg, temp); mp_init(temp, c); mp_add(reg, temp); } if (minus) mp_neg(reg); return (radix); } /* str2reg */
/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the * random number generator. * * Parameters * - order: a buffer that holds the curve's group order * - len: the length in octets of the order buffer * - random: a buffer of 2 * len random bytes * - randomlen: the length in octets of the random buffer * * Return Value * Returns a buffer of len octets that holds the private key. The caller * is responsible for freeing the buffer with PORT_ZFree. */ static unsigned char * ec_GenerateRandomPrivateKey(const unsigned char *order, int len, const unsigned char *random, int randomlen, int kmflag) { SECStatus rv = SECSuccess; mp_err err; unsigned char *privKeyBytes = NULL; mp_int privKeyVal, order_1, one; MP_DIGITS(&privKeyVal) = 0; MP_DIGITS(&order_1) = 0; MP_DIGITS(&one) = 0; CHECK_MPI_OK( mp_init(&privKeyVal, kmflag) ); CHECK_MPI_OK( mp_init(&order_1, kmflag) ); CHECK_MPI_OK( mp_init(&one, kmflag) ); /* * Reduces the 2*len buffer of random bytes modulo the group order. */ if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup; if (randomlen != 2 * len) { randomlen = 2 * len; } /* No need to generate - random bytes are now supplied */ /* CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) );*/ memcpy(privKeyBytes, random, randomlen); CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) ); CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) ); CHECK_MPI_OK( mp_set_int(&one, 1) ); CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); memset(privKeyBytes+len, 0, len); cleanup: mp_clear(&privKeyVal); mp_clear(&order_1); mp_clear(&one); if (err < MP_OKAY) { MP_TO_SEC_ERROR(err); rv = SECFailure; } if (rv != SECSuccess && privKeyBytes) { #ifdef _KERNEL kmem_free(privKeyBytes, 2*len); #else free(privKeyBytes); #endif privKeyBytes = NULL; } return privKeyBytes; }
int main() { unsigned int a, b, r; a = __VERIFIER_nondet_uint(); b = 234770789; r = mp_add(a, b); __VERIFIER_assert(r == a + b); return 0; }
Object* UnMarshaller::get_positive_varint() { bool done; unsigned long val = get_varint(&done); bool is_fixnum = done; mp_int mp_val; // do we need to switch to bignum math? if(!done) { int shift = sizeof(long) * 7; mp_int a; mp_init_set_int(&mp_val, val); mp_init(&a); #if (__WORDSIZE == 64) // mp_(init_)set_int can only deal with 32 bit values, // so the above call only copied the lower 32 bits of _val_. // Handle the upper 32 bits as well: mp_set_int(&a, val >> 32); mp_mul_2d(&a, 32, &a); mp_add(&a, &mp_val, &mp_val); #endif while(!done) { unsigned int byte = stream.get(); mp_set_int(&a, byte & ~128); mp_mul_2d(&a, shift, &a); mp_add(&a, &mp_val, &mp_val); shift += 7; done = byte < 128; } mp_clear(&a); }
int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y) { void *prime, *a, *b, *t1, *t2; int err; if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) { return err; } /* load prime, a and b */ if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) goto cleanup; if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) goto cleanup; if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) goto cleanup; /* compute y^2 */ if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup; /* compute x^3 */ if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup; if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup; if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup; /* compute y^2 - x^3 */ if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup; /* compute y^2 - x^3 - a*x */ if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup; if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup; if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup; /* adjust range (0, prime) */ while (mp_cmp_d(t1, 0) == LTC_MP_LT) { if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup; } while (mp_cmp(t1, prime) != LTC_MP_LT) { if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup; } /* compare to b */ if (mp_cmp(t1, b) != LTC_MP_EQ) { err = CRYPT_INVALID_PACKET; } else { err = CRYPT_OK; } cleanup: mp_clear_multi(prime, b, t1, t2, NULL); return err; }
/* Add two field elements. Assumes that 0 <= a, b < meth->irr */ mp_err ec_GFp_add(const mp_int *a, const mp_int *b, mp_int *r, const GFMethod *meth) { /* PRE: 0 <= a, b < p = meth->irr POST: 0 <= r < p, r = a + b (mod p) */ mp_err res; if ((res = mp_add(a, b, r)) != MP_OKAY) { return res; } if (mp_cmp(r, &meth->irr) >= 0) { return mp_sub(r, &meth->irr, r); } return res; }
/* Generate a random private key using the algorithm A.4.1 of ANSI X9.62, * modified a la FIPS 186-2 Change Notice 1 to eliminate the bias in the * random number generator. * * Parameters * - order: a buffer that holds the curve's group order * - len: the length in octets of the order buffer * * Return Value * Returns a buffer of len octets that holds the private key. The caller * is responsible for freeing the buffer with PORT_ZFree. */ static unsigned char * ec_GenerateRandomPrivateKey(const unsigned char *order, int len, int kmflag) { SECStatus rv = SECSuccess; mp_err err; unsigned char *privKeyBytes = NULL; mp_int privKeyVal, order_1, one; MP_DIGITS(&privKeyVal) = 0; MP_DIGITS(&order_1) = 0; MP_DIGITS(&one) = 0; CHECK_MPI_OK( mp_init(&privKeyVal) ); CHECK_MPI_OK( mp_init(&order_1) ); CHECK_MPI_OK( mp_init(&one) ); /* Generates 2*len random bytes using the global random bit generator * (which implements Algorithm 1 of FIPS 186-2 Change Notice 1) then * reduces modulo the group order. */ if ((privKeyBytes = PORT_Alloc(2*len, kmflag)) == NULL) goto cleanup; CHECK_SEC_OK( RNG_GenerateGlobalRandomBytes(privKeyBytes, 2*len) ); CHECK_MPI_OK( mp_read_unsigned_octets(&privKeyVal, privKeyBytes, 2*len) ); CHECK_MPI_OK( mp_read_unsigned_octets(&order_1, order, len) ); CHECK_MPI_OK( mp_set_int(&one, 1) ); CHECK_MPI_OK( mp_sub(&order_1, &one, &order_1) ); CHECK_MPI_OK( mp_mod(&privKeyVal, &order_1, &privKeyVal) ); CHECK_MPI_OK( mp_add(&privKeyVal, &one, &privKeyVal) ); CHECK_MPI_OK( mp_to_fixlen_octets(&privKeyVal, privKeyBytes, len) ); memset(privKeyBytes+len, 0, len); cleanup: mp_clear(&privKeyVal); mp_clear(&order_1); mp_clear(&one); if (err < MP_OKAY) { MP_TO_SEC_ERROR(err); rv = SECFailure; } if (rv != SECSuccess && privKeyBytes) { #ifdef _KERNEL kmem_free(privKeyBytes, 2*len); #else free(privKeyBytes); #endif privKeyBytes = NULL; } return privKeyBytes; }
/* d = a + b (mod c) */ int mp_addmod(mp_int * a, mp_int * b, mp_int * c, mp_int * d) { int res; mp_int t; if ((res = mp_init(&t)) != MP_OKAY) { return res; } if ((res = mp_add(a, b, &t)) != MP_OKAY) { mp_clear(&t); return res; } res = mp_mod(&t, c, d); mp_clear(&t); return res; }
static void mpi_addsub(mpi *rop, mpi *op1, mpi *op2, int sub) { long xlen; /* maximum result size */ if (sub ^ (op1->sign == op2->sign)) { /* plus one for possible carry */ xlen = MAX(op1->size, op2->size) + 1; if (rop->alloc < xlen) { rop->digs = mp_realloc(rop->digs, sizeof(BNS) * xlen); rop->alloc = xlen; } rop->size = mp_add(rop->digs, op1->digs, op2->digs, op1->size, op2->size); rop->sign = op1->sign; } else { long cmp; /* check for larger operator */ cmp = mpi_cmpabs(op1, op2); if (cmp == 0) { rop->digs[0] = 0; rop->size = 1; rop->sign = 0; } else { xlen = MAX(op1->size, op2->size); if (rop->alloc < xlen) { rop->digs = mp_realloc(rop->digs, sizeof(BNS) * xlen); rop->alloc = xlen; } if (cmp > 0) { rop->size = mp_sub(rop->digs, op1->digs, op2->digs, op1->size, op2->size); rop->sign = op1->sign; } else { rop->size = mp_sub(rop->digs, op2->digs, op1->digs, op2->size, op1->size); rop->sign = sub ^ op2->sign; } } } }
/*-------------------------------------------------------------------*/ static void convert_to_integer(gmp_poly_t *alg_sqrt, mp_t *n, mp_t *c, signed_mp_t *m1, signed_mp_t *m0, mp_t *res) { /* given the completed square root, apply the homomorphism to convert the polynomial to an integer. We do this by evaluating alg_sqrt at c*m0/m1, with all calculations performed mod n */ uint32 i; mpz_t gmp_n; mp_t m1_pow; mp_t m1_tmp; mp_t m0_tmp; mp_t next_coeff; mpz_init(gmp_n); mp2gmp(n, gmp_n); gmp_poly_mod_q(alg_sqrt, gmp_n, alg_sqrt); mpz_clear(gmp_n); mp_copy(&m1->num, &m1_tmp); if (m1->sign == NEGATIVE) mp_sub(n, &m1_tmp, &m1_tmp); mp_copy(&m1_tmp, &m1_pow); mp_modmul(&m0->num, c, n, &m0_tmp); if (m0->sign == POSITIVE) mp_sub(n, &m0_tmp, &m0_tmp); i = alg_sqrt->degree; gmp2mp(alg_sqrt->coeff[i], res); for (i--; (int32)i >= 0; i--) { mp_modmul(res, &m0_tmp, n, res); gmp2mp(alg_sqrt->coeff[i], &next_coeff); mp_modmul(&next_coeff, &m1_pow, n, &next_coeff); mp_add(res, &next_coeff, res); if (i > 0) mp_modmul(&m1_pow, &m1_tmp, n, &m1_pow); } if (mp_cmp(res, n) > 0) mp_sub(res, n, res); }
unsigned char *cli_decodesig(const char *sig, unsigned int plen, mp_int e, mp_int n) { int i, slen = strlen(sig), dec; unsigned char *plain; mp_int r, p, c; mp_init(&r); mp_init(&c); for(i = 0; i < slen; i++) { if((dec = cli_ndecode(sig[i])) < 0) { mp_clear(&r); mp_clear(&c); return NULL; } mp_set_int(&r, dec); mp_mul_2d(&r, 6 * i, &r); mp_add(&r, &c, &c); } plain = (unsigned char *) cli_calloc(plen + 1, sizeof(unsigned char)); if(!plain) { cli_errmsg("cli_decodesig: Can't allocate memory for 'plain'\n"); mp_clear(&r); mp_clear(&c); return NULL; } mp_init(&p); mp_exptmod(&c, &e, &n, &p); /* plain = cipher^e mod n */ mp_clear(&c); mp_set_int(&c, 256); for(i = plen - 1; i >= 0; i--) { /* reverse */ mp_div(&p, &c, &p, &r); plain[i] = mp_get_int(&r); } mp_clear(&c); mp_clear(&p); mp_clear(&r); return plain; }
/** * Generate a numberOfBits-bit long random integer. Note: The most-significant * bit will not be random: it will always be 1. The number of random bits * therefore is numberOfBits - 1. * * @return random number */ mp_int *fhe_new_random_integer(unsigned long long int numberOfBits) { #if defined(__linux__) int c; unsigned int bitmask; unsigned long int i; INIT_MP_INT(randomInteger); INIT_MP_INT(tmp1); /* The whole bytes */ for (bitmask = 0xff, i = numberOfBits; i > 0;) { if ((c = fgetc(randomFile)) == EOF) { perror("Error reading " RANDOM_FILE); exit(EXIT_FAILURE); } /* Ensure the most-significant bit of the random integer is always 1 */ if (i == numberOfBits) { assert(i > 0); c |= 0x1 << ((i < 8 ? i : 8) - 1); } if (i < 8) { // The last few bits will have a bitmask bitmask = 0xff >> (8 - i); } for (unsigned long int j = 0; j < i; j++) { mp_mul_2(randomInteger, randomInteger); } mp_set_int(tmp1, c & bitmask); mp_add(randomInteger, tmp1, randomInteger); /* Decrement; check for underflow */ if (i < 8) { break; } else { i -= 8; } }
void bn_double2int (double a, mp_int *b) { const unsigned int FRAC_BITS = 52; int ret, exp; long int val; double frac; mp_int upper, number; assert (a >= 0); ret = mp_init_multi (b, &number, &upper, NULL); if (ret != MP_OKAY) Fatal (1, error, "Error initializing number"); mp_set (&upper, 1); frac = frexp (a, &exp); ret = mp_mul_2d (&upper, exp, &upper); if (ret != MP_OKAY) Fatal (1, error, "Error initializing number"); for (unsigned int i = 0; i < FRAC_BITS; i++) { frac = frac * 2; val = lround (floor (frac)); assert (val == 0 || val == 1); frac = frac - lround (floor (frac)); if (val == 1) { mp_div_2d (&upper, i + 1, &number, NULL); if (ret != MP_OKAY) Fatal (1, error, "Error dividing numbers"); mp_add (b, &number, b); if (ret != MP_OKAY) Fatal (1, error, "Error adding numbers"); } } mp_clear_multi (&number, &upper, NULL); }
/* 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(const mp_int *a, mp_int *b) { mp_int x0, x1, t1, t2, x0x0, x1x1; int B, err; err = MP_MEM; /* min # of digits */ B = a->used; /* now divide in two */ B = B >> 1; /* init copy all the temps */ if (mp_init_size(&x0, B) != MP_OKAY) goto LBL_ERR; if (mp_init_size(&x1, a->used - B) != MP_OKAY) goto X0; /* init temps */ if (mp_init_size(&t1, a->used * 2) != MP_OKAY) goto X1; if (mp_init_size(&t2, a->used * 2) != MP_OKAY) goto T1; if (mp_init_size(&x0x0, B * 2) != MP_OKAY) goto T2; if (mp_init_size(&x1x1, (a->used - B) * 2) != MP_OKAY) goto X0X0; { int x; mp_digit *dst, *src; src = a->dp; /* now shift the digits */ dst = x0.dp; for (x = 0; x < B; x++) { *dst++ = *src++; } dst = x1.dp; for (x = B; x < a->used; x++) { *dst++ = *src++; } } x0.used = B; x1.used = a->used - 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); LBL_ERR: return err; }
/** Sign a hash with DSA @param in The hash to sign @param inlen The length of the hash to sign @param r The "r" integer of the signature (caller must initialize with mp_init() first) @param s The "s" integer of the signature (caller must initialize with mp_init() first) @param prng An active PRNG state @param wprng The index of the PRNG desired @param key A private DSA key @return CRYPT_OK if successful */ int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, void *r, void *s, prng_state *prng, int wprng, dsa_key *key) { void *k, *kinv, *tmp; unsigned char *buf; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); LTC_ARGCHK(key != NULL); if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* check group order size */ if (key->qord >= MDSA_MAX_GROUP) { return CRYPT_INVALID_ARG; } buf = XMALLOC(MDSA_MAX_GROUP); if (buf == NULL) { return CRYPT_MEM; } /* Init our temps */ if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } retry: do { /* gen random k */ if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { err = CRYPT_ERROR_READPRNG; goto error; } /* read k */ if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; } /* k > 1 ? */ if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; } /* test gcd */ if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; } } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); /* now find 1/k mod q */ if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; } /* now find r = g^k mod p mod q */ if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; } if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; } if (mp_iszero(r) == LTC_MP_YES) { goto retry; } /* now find s = (in + xr)/k mod q */ if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; } if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; } if (mp_iszero(s) == LTC_MP_YES) { goto retry; } err = CRYPT_OK; error: mp_clear_multi(k, kinv, tmp, NULL); ERRBUF: #ifdef LTC_CLEAN_STACK zeromem(buf, MDSA_MAX_GROUP); #endif XFREE(buf); return err; }
/* slower bit-bang division... also smaller */ int mp_div MPA(mp_int * a, mp_int * b, mp_int * c, mp_int * d) { mp_int ta, tb, tq, q; int res, n, n2; /* is divisor zero ? */ if (mp_iszero (b) == 1) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag (a, b) == MP_LT) { if (d != NULL) { res = mp_copy (a, d); } else { res = MP_OKAY; } if (c != NULL) { mp_zero (c); } return res; } /* init our temps */ if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) { return res; } mp_set(&tq, 1); n = mp_count_bits(a) - mp_count_bits(b); if (((res = mp_abs(a, &ta)) != MP_OKAY) || ((res = mp_abs(b, &tb)) != MP_OKAY) || ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { goto LBL_ERR; } while (n-- >= 0) { if (mp_cmp(&tb, &ta) != MP_GT) { if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { goto LBL_ERR; } } if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { goto LBL_ERR; } } /* now q == quotient and ta == remainder */ n = a->sign; n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG); if (c != NULL) { mp_exch(c, &q); c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; } if (d != NULL) { mp_exch(d, &ta); d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; } LBL_ERR: mp_clear_multi(&ta, &tb, &tq, &q, NULL); return res; }
/* integer signed division. * c*b + d == a [e.g. a/b, c=quotient, d=remainder] * HAC pp.598 Algorithm 14.20 * * Note that the description in HAC is horribly * incomplete. For example, it doesn't consider * the case where digits are removed from 'x' in * the inner loop. It also doesn't consider the * case that y has fewer than three digits, etc.. * * The overall algorithm is as described as * 14.20 from HAC but fixed to treat these cases. */ int mp_div MPA(mp_int * a, mp_int * b, mp_int * c, mp_int * d) { mp_int q, x, y, t1, t2; int res, n, t, i, norm, neg; /* is divisor zero ? */ if (mp_iszero (b) == 1) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag (a, b) == MP_LT) { if (d != NULL) { res = mp_copy (MPST, a, d); } else { res = MP_OKAY; } if (c != NULL) { mp_zero (c); } return res; } if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) { return res; } q.used = a->used + 2; if ((res = mp_init (&t1)) != MP_OKAY) { goto LBL_Q; } if ((res = mp_init (&t2)) != MP_OKAY) { goto LBL_T1; } if ((res = mp_init_copy (MPST, &x, a)) != MP_OKAY) { goto LBL_T2; } if ((res = mp_init_copy (MPST, &y, b)) != MP_OKAY) { goto LBL_X; } /* fix the sign */ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; x.sign = y.sign = MP_ZPOS; /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ norm = mp_count_bits(&y) % DIGIT_BIT; if (norm < (int)(DIGIT_BIT-1)) { norm = (DIGIT_BIT-1) - norm; if ((res = mp_mul_2d (MPST, &x, norm, &x)) != MP_OKAY) { goto LBL_Y; } if ((res = mp_mul_2d (MPST, &y, norm, &y)) != MP_OKAY) { goto LBL_Y; } } else { norm = 0; } /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ n = x.used - 1; t = y.used - 1; /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ if ((res = mp_lshd (MPST, &y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ goto LBL_Y; } while (mp_cmp (&x, &y) != MP_LT) { ++(q.dp[n - t]); if ((res = mp_sub (MPST, &x, &y, &x)) != MP_OKAY) { goto LBL_Y; } } /* reset y by shifting it back down */ mp_rshd (&y, n - t); /* step 3. for i from n down to (t + 1) */ for (i = n; i >= (t + 1); i--) { if (i > x.used) { continue; } /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ if (x.dp[i] == y.dp[t]) { q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1); } else { mp_word tmp; tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); tmp |= ((mp_word) x.dp[i - 1]); tmp /= ((mp_word) y.dp[t]); if (tmp > (mp_word) MP_MASK) tmp = MP_MASK; q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); } /* while (q{i-t-1} * (yt * b + y{t-1})) > xi * b**2 + xi-1 * b + xi-2 do q{i-t-1} -= 1; */ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK; do { q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK; /* find left hand */ mp_zero (&t1); t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; t1.dp[1] = y.dp[t]; t1.used = 2; if ((res = mp_mul_d (MPST, &t1, q.dp[i - t - 1], &t1)) != MP_OKAY) { goto LBL_Y; } /* find right hand */ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; t2.dp[2] = x.dp[i]; t2.used = 3; } while (mp_cmp_mag(&t1, &t2) == MP_GT); /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ if ((res = mp_mul_d (MPST, &y, q.dp[i - t - 1], &t1)) != MP_OKAY) { goto LBL_Y; } if ((res = mp_lshd (MPST, &t1, i - t - 1)) != MP_OKAY) { goto LBL_Y; } if ((res = mp_sub (MPST, &x, &t1, &x)) != MP_OKAY) { goto LBL_Y; } /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ if (x.sign == MP_NEG) { if ((res = mp_copy (MPST, &y, &t1)) != MP_OKAY) { goto LBL_Y; } if ((res = mp_lshd (MPST, &t1, i - t - 1)) != MP_OKAY) { goto LBL_Y; } if ((res = mp_add (MPST, &x, &t1, &x)) != MP_OKAY) { goto LBL_Y; } q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK; } } /* now q is the quotient and x is the remainder * [which we have to normalize] */ /* get sign before writing to c */ x.sign = x.used == 0 ? MP_ZPOS : a->sign; if (c != NULL) { mp_clamp (&q); mp_managed_copy (MPST, &q, c); c->sign = neg; } if (d != NULL) { mp_div_2d (MPST, &x, norm, &x, NULL); mp_managed_copy (MPST, &x, d); } res = MP_OKAY; LBL_Y:mp_clear (&y); LBL_X:mp_clear (&x); LBL_T2:mp_clear (&t2); LBL_T1:mp_clear (&t1); LBL_Q:mp_clear (&q); return res; }