void ep_curve_set_endom(const fp_t b, const ep_t g, const bn_t r, const bn_t h, const fp_t beta, const bn_t l) { int bits = bn_bits(r); ctx_t *ctx = core_get(); ctx->ep_is_endom = 1; ctx->ep_is_super = 0; fp_zero(ctx->ep_a); fp_copy(ctx->ep_b, b); detect_opt(&(ctx->ep_opt_a), ctx->ep_a); detect_opt(&(ctx->ep_opt_b), ctx->ep_b); #if EP_MUL == LWNAF || EP_FIX == COMBS || EP_FIX == LWNAF || EP_SIM == INTER || !defined(STRIP) fp_copy(ctx->beta, beta); bn_gcd_ext_mid(&(ctx->ep_v1[1]), &(ctx->ep_v1[2]), &(ctx->ep_v2[1]), &(ctx->ep_v2[2]), l, r); /* l = v1[1] * v2[2] - v1[2] * v2[1], r = l / 2. */ bn_mul(&(ctx->ep_v1[0]), &(ctx->ep_v1[1]), &(ctx->ep_v2[2])); bn_mul(&(ctx->ep_v2[0]), &(ctx->ep_v1[2]), &(ctx->ep_v2[1])); bn_sub(&(ctx->ep_r), &(ctx->ep_v1[0]), &(ctx->ep_v2[0])); bn_hlv(&(ctx->ep_r), &(ctx->ep_r)); /* v1[0] = round(v2[2] * 2^|n| / l). */ bn_lsh(&(ctx->ep_v1[0]), &(ctx->ep_v2[2]), bits + 1); if (bn_sign(&(ctx->ep_v1[0])) == BN_POS) { bn_add(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r)); } else { bn_sub(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r)); } bn_dbl(&(ctx->ep_r), &(ctx->ep_r)); bn_div(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), &(ctx->ep_r)); if (bn_sign(&ctx->ep_v1[0]) == BN_NEG) { bn_add_dig(&(ctx->ep_v1[0]), &(ctx->ep_v1[0]), 1); } /* v2[0] = round(v1[2] * 2^|n| / l). */ bn_lsh(&(ctx->ep_v2[0]), &(ctx->ep_v1[2]), bits + 1); if (bn_sign(&(ctx->ep_v2[0])) == BN_POS) { bn_add(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r)); } else { bn_sub(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r)); } bn_div(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), &(ctx->ep_r)); if (bn_sign(&ctx->ep_v2[0]) == BN_NEG) { bn_add_dig(&(ctx->ep_v2[0]), &(ctx->ep_v2[0]), 1); } bn_neg(&(ctx->ep_v2[0]), &(ctx->ep_v2[0])); #endif ep_norm(&(ctx->ep_g), g); bn_copy(&(ctx->ep_r), r); bn_copy(&(ctx->ep_h), h); #if defined(EP_PRECO) ep_mul_pre((ep_t *)ep_curve_get_tab(), &(ctx->ep_g)); #endif }
void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n) { u32 i; u8 mask; bn_zero(d, n); for (i = 0; i < n; i++) for (mask = 0x80; mask != 0; mask >>= 1) { bn_add(d, d, d, N, n); if ((a[i] & mask) != 0) bn_add(d, d, b, N, n); } }
status_t element_add(element_t c, element_t a, element_t b) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, b); LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments."); if(type == ZR) { LEAVE_IF( c->type != ZR, "result initialized but invalid type."); bn_add(c->bn, a->bn, b->bn); bn_mod(c->bn, c->bn, c->order); } else if(type == G1) { LEAVE_IF( c->type != G1, "result initialized but invalid type."); g1_add(c->g1, a->g1, b->g1); g1_norm(c->g1, c->g1); } else if(type == G2) { LEAVE_IF( c->type != G2, "result initialized but invalid type."); g2_add(c->g2, a->g2, b->g2); g2_norm(c->g2, c->g2); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
void bn_to_mon(u8 *d, u8 *N, u32 n) { u32 i; for (i = 0; i < 8*n; i++) bn_add(d, d, d, N, n); }
status_t element_mul(element_t c, element_t a, element_t b) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, b); LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments."); LEAVE_IF( c->type != type, "result initialized but invalid type."); if(type == ZR) { bn_mul(c->bn, a->bn, b->bn); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); else { bn_mod(c->bn, c->bn, c->order); } } else if(type == G1) { g1_add(c->g1, a->g1, b->g1); //g1_norm(c->g1, c->g1); } else if(type == G2) { g2_add(c->g2, a->g2, b->g2); //g2_norm(c->g2, c->g2); } else if(type == GT) { gt_mul(c->gt, a->gt, b->gt); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
int cp_pss_sig(g1_t a, g1_t b, uint8_t *msg, int len, bn_t r, bn_t s) { bn_t m, n; int result = RLC_OK; bn_null(m); bn_null(n); TRY { bn_new(m); bn_new(n); g1_get_ord(n); bn_read_bin(m, msg, len); bn_mul(m, m, s); bn_mod(m, m, n); bn_add(m, m, r); bn_mod(m, m, n); g1_rand(a); g1_mul(b, a, m); } CATCH_ANY { result = RLC_ERR; } FINALLY { bn_free(m); bn_free(n); } return result; }
status_t element_invert(element_t c, element_t a) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, c); if(type == ZR) { bn_t s; bn_inits(s); // compute c = (1 / a) mod n bn_gcd_ext(s, c->bn, NULL, a->bn, a->order); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); bn_free(s); } else if(type == G1) { g1_neg(c->g1, a->g1); } else if(type == G2) { g2_neg(c->g2, a->g2); } else if(type == GT) { gt_inv(c->gt, a->gt); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
status_t element_mul_int(element_t c, element_t a, integer_t b) { GroupType type = a->type; LEAVE_IF(a->isInitialized != TRUE, "invalid argument."); LEAVE_IF(c->isInitialized != TRUE || c->type != type, "result not initialized or invalid type."); if(type == ZR) { bn_mul(c->bn, a->bn, b); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); else { bn_mod(c->bn, c->bn, c->order); } } else if(type == G1) { g1_mul(c->g1, a->g1, b); } else if(type == G2) { g2_mul(c->g2, a->g2, b); } else if(type == GT) { gt_exp(c->gt, a->gt, b); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
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 { bn_rand_mod(k, n); 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 bn_to_mon(uint8_t *d, uint8_t *N, uint32_t n) { uint32_t i; for (i = 0; i < 8*n; i++) bn_add(d, d, d, N, n); }
int bn_add_array(bn_st * bn_out, bn_st * bn_array, int size) { for (int i = 0; i < size; ++i) { bn_add(bn_out, &bn_array[i], bn_out); // Add all the values } return 0; }
int cp_rsa_gen_basic(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); } 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); bn_mul(t, prv->p, prv->q); bn_set_2b(pub->e, 16); bn_add_dig(pub->e, pub->e, 1); 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) { bn_add_dig(prv->p, prv->p, 1); bn_add_dig(prv->q, prv->q, 1); } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(t); bn_free(r); } return result; }
int bn_add_array_mod(bn_st * bn_out, bn_st * bn_array, int size, bn_st * modulus) { for (int i = 0; i < size; ++i) { bn_add(bn_out, &bn_array[i], bn_out); // Add all the values bn_mod_basic(bn_out, bn_out, modulus); // Reduce at each step } return 0; }
int cp_bbs_sig(g1_t s, uint8_t *msg, int len, int hash, bn_t d) { bn_t m, n, r; uint8_t h[MD_LEN]; int result = STS_OK; bn_null(m); bn_null(n); bn_null(r); TRY { bn_new(m); bn_new(n); bn_new(r); g1_get_ord(n); /* m = H(msg). */ if (hash) { bn_read_bin(m, msg, len); } else { md_map(h, msg, len); bn_read_bin(m, h, MD_LEN); } bn_mod(m, m, n); /* m = 1/(m + d) mod n. */ bn_add(m, m, d); bn_gcd_ext(r, m, NULL, m, n); if (bn_sign(m) == BN_NEG) { bn_add(m, m, n); } /* s = 1/(m+d) * g1. */ g1_mul_gen(s, m); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(n); bn_free(r); } return result; }
static char * kcl_z_add(z_t *z, cint_t *a, cint_t *b, cint_t **r) { bn_t *bn; char *err; bn = bn_add(z->z_data, NULL, a->cint_data, b->cint_data); err = kcl_z_set_result(r, bn); bn_freetbuf(z->z_data, bn); return(err); }
int bn_add_mod(bn_st * out, bn_st * in1, bn_st * in2, bn_st * modulus) { // Temporary variable in which to store the reuslt of the addition // before appplying the modular reduction bn_st temp; bn_new_size(&temp, RELIC_DIGS+1); // Addition bn_add(&temp,in1,in2); // Modular reduction bn_mod_basic(out, &temp, modulus); bn_clean(&temp); return 0; }
int cp_phpe_dec(uint8_t *out, int out_len, uint8_t *in, int in_len, bn_t n, bn_t l) { bn_t c, u, s; int size, result = STS_OK; size = bn_size_bin(n); if (in_len < 0 || in_len != 2 * size) { return STS_ERR; } bn_null(c); bn_null(u); bn_null(s); TRY { bn_new(c); bn_new(u); bn_new(s); /* Compute (c^l mod n^2) * u mod n. */ bn_sqr(s, n); bn_read_bin(c, in, in_len); bn_mxp(c, c, l, s); bn_sub_dig(c, c, 1); bn_div(c, c, n); bn_gcd_ext(s, u, NULL, l, n); if (bn_sign(u) == BN_NEG) { bn_add(u, u, n); } bn_mul(c, c, u); bn_mod(c, c, n); size = bn_size_bin(c); if (size <= out_len) { memset(out, 0, out_len); bn_write_bin(out + (out_len - size), size, c); } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(c); bn_free(u); bn_free(s); } return result; }
int main() { bn *x = bn_new(); bn *y = bn_new(); bn *z = bn_new(); assert(x); assert(y); assert(z); int ret = bn_hex2bn(x, "Feedf00D"); assert(!ret); ret = bn_hex2bn(y, "CafeF00d5"); assert(!ret); ret = bn_add(x, x, x); assert(!ret); ret = bn_add(y, y, x); assert(!ret); ret = bn_hex2bn(x, "123456789abcdef"); assert(!ret); ret = bn_add(z, x, y); assert(!ret); char x_str[20]; char y_str[20]; char z_str[20]; ret = bn_bn2hex(x_str, sizeof x_str, x); assert(!ret); ret = bn_bn2hex(y_str, sizeof y_str, y); assert(!ret); ret = bn_bn2hex(z_str, sizeof z_str, z); assert(!ret); bn_free(x); bn_free(y); bn_free(z); printf("x: %s\ny: %s\nz: %s\n", x_str, y_str, z_str); return 0; }
void fp_prime_set_pmers(const int *f, int len) { bn_t p, t; bn_null(p); bn_null(t); TRY { bn_new(p); bn_new(t); if (len >= MAX_TERMS) { THROW(ERR_NO_VALID); } bn_set_2b(p, f[len - 1]); for (int i = len - 2; i > 0; i--) { if (f[i] > 0) { bn_set_2b(t, f[i]); bn_add(p, p, t); } else { bn_set_2b(t, -f[i]); bn_sub(p, p, t); } } if (f[0] > 0) { bn_add_dig(p, p, f[0]); } else { bn_sub_dig(p, p, -f[0]); } #if FP_RDC == QUICK || !defined(STRIP) ctx_t *ctx = core_get(); for (int i = 0; i < len; i++) { ctx->sps[i] = f[i]; } ctx->sps[len] = 0; ctx->sps_len = len; #endif /* FP_RDC == QUICK */ fp_prime_set(p); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(p); bn_free(t); } }
int bn_sub_mod(bn_st * out, bn_st * in1, bn_st * in2, bn_st * modulus) { if (bn_cmp(in1,in2) == CMP_GT) { // If in1 > in2 we just subtract bn_sub(out,in1,in2); } else { // Otherwise compute mod + in1 - in2 bn_add(out, modulus, in1); bn_sub(out,out,in2); } return 0; }
int main(int argc, char *argv[]) { big_number *res = bn_create(1000, NULL); int i; for (i = 0; i < 50; i++) { big_number *tmp1 = bn_create(500, text[i]); big_number *tmp2 = bn_add(tmp1, res); bn_free(tmp1); bn_free(res); res = tmp2; } bn_print(res); return 0; }
void buildnodelist() { struct DayDream_Multinode *cn; cn=nodes; nodelist=(struct List *)NewList(); while(cn->MULTI_NODE) { if (cn->MULTI_NODE == 253) { int j; int i=maincfg.CFG_TELNET1ST; j=maincfg.CFG_TELNETMAX; while(j) { j--; bn_add(cn,i); i++; } } else if (cn->MULTI_NODE == 254) { int j; int i=maincfg.CFG_LOCAL1ST; j=maincfg.CFG_LOCALMAX; while(j) { j--; bn_add(cn,i); i++; } } else { bn_add(cn,cn->MULTI_NODE); } cn++; } return; }
static void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) { u8 e[21]; u8 kk[21]; u8 m[21]; u8 minv[21]; struct point mG; FILE *fp; e[0] = 0; memcpy(e + 1, hash, 20); bn_reduce(e, ec_N, 21); try_again: fp = fopen("/dev/random", "rb"); if (fread(m, sizeof m, 1, fp) != 1) fail("reading random"); fclose(fp); m[0] = 0; if (bn_compare(m, ec_N, 21) >= 0) goto try_again; // R = (mG).x point_mul(&mG, m, &ec_G); point_from_mon(&mG); R[0] = 0; elt_copy(R+1, mG.x); // S = m**-1*(e + Rk) (mod N) bn_copy(kk, k, 21); bn_reduce(kk, ec_N, 21); bn_to_mon(m, ec_N, 21); bn_to_mon(e, ec_N, 21); bn_to_mon(R, ec_N, 21); bn_to_mon(kk, ec_N, 21); bn_mon_mul(S, R, kk, ec_N, 21); bn_add(kk, S, e, ec_N, 21); bn_mon_inv(minv, m, ec_N, 21); bn_mon_mul(S, minv, kk, ec_N, 21); bn_from_mon(R, ec_N, 21); bn_from_mon(S, ec_N, 21); }
// 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; }
static void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) { u8 e[21]; u8 kk[21]; u8 m[21]; u8 minv[21]; struct point mG; e[0] = 0; memcpy(e + 1, hash, 20); bn_reduce(e, ec_N, 21); try_again: get_rand(m, sizeof m); m[0] = 0; if (bn_compare(m, ec_N, 21) >= 0) goto try_again; // R = (mG).x point_mul(&mG, m, &ec_G); point_from_mon(&mG); R[0] = 0; elt_copy(R+1, mG.x); // S = m**-1*(e + Rk) (mod N) bn_copy(kk, k, 21); bn_reduce(kk, ec_N, 21); bn_to_mon(m, ec_N, 21); bn_to_mon(e, ec_N, 21); bn_to_mon(R, ec_N, 21); bn_to_mon(kk, ec_N, 21); bn_mon_mul(S, R, kk, ec_N, 21); bn_add(kk, S, e, ec_N, 21); bn_mon_inv(minv, m, ec_N, 21); bn_mon_mul(S, minv, kk, ec_N, 21); bn_from_mon(R, ec_N, 21); bn_from_mon(S, ec_N, 21); }
int igraph_biguint_add(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); limb_t carry; 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, size_left)); carry=bn_add( VECTOR(res->v), VECTOR(left->v), VECTOR(right->v), size_left); if (carry) { IGRAPH_CHECK(igraph_biguint_extend(res, carry)); } return 0; }
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; }
status_t element_neg(element_t c, element_t a) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, c); if(type == ZR) { bn_neg(c->bn, a->bn); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); } else if(type == G1) { g1_neg(c->g1, a->g1); } else if(type == G2) { g2_neg(c->g2, a->g2); } else if(type == GT) { gt_inv(c->gt, a->gt); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
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_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; }