int igraph_biguint_mul(igraph_biguint_t *res, igraph_biguint_t *left, igraph_biguint_t *right) { long int size_left=igraph_biguint_size(left); long int size_right=igraph_biguint_size(right); if (size_left > size_right) { IGRAPH_CHECK(igraph_biguint_resize(right, size_left)); size_right=size_left; } else if (size_left < size_right) { IGRAPH_CHECK(igraph_biguint_resize(left, size_right)); size_left=size_right; } IGRAPH_CHECK(igraph_biguint_resize(res, 2*size_left)); bn_mul( VECTOR(res->v), VECTOR(left->v), VECTOR(right->v), size_left ); return 0; }
// int appears on rhs status_t element_div_int(element_t c, element_t a, integer_t b) { GroupType type = a->type; EXIT_IF_NOT_SAME(c, a); LEAVE_IF( c->isInitialized != TRUE || a->isInitialized != TRUE, "uninitialized arguments."); LEAVE_IF( c->type != type, "result initialized but invalid type."); if(type == ZR) { if(bn_is_zero(b)) return ELEMENT_DIV_ZERO; // if(bn_is_one(a->bn)) { // element_set_int(a, b); // return element_invert(c, a); // not going to work // } integer_t s; bn_inits(s); // compute c = (1 / b) mod order bn_gcd_ext(s, c->bn, NULL, b, a->order); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); if(bn_is_one(a->bn) && bn_sign(a->bn) == BN_POS) { bn_free(s); return ELEMENT_OK; } // remainder of ((a * c) / order) // c = (a * c) / order (remainder only) bn_mul(s, a->bn, c->bn); bn_div_rem(s, c->bn, s, a->order); // if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); bn_free(s); // bn_div(c->bn, a->bn, b); // bn_mod(c->bn, c->bn, c->order); } else if(type == G1 || type == G2 || type == GT) { if(bn_is_one(b)) { return element_set(c, a); } // TODO: other cases: b > 1 (ZR)? } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
int cp_bdpe_enc(uint8_t *out, int *out_len, dig_t in, bdpe_t pub) { bn_t m, u; int size, result = STS_OK; bn_null(m); bn_null(u); size = bn_size_bin(pub->n); if (in > pub->t) { return STS_ERR; } TRY { bn_new(m); bn_new(u); bn_set_dig(m, in); bn_rand_mod(u, pub->n); bn_mxp(m, pub->y, m, pub->n); bn_mxp_dig(u, u, pub->t, pub->n); bn_mul(m, m, u); bn_mod(m, m, pub->n); if (size <= *out_len) { *out_len = size; memset(out, 0, *out_len); bn_write_bin(out, size, m); } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(u); } return result; }
void ep2_curve_get_vs(bn_t *v) { bn_t x, t; bn_null(x); bn_null(t); TRY { bn_new(x); bn_new(t); fp_param_get_var(x); bn_mul_dig(v[0], x, 3); bn_add_dig(v[0], v[0], 1); bn_copy(v[1], x); bn_copy(v[2], x); bn_copy(v[3], x); bn_sqr(x, x); bn_lsh(t, x, 1); bn_add(v[0], v[0], t); bn_add(v[3], v[3], t); bn_lsh(t, t, 1); bn_add(v[2], v[2], t); bn_lsh(t, t, 1); bn_add(v[1], v[1], t); fp_param_get_var(t); bn_mul(x, x, t); bn_mul_dig(t, x, 6); bn_add(v[2], v[2], t); bn_lsh(t, t, 1); bn_add(v[1], v[1], t); bn_neg(v[3], v[3]); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(x); bn_free(t); } }
int cp_psb_sig(g1_t a, g1_t b, uint8_t *msgs[], int lens[], bn_t r, bn_t s[], int l) { bn_t m, n, t; int i, result = RLC_OK; bn_null(m); bn_null(n); bn_null(t); TRY { bn_new(m); bn_new(n); bn_new(t); /* Choose random a in G1. */ g1_rand(a); /* Compute b = a^x+\sum y_im_i. */ g1_get_ord(n); bn_copy(t, r); for (i = 0; i < l; i++) { bn_read_bin(m, msgs[i], lens[i]); bn_mod(m, m, n); bn_mul(m, m, s[i]); bn_mod(m, m, n); bn_add(t, t, m); bn_mod(t, t, n); } g1_mul(b, a, t); } CATCH_ANY { result = RLC_ERR; } FINALLY { bn_free(m); bn_free(n); bn_free(t); } return result; }
void bn_mxp_slide(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_t tab[TABLE_SIZE], t, u, r; int i, j, l, w = 1; uint8_t win[BN_BITS]; bn_null(t); bn_null(u); bn_null(r); /* Initialize table. */ for (i = 0; i < TABLE_SIZE; i++) { bn_null(tab[i]); } TRY { /* Find window size. */ i = bn_bits(b); if (i <= 21) { w = 2; } else if (i <= 32) { w = 3; } else if (i <= 128) { w = 4; } else if (i <= 256) { w = 5; } else { w = 6; } for (i = 1; i < (1 << w); i += 2) { bn_new(tab[i]); } bn_new(t); bn_new(u); bn_new(r); bn_mod_pre(u, m); #if BN_MOD == MONTY bn_set_dig(r, 1); bn_mod_monty_conv(r, r, m); bn_mod_monty_conv(t, a, m); #else /* BN_MOD == BARRT || BN_MOD == RADIX */ bn_set_dig(r, 1); bn_copy(t, a); #endif bn_copy(tab[1], t); bn_sqr(t, tab[1]); bn_mod(t, t, m, u); /* Create table. */ for (i = 1; i < 1 << (w - 1); i++) { bn_mul(tab[2 * i + 1], tab[2 * i - 1], t); bn_mod(tab[2 * i + 1], tab[2 * i + 1], m, u); } l = BN_BITS + 1; bn_rec_slw(win, &l, b, w); for (i = 0; i < l; i++) { if (win[i] == 0) { bn_sqr(r, r); bn_mod(r, r, m, u); } else { for (j = 0; j < util_bits_dig(win[i]); j++) { bn_sqr(r, r); bn_mod(r, r, m, u); } bn_mul(r, r, tab[win[i]]); bn_mod(r, r, m, u); } } bn_trim(r); #if BN_MOD == MONTY bn_mod_monty_back(c, r, m); #else bn_copy(c, r); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 1; i < (1 << w); i++) { bn_free(tab[i]); } bn_free(u); bn_free(t); bn_free(r); } }
int cp_rsa_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t pub) { bn_t m, eb; int size, pad_len, result = STS_OK; bn_null(m); bn_null(eb); size = bn_size_bin(pub->n); if (pub == NULL || in_len <= 0 || in_len > (size - RSA_PAD_LEN)) { return STS_ERR; } TRY { bn_new(m); bn_new(eb); bn_zero(m); bn_zero(eb); #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC) == STS_OK) { #endif bn_read_bin(m, in, in_len); bn_add(eb, eb, m); #if CP_RSAPD == PKCS2 pad_pkcs2(eb, &pad_len, in_len, size, RSA_ENC_FIN); #endif bn_mxp(eb, eb, pub->e, pub->n); if (size <= *out_len) { *out_len = size; memset(out, 0, *out_len); bn_write_bin(out, size, eb); } else { result = STS_ERR; } } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(eb); } return result; } #if CP_RSA == BASIC || !defined(STRIP) int cp_rsa_dec_basic(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) { bn_t m, eb; int size, pad_len, result = STS_OK; size = bn_size_bin(prv->n); if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) { return STS_ERR; } bn_null(m); bn_null(eb); TRY { bn_new(m); bn_new(eb); bn_read_bin(eb, in, in_len); bn_mxp(eb, eb, prv->d, prv->n); if (bn_cmp(eb, prv->n) != CMP_LT) { result = STS_ERR; } #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #endif size = size - pad_len; if (size <= *out_len) { memset(out, 0, size); bn_write_bin(out, size, eb); *out_len = size; } else { result = STS_ERR; } } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(eb); } return result; } #endif #if CP_RSA == QUICK || !defined(STRIP) int cp_rsa_dec_quick(uint8_t *out, int *out_len, uint8_t *in, int in_len, rsa_t prv) { bn_t m, eb; int size, pad_len, result = STS_OK; bn_null(m); bn_null(eb); size = bn_size_bin(prv->n); if (prv == NULL || in_len != size || in_len < RSA_PAD_LEN) { return STS_ERR; } TRY { bn_new(m); bn_new(eb); bn_read_bin(eb, in, in_len); bn_copy(m, eb); /* m1 = c^dP mod p. */ bn_mxp(eb, eb, prv->dp, prv->p); /* m2 = c^dQ mod q. */ bn_mxp(m, m, prv->dq, prv->q); /* m1 = m1 - m2 mod p. */ bn_sub(eb, eb, m); while (bn_sign(eb) == BN_NEG) { bn_add(eb, eb, prv->p); } bn_mod(eb, eb, prv->p); /* m1 = qInv(m1 - m2) mod p. */ bn_mul(eb, eb, prv->qi); bn_mod(eb, eb, prv->p); /* m = m2 + m1 * q. */ bn_mul(eb, eb, prv->q); bn_add(eb, eb, m); if (bn_cmp(eb, prv->n) != CMP_LT) { result = STS_ERR; } #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, in_len, size, RSA_DEC) == STS_OK) { #endif size = size - pad_len; if (size <= *out_len) { memset(out, 0, size); bn_write_bin(out, size, eb); *out_len = size; } else { result = STS_ERR; } } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(eb); } return result; } #endif #if CP_RSA == BASIC || !defined(STRIP) int cp_rsa_sig_basic(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) { bn_t m, eb; int size, pad_len, result = STS_OK; uint8_t h[MD_LEN]; if (prv == NULL || msg_len < 0) { return STS_ERR; } pad_len = (!hash ? MD_LEN : msg_len); #if CP_RSAPD == PKCS2 size = bn_bits(prv->n) - 1; size = (size / 8) + (size % 8 > 0); if (pad_len > (size - 2)) { return STS_ERR; } #else size = bn_size_bin(prv->n); if (pad_len > (size - RSA_PAD_LEN)) { return STS_ERR; } #endif bn_null(m); bn_null(eb); TRY { bn_new(m); bn_new(eb); bn_zero(m); bn_zero(eb); int operation = (!hash ? RSA_SIG : RSA_SIG_HASH); #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) { #endif if (!hash) { md_map(h, msg, msg_len); bn_read_bin(m, h, MD_LEN); bn_add(eb, eb, m); } else { bn_read_bin(m, msg, msg_len); bn_add(eb, eb, m); } #if CP_RSAPD == PKCS2 pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN); #endif bn_mxp(eb, eb, prv->d, prv->n); size = bn_size_bin(prv->n); if (size <= *sig_len) { memset(sig, 0, size); bn_write_bin(sig, size, eb); *sig_len = size; } else { result = STS_ERR; } } else { result = STS_ERR; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(m); bn_free(eb); } return result; } #endif #if CP_RSA == QUICK || !defined(STRIP) int cp_rsa_sig_quick(uint8_t *sig, int *sig_len, uint8_t *msg, int msg_len, int hash, rsa_t prv) { bn_t m, eb; int pad_len, size, result = STS_OK; uint8_t h[MD_LEN]; if (prv == NULL || msg_len < 0) { return STS_ERR; } pad_len = (!hash ? MD_LEN : msg_len); #if CP_RSAPD == PKCS2 size = bn_bits(prv->n) - 1; size = (size / 8) + (size % 8 > 0); if (pad_len > (size - 2)) { return STS_ERR; } #else size = bn_size_bin(prv->n); if (pad_len > (size - RSA_PAD_LEN)) { return STS_ERR; } #endif bn_null(m); bn_null(eb); TRY { bn_new(m); bn_new(eb); bn_zero(m); bn_zero(eb); int operation = (!hash ? RSA_SIG : RSA_SIG_HASH); #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, pad_len, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, pad_len, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, pad_len, size, operation) == STS_OK) { #endif if (!hash) { md_map(h, msg, msg_len); bn_read_bin(m, h, MD_LEN); bn_add(eb, eb, m); } else { bn_read_bin(m, msg, msg_len); bn_add(eb, eb, m); } #if CP_RSAPD == PKCS2 pad_pkcs2(eb, &pad_len, bn_bits(prv->n), size, RSA_SIG_FIN); #endif bn_copy(m, eb); /* m1 = c^dP mod p. */ bn_mxp(eb, eb, prv->dp, prv->p); /* m2 = c^dQ mod q. */ bn_mxp(m, m, prv->dq, prv->q); /* m1 = m1 - m2 mod p. */ bn_sub(eb, eb, m); while (bn_sign(eb) == BN_NEG) { bn_add(eb, eb, prv->p); } bn_mod(eb, eb, prv->p); /* m1 = qInv(m1 - m2) mod p. */ bn_mul(eb, eb, prv->qi); bn_mod(eb, eb, prv->p); /* m = m2 + m1 * q. */ bn_mul(eb, eb, prv->q); bn_add(eb, eb, m); bn_mod(eb, eb, prv->n); size = bn_size_bin(prv->n); if (size <= *sig_len) { memset(sig, 0, size); bn_write_bin(sig, size, eb); *sig_len = size; } else { result = STS_ERR; } } else { result = STS_ERR; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(m); bn_free(eb); } return result; } #endif int cp_rsa_ver(uint8_t *sig, int sig_len, uint8_t *msg, int msg_len, int hash, rsa_t pub) { bn_t m, eb; int size, pad_len, result; uint8_t h1[MAX(msg_len, MD_LEN) + 8], h2[MAX(msg_len, MD_LEN)]; /* We suppose that the signature is invalid. */ result = 0; if (pub == NULL || msg_len < 0) { return 0; } pad_len = (!hash ? MD_LEN : msg_len); #if CP_RSAPD == PKCS2 size = bn_bits(pub->n) - 1; if (size % 8 == 0) { size = size / 8 - 1; } else { size = bn_size_bin(pub->n); } if (pad_len > (size - 2)) { return 0; } #else size = bn_size_bin(pub->n); if (pad_len > (size - RSA_PAD_LEN)) { return 0; } #endif bn_null(m); bn_null(eb); TRY { bn_new(m); bn_new(eb); bn_read_bin(eb, sig, sig_len); bn_mxp(eb, eb, pub->e, pub->n); int operation = (!hash ? RSA_VER : RSA_VER_HASH); #if CP_RSAPD == BASIC if (pad_basic(eb, &pad_len, MD_LEN, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS1 if (pad_pkcs1(eb, &pad_len, MD_LEN, size, operation) == STS_OK) { #elif CP_RSAPD == PKCS2 if (pad_pkcs2(eb, &pad_len, bn_bits(pub->n), size, operation) == STS_OK) { #endif #if CP_RSAPD == PKCS2 memset(h1, 0, 8); if (!hash) { md_map(h1 + 8, msg, msg_len); md_map(h2, h1, MD_LEN + 8); memset(h1, 0, MD_LEN); bn_write_bin(h1, size - pad_len, eb); /* Everything went ok, so signature status is changed. */ result = util_cmp_const(h1, h2, MD_LEN); } else { memcpy(h1 + 8, msg, msg_len); md_map(h2, h1, MD_LEN + 8); memset(h1, 0, msg_len); bn_write_bin(h1, size - pad_len, eb); /* Everything went ok, so signature status is changed. */ result = util_cmp_const(h1, h2, msg_len); } #else memset(h1, 0, MAX(msg_len, MD_LEN)); bn_write_bin(h1, size - pad_len, eb); if (!hash) { md_map(h2, msg, msg_len); /* Everything went ok, so signature status is changed. */ result = util_cmp_const(h1, h2, MD_LEN); } else { /* Everything went ok, so signature status is changed. */ result = util_cmp_const(h1, msg, msg_len); } #endif result = (result == CMP_EQ ? 1 : 0); } else { result = 0; } } CATCH_ANY { result = 0; } FINALLY { bn_free(m); bn_free(eb); } return result; }
int cp_rsa_gen_quick(rsa_t pub, rsa_t prv, int bits) { bn_t t, r; int result = STS_OK; if (pub == NULL || prv == NULL || bits == 0) { return STS_ERR; } bn_null(t); bn_null(r); TRY { bn_new(t); bn_new(r); /* Generate different primes p and q. */ do { bn_gen_prime(prv->p, bits / 2); bn_gen_prime(prv->q, bits / 2); } while (bn_cmp(prv->p, prv->q) == CMP_EQ); /* Swap p and q so that p is smaller. */ if (bn_cmp(prv->p, prv->q) == CMP_LT) { bn_copy(t, prv->p); bn_copy(prv->p, prv->q); bn_copy(prv->q, t); } /* n = pq. */ bn_mul(pub->n, prv->p, prv->q); bn_copy(prv->n, pub->n); bn_sub_dig(prv->p, prv->p, 1); bn_sub_dig(prv->q, prv->q, 1); /* phi(n) = (p - 1)(q - 1). */ bn_mul(t, prv->p, prv->q); bn_set_2b(pub->e, 16); bn_add_dig(pub->e, pub->e, 1); /* d = e^(-1) mod phi(n). */ bn_gcd_ext(r, prv->d, NULL, pub->e, t); if (bn_sign(prv->d) == BN_NEG) { bn_add(prv->d, prv->d, t); } if (bn_cmp_dig(r, 1) == CMP_EQ) { /* dP = d mod (p - 1). */ bn_mod(prv->dp, prv->d, prv->p); /* dQ = d mod (q - 1). */ bn_mod(prv->dq, prv->d, prv->q); bn_add_dig(prv->p, prv->p, 1); bn_add_dig(prv->q, prv->q, 1); /* qInv = q^(-1) mod p. */ bn_gcd_ext(r, prv->qi, NULL, prv->q, prv->p); if (bn_sign(prv->qi) == BN_NEG) { bn_add(prv->qi, prv->qi, prv->p); } result = STS_OK; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(t); bn_free(r); } return result; }
int cp_bdpe_gen(bdpe_t pub, bdpe_t prv, dig_t block, int bits) { bn_t t, r; int result = STS_OK; bn_null(t); bn_null(r); TRY { bn_new(t); bn_new(r); prv->t = pub->t = block; /* Make sure that block size is prime. */ bn_set_dig(t, block); if (bn_is_prime_basic(t) == 0) { THROW(ERR_NO_VALID); } /* Generate prime q such that gcd(block, (q - 1)) = 1. */ do { bn_gen_prime(prv->q, bits / 2); bn_sub_dig(prv->q, prv->q, 1); bn_gcd_dig(t, prv->q, block); bn_add_dig(prv->q, prv->q, 1); } while (bn_cmp_dig(t, 1) != CMP_EQ); /* Generate different primes p and q. */ do { /* Compute p = block * (x * block + b) + 1, 0 < b < block random. */ bn_rand(prv->p, BN_POS, bits / 2 - 2 * util_bits_dig(block)); bn_mul_dig(prv->p, prv->p, block); bn_rand(t, BN_POS, util_bits_dig(block)); bn_add_dig(prv->p, prv->p, t->dp[0]); /* We know that block divides (p-1). */ bn_gcd_dig(t, prv->p, block); bn_mul_dig(prv->p, prv->p, block); bn_add_dig(prv->p, prv->p, 1); } while (bn_cmp_dig(t, 1) != CMP_EQ || bn_is_prime(prv->p) == 0); /* Compute t = (p-1)*(q-1). */ bn_sub_dig(prv->q, prv->q, 1); bn_sub_dig(prv->p, prv->p, 1); bn_mul(t, prv->p, prv->q); bn_div_dig(t, t, block); /* Restore factors p and q and compute n = p * q. */ bn_add_dig(prv->p, prv->p, 1); bn_add_dig(prv->q, prv->q, 1); bn_mul(pub->n, prv->p, prv->q); bn_copy(prv->n, pub->n); /* Select random y such that y^{(p-1)(q-1)}/block \neq 1 mod N. */ do { bn_rand(pub->y, BN_POS, bits); bn_mxp(r, pub->y, t, pub->n); } while (bn_cmp_dig(r, 1) == CMP_EQ); bn_copy(prv->y, pub->y); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(t); bn_free(r); } return result; }
void bn_gen_prime_stron(bn_t a, int bits) { dig_t i, j; int found, k; bn_t r, s, t; bn_null(r); bn_null(s); bn_null(t); TRY { bn_new(r); bn_new(s); bn_new(t); do { do { /* Generate two large primes r and s. */ bn_rand(s, BN_POS, bits / 2 - BN_DIGIT / 2); bn_rand(t, BN_POS, bits / 2 - BN_DIGIT / 2); } while (!bn_is_prime(s) || !bn_is_prime(t)); found = 1; bn_rand(a, BN_POS, bits / 2 - bn_bits(t) - 1); i = a->dp[0]; bn_dbl(t, t); do { /* Find first prime r = 2 * i * t + 1. */ bn_mul_dig(r, t, i); bn_add_dig(r, r, 1); i++; if (bn_bits(r) > bits / 2 - 1) { found = 0; break; } } while (!bn_is_prime(r)); if (found == 0) { continue; } /* Compute t = 2 * (s^(r-2) mod r) * s - 1. */ bn_sub_dig(t, r, 2); #if BN_MOD != PMERS bn_mxp(t, s, t, r); #else bn_exp(t, s, t, r); #endif bn_mul(t, t, s); bn_dbl(t, t); bn_sub_dig(t, t, 1); k = bits - bn_bits(r); k -= bn_bits(s); bn_rand(a, BN_POS, k); j = a->dp[0]; do { /* Find first prime a = t + 2 * j * r * s. */ bn_mul(a, r, s); bn_mul_dig(a, a, j); bn_dbl(a, a); bn_add(a, a, t); j++; if (bn_bits(a) > bits) { found = 0; break; } } while (!bn_is_prime(a)); } while (found == 0 && bn_bits(a) != bits); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(r); bn_free(s); bn_free(t); } }
void cp_ecss_sig(bn_t e, bn_t s, unsigned char *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; unsigned char hash[MD_LEN]; unsigned char m[len + EC_BYTES]; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { do { bn_rand(k, BN_POS, bn_bits(n)); bn_mod(k, k, n); } while (bn_is_zero(k)); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, EC_BYTES, r); md_map(hash, m, len + EC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } }
int cp_bgn_dec(dig_t *out, gt_t in[4], bgn_t prv) { int i, result = STS_ERR; g1_t g; g2_t h; gt_t t[4]; bn_t n, r, s; bn_null(n); bn_null(r); bn_null(s); g1_null(g); g2_null(h); TRY { bn_new(n); bn_new(r); bn_new(s); g1_new(g); g2_new(h); for (i = 0; i < 4; i++) { gt_null(t[i]); gt_new(t[i]); } gt_exp(t[0], in[0], prv->x); gt_exp(t[0], t[0], prv->x); gt_mul(t[1], in[1], in[2]); gt_exp(t[1], t[1], prv->x); gt_inv(t[1], t[1]); gt_mul(t[3], in[3], t[1]); gt_mul(t[3], t[3], t[0]); gt_get_ord(n); g1_get_gen(g); g2_get_gen(h); bn_mul(r, prv->x, prv->y); bn_sqr(r, r); bn_mul(s, prv->x, prv->y); bn_mul(s, s, prv->z); bn_sub(r, r, s); bn_sub(r, r, s); bn_sqr(s, prv->z); bn_add(r, r, s); bn_mod(r, r, n); pc_map(t[1], g, h); gt_exp(t[1], t[1], r); gt_copy(t[2], t[1]); if (gt_is_unity(t[3]) == 1) { *out = 0; result = STS_OK; } else { for (i = 0; i < INT_MAX; i++) { if (gt_cmp(t[2], t[3]) == CMP_EQ) { *out = i + 1; result = STS_OK; break; } gt_mul(t[2], t[2], t[1]); } } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(r); bn_free(s); g1_free(g); g2_free(h); for (i = 0; i < 4; i++) { gt_free(t[i]); } } return result; }
int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = STS_OK; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { do { bn_rand(k, BN_POS, bn_bits(n)); bn_mod(k, k, n); } while (bn_is_zero(k)); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, r); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } return result; }
void fp_param_set(int param) { bn_t t0, t1, t2, p; int f[10] = { 0 }; bn_null(t0); bn_null(t1); bn_null(t2); bn_null(p); /* Suppress possible unused parameter warning. */ (void) f; TRY { bn_new(t0); bn_new(t1); bn_new(t2); bn_new(p); core_get()->fp_id = param; switch (param) { #if FP_PRIME == 158 case BN_158: /* x = 4000000031. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 160 case SECG_160: /* p = 2^160 - 2^31 + 1. */ f[0] = -1; f[1] = -31; f[2] = 160; fp_prime_set_pmers(f, 3); break; case SECG_160D: /* p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1.*/ f[0] = -1; f[1] = -2; f[2] = -3; f[3] = -7; f[4] = -8; f[5] = -9; f[6] = -12; f[7] = -14; f[8] = -32; f[9] = 160; fp_prime_set_pmers(f, 10); break; #elif FP_PRIME == 192 case NIST_192: /* p = 2^192 - 2^64 - 1. */ f[0] = -1; f[1] = -64; f[2] = 192; fp_prime_set_pmers(f, 3); break; case SECG_192: /* p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1.*/ f[0] = -1; f[1] = -3; f[2] = -6; f[3] = -7; f[4] = -8; f[5] = -12; f[6] = -32; f[7] = 192; fp_prime_set_pmers(f, 8); break; #elif FP_PRIME == 224 case NIST_224: /* p = 2^224 - 2^96 + 1. */ f[0] = 1; f[1] = -96; f[2] = 224; fp_prime_set_pmers(f, 3); break; case SECG_224: /* p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1.*/ f[0] = -1; f[1] = -1; f[2] = -4; f[3] = -7; f[4] = -9; f[5] = -11; f[6] = -12; f[7] = -32; f[8] = 224; fp_prime_set_pmers(f, 9); break; #elif FP_PRIME == 254 case BN_254: /* x = -4080000000000001. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 256 case NIST_256: /* p = 2^256 - 2^224 + 2^192 + 2^96 - 1. */ f[0] = -1; f[1] = 96; f[2] = 192; f[3] = -224; f[4] = 256; fp_prime_set_pmers(f, 5); break; case SECG_256: /* p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1. */ f[0] = -1; f[1] = -4; f[2] = -6; f[3] = -7; f[4] = -8; f[5] = -9; f[6] = -32; f[7] = 256; fp_prime_set_pmers(f, 8); break; case BN_256: /* x = 6000000000001F2D. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 384 case NIST_384: /* p = 2^384 - 2^128 - 2^96 + 2^32 - 1. */ f[0] = -1; f[1] = 32; f[2] = -96; f[3] = -128; f[4] = 384; fp_prime_set_pmers(f, 5); break; #elif FP_PRIME == 477 case B24_477: fp_param_get_var(t0); /* p = (u - 1)^2 * (u^8 - u^4 + 1) div 3 + u. */ bn_sub_dig(p, t0, 1); bn_sqr(p, p); bn_sqr(t1, t0); bn_sqr(t1, t1); bn_sqr(t2, t1); bn_sub(t2, t2, t1); bn_add_dig(t2, t2, 1); bn_mul(p, p, t2); bn_div_dig(p, p, 3); bn_add(p, p, t0); fp_prime_set_dense(p); break; #elif FP_PRIME == 508 case KSS_508: fp_param_get_var(t0); /* h = (49*u^2 + 245 * u + 343)/3 */ bn_mul_dig(p, t0, 245); bn_add_dig(p, p, 200); bn_add_dig(p, p, 143); bn_sqr(t1, t0); bn_mul_dig(t2, t1, 49); bn_add(p, p, t2); bn_div_dig(p, p, 3); /* n = (u^6 + 37 * u^3 + 343)/343. */ bn_mul(t1, t1, t0); bn_mul_dig(t2, t1, 37); bn_sqr(t1, t1); bn_add(t2, t2, t1); bn_add_dig(t2, t2, 200); bn_add_dig(t2, t2, 143); bn_div_dig(t2, t2, 49); bn_div_dig(t2, t2, 7); bn_mul(p, p, t2); /* t = (u^4 + 16 * u + 7)/7. */ bn_mul_dig(t1, t0, 16); bn_add_dig(t1, t1, 7); bn_sqr(t2, t0); bn_sqr(t2, t2); bn_add(t2, t2, t1); bn_div_dig(t2, t2, 7); bn_add(p, p, t2); bn_sub_dig(p, p, 1); fp_prime_set_dense(p); break; #elif FP_PRIME == 521 case NIST_521: /* p = 2^521 - 1. */ f[0] = -1; f[1] = 521; fp_prime_set_pmers(f, 2); break; #elif FP_PRIME == 638 case BN_638: fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; case B12_638: fp_param_get_var(t0); /* p = (x^2 - 2x + 1) * (x^4 - x^2 + 1)/3 + x. */ bn_sqr(t1, t0); bn_sqr(p, t1); bn_sub(p, p, t1); bn_add_dig(p, p, 1); bn_sub(t1, t1, t0); bn_sub(t1, t1, t0); bn_add_dig(t1, t1, 1); bn_mul(p, p, t1); bn_div_dig(p, p, 3); bn_add(p, p, t0); fp_prime_set_dense(p); break; #elif FP_PRIME == 1536 case SS_1536: fp_param_get_var(t0); bn_read_str(p, SS_P1536, strlen(SS_P1536), 16); bn_mul(p, p, t0); bn_dbl(p, p); bn_sub_dig(p, p, 1); fp_prime_set_dense(p); break; #else default: bn_gen_prime(p, FP_BITS); fp_prime_set_dense(p); core_get()->fp_id = 0; break; #endif } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t0); bn_free(t1); bn_free(t2); bn_free(p); } }