void fp_read_str(fp_t a, const char *str, int len, int radix) { bn_t t; bn_null(t); TRY { bn_new(t); bn_read_str(t, str, len, radix); if (bn_is_zero(t)) { fp_zero(a); } else { if (t->used == 1) { fp_prime_conv_dig(a, t->dp[0]); } else { fp_prime_conv(a, t); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
void ed_read_bin(ed_t a, const uint8_t *bin, int len) { if (len == 1) { if (bin[0] == 0) { ed_set_infty(a); return; } else { THROW(ERR_NO_BUFFER); return; } } if (len != (FP_BYTES + 1) && len != (2 * FP_BYTES + 1)) { THROW(ERR_NO_BUFFER); return; } a->norm = 1; fp_set_dig(a->z, 1); fp_read_bin(a->y, bin + 1, FP_BYTES); if (len == FP_BYTES + 1) { switch(bin[0]) { case 2: fp_zero(a->x); break; case 3: fp_zero(a->x); fp_set_bit(a->x, 0, 1); break; default: THROW(ERR_NO_VALID); break; } ed_upk(a, a); } if (len == 2 * FP_BYTES + 1) { if (bin[0] == 4) { fp_read_bin(a->x, bin + FP_BYTES + 1, FP_BYTES); } else { THROW(ERR_NO_VALID); } } #if ED_ADD == EXTND ed_projc_to_extnd(a, a->x, a->y, a->z); #endif }
/* * Compress twisted Edwards curve point by compressing the x-coordinate to its sign. */ void ed_pck(ed_t r, const ed_t p) { fp_copy(r->y, p->y); int b = fp_get_bit(p->x, 0); fp_zero(r->x); fp_set_bit(r->x, 0, b); fp_set_dig(r->z, 1); r->norm = 1; }
/* * Emulates (~v). */ VECTOR_T* MATLAB_NAMESPACE::logical_not(const VECTOR_T* v) { VECTOR_T* not_v = VECTOR_ID(alloc)(v->size); for (int i = 0; i < (int)v->size; i++) { bool z = fp_zero(VECTOR_ID(get)(v, i)); VECTOR_ID(set)(not_v, i, (FP_T)z); } return not_v; }
void ep2_read_bin(ep2_t a, uint8_t *bin, int len) { if (len == 1) { if (bin[0] == 0) { ep2_set_infty(a); return; } else { THROW(ERR_NO_BUFFER); return; } } if (len != (2 * FP_BYTES + 1) && len != (4 * FP_BYTES + 1)) { THROW(ERR_NO_BUFFER); return; } a->norm = 1; fp_set_dig(a->z[0], 1); fp_zero(a->z[1]); fp2_read_bin(a->x, bin + 1, 2 * FP_BYTES); if (len == 2 * FP_BYTES + 1) { switch(bin[0]) { case 2: fp2_zero(a->y); break; case 3: fp2_zero(a->y); fp_set_bit(a->y[0], 0, 1); fp_zero(a->y[1]); break; default: THROW(ERR_NO_VALID); break; } ep2_upk(a, a); } if (len == 4 * FP_BYTES + 1) { if (bin[0] == 4) { fp2_read_bin(a->y, bin + 2 * FP_BYTES + 1, 2 * FP_BYTES); } else { THROW(ERR_NO_VALID); } } }
t_stat fp_div (uint32 d, uint32 s) { FPA sfp, dfp; uint32 i, pad, a100ml, a99ml; int32 ez; t_stat r; r = fp_unpack_two (d, s, &dfp, &sfp); /* unpack operands */ if (r != SCPE_OK) /* error? */ return r; if (sfp.zero) { /* divide by zero? */ ind[IN_OVF] = 1; /* dead jim */ return SCPE_OK; } if (dfp.zero) /* divide into zero? */ return fp_zero (&dfp); for (i = 0; i < PROD_AREA_LEN; i++) /* clear prod area */ M[PROD_AREA + i] = 0; a100ml = ADDR_S (PROD_AREA_END, dfp.lnt); /* 100 - lnt */ a99ml = ADDR_S (PROD_AREA_END - 1, dfp.lnt); /* 99 - lnt */ if (fp_comp_mant (dfp.addr, sfp.addr, dfp.lnt) >= 0) { /* |Mdst| >= |Msrc|? */ pad = a100ml; dfp.exp = dfp.exp - sfp.exp + 1; /* res exp = diff + 1 */ } else { pad = a99ml; dfp.exp = dfp.exp - sfp.exp; /* res exp = diff */ } r = xmt_divd (pad, dfp.addr); /* xmt dividend */ if (r != SCPE_OK) /* error? */ return r; r = div_field (a100ml, sfp.addr, &ez); /* divide fractions */ if (r != SCPE_OK) /* error? */ return r; if (ez) /* result zero? */ return fp_zero (&dfp); ind[IN_HP] = ((dfp.sign ^ sfp.sign) == 0); /* set res sign */ ind[IN_EZ] = 0; /* not zero */ fp_copy_mant (dfp.addr, a99ml, dfp.lnt); /* copy result */ return fp_pack (&dfp); }
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 }
/* * Emulates (~m) */ MATRIX_T* MATLAB_NAMESPACE::logical_not(const MATRIX_T* m) { MATRIX_T* not_m = MATRIX_ID(alloc)(m->size1, m->size2); for (int i = 0; i < (int)m->size1; i++) { for (int j = 0; j < (int)m->size2; j++) { bool z = fp_zero(MATRIX_ID(get)(m, i, j)); MATRIX_ID(set)(not_m, i, j, (FP_T)z); } } return not_m; }
status_t g1_read_bin(g1_t g, uint8_t *data, int data_len) { if(g == NULL) return ELEMENT_UNINITIALIZED; fp_read_bin(g->x, data, FP_BYTES); fp_read_bin(g->y, &(data[FP_BYTES + 1]), FP_BYTES); fp_zero(g->z); fp_set_dig(g->z, 1); return ELEMENT_OK; }
void fp2_pck(fp2_t c, fp2_t a) { int b = fp_get_bit(a[1], 0); if (fp2_test_uni(c)) { fp_copy(c[0], a[0]); fp_zero(c[1]); fp_set_bit(c[1], 0, b); } else { fp2_copy(c, a); } }
status_t g2_read_bin(g2_t g, uint8_t *data, int data_len) { if(g == NULL) return ELEMENT_UNINITIALIZED; if(data_len < G2_LEN) return ELEMENT_INVALID_ARG_LEN; uint8_t *d = data; fp_read_bin(g->x[0], d, FP_BYTES); d = &(d[FP_BYTES + 1]); fp_read_bin(g->x[1], d, FP_BYTES); d = &(d[FP_BYTES + 1]); fp_read_bin(g->y[0], d, FP_BYTES); d = &(d[FP_BYTES + 1]); fp_read_bin(g->y[1], d, FP_BYTES); fp_zero(g->z[0]); fp_zero(g->z[1]); fp_set_dig(g->z[0], 1); return ELEMENT_OK; }
/* c = (a, b) */ void fp_gcd(fp_int *a, fp_int *b, fp_int *c) { fp_int u, v, r; /* either zero than gcd is the largest */ if (fp_iszero (a) == 1 && fp_iszero (b) == 0) { fp_abs (b, c); return; } if (fp_iszero (a) == 0 && fp_iszero (b) == 1) { fp_abs (a, c); return; } /* optimized. At this point if a == 0 then * b must equal zero too */ if (fp_iszero (a) == 1) { fp_zero(c); return; } /* sort inputs */ if (fp_cmp_mag(a, b) != FP_LT) { fp_init_copy(&u, a); fp_init_copy(&v, b); } else { fp_init_copy(&u, b); fp_init_copy(&v, a); } fp_zero(&r); while (fp_iszero(&v) == FP_NO) { fp_mod(&u, &v, &r); fp_copy(&v, &u); fp_copy(&r, &v); } fp_copy(&u, c); }
void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c) { /* zero the int */ fp_zero (a); /* If we know the endianness of this architecture, and we're using 32-bit fp_digits, we can optimize this */ #if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(FP_64BIT) /* But not for both simultaneously */ #if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG) #error Both ENDIAN_LITTLE and ENDIAN_BIG defined. #endif { unsigned char *pd = (unsigned char *)a->dp; if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) { int excess = c - (FP_SIZE * sizeof(fp_digit)); c -= excess; b += excess; } a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit); /* read the bytes in */ #ifdef ENDIAN_BIG { /* Use Duff's device to unroll the loop. */ int idx = (c - 1) & ~3; switch (c % 4) { case 0: do { pd[idx+0] = *b++; case 3: pd[idx+1] = *b++; case 2: pd[idx+2] = *b++; case 1: pd[idx+3] = *b++; idx -= 4; } while ((c -= 4) > 0); } } #else for (c -= 1; c >= 0; c -= 1) { pd[c] = *b++; } #endif } #else /* read the bytes in */ for (; c > 0; c--) { fp_mul_2d (a, 8, a); a->dp[0] |= *b++; a->used += 1; } #endif fp_clamp (a); }
void ep2_frb(ep2_t r, ep2_t p, int i) { switch (i) { case 0: ep2_copy(r, p); break; case 1: fp2_frb(r->x, p->x, 1); fp2_frb(r->y, p->y, 1); if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_art(r->x, r->x); fp2_mul_art(r->y, r->y); } else { fp2_mul_frb(r->x, r->x, 1, 2); } fp2_mul_frb(r->y, r->y, 1, 3); break; case 2: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_mul_frb(r->x, p->x, 2, 4); } else { fp2_mul_frb(r->x, p->x, 2, 2); } fp2_neg(r->y, p->y); break; case 3: if (ep2_curve_is_twist() == EP_MTYPE) { fp2_frb(r->x, p->x, 1); fp2_frb(r->y, p->y, 1); fp2_mul_frb(r->x, r->x, 1, 4); fp2_mul_frb(r->x, r->x, 2, 4); fp2_mul_art(r->x, r->x); fp2_mul_frb(r->y, r->y, 1, 3); fp2_mul_art(r->y, r->y); fp2_neg(r->y, r->y); } else { fp2_frb(r->x, p->x, 1); fp2_mul_frb(r->x, r->x, 3, 2); fp_neg(r->y[0], p->y[0]); fp_copy(r->y[1], p->y[1]); fp2_mul_frb(r->y, r->y, 1, 3); } break; } r->norm = 1; fp_set_dig(r->z[0], 1); fp_zero(r->z[1]); }
/* c = a mod b, 0 <= c < b */ int fp_mod(fp_int *a, fp_int *b, fp_int *c) { fp_int t; int err; fp_zero(&t); if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) { return err; } if (t.sign != b->sign) { fp_add(&t, b, c); } else { fp_copy(&t, c); } return FP_OKAY; }
void fp_prime_conv(fp_t c, const bn_t a) { bn_t t; bn_null(t); TRY { bn_new(t); #if FP_RDC == MONTY bn_mod(t, a, &(core_get()->prime)); bn_lsh(t, t, FP_DIGS * FP_DIGIT); bn_mod(t, t, &(core_get()->prime)); dv_copy(c, t->dp, FP_DIGS); #else if (a->used > FP_DIGS) { THROW(ERR_NO_PRECI); } bn_mod(t, a, &(core_get()->prime)); if (bn_is_zero(t)) { fp_zero(c); } else { int i; for (i = 0; i < t->used; i++) { c[i] = t->dp[i]; } for (; i < FP_DIGS; i++) { c[i] = 0; } } (void)t; #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
t_stat fp_pack (FPA *fp) { int32 e; uint32 i, mad; e = (fp->exp >= 0)? fp->exp: -fp->exp; /* get |exp| */ if (e > FP_EMAX) { /* too big? */ ind[IN_EXPCHK] = 1; /* set indicator */ if (fp->exp < 0) /* underflow? */ return fp_zero (fp); mad = fp->addr; for (i = 0; i < fp->lnt; i++) { /* mant = 99...99 */ M[mad] = (M[mad] & FLAG) | 9; MM (mad); } e = FP_EMAX; /* cap at max */ } M[ADDR_A (fp->addr, 1)] = (e / 10) | FLAG; /* high exp digit */ M[ADDR_A (fp->addr, 2)] = (e % 10) | /* low exp digit */ ((fp->exp < 0)? FLAG: 0); return SCPE_OK; }
/* computes a = 2**b */ void fp_2expt(fp_int *a, int b) { int z; /* zero a as per default */ fp_zero (a); if (b < 0) { return; } z = b / DIGIT_BIT; if (z >= FP_SIZE) { return; } /* set the used count of where the bit will go */ a->used = z + 1; /* put the single bit in its place */ a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT); }
static int tfm_dh_compute_key(unsigned char *shared, const BIGNUM * pub, DH *dh) { fp_int s, priv_key, p, peer_pub; size_t size = 0; int ret; if (dh->pub_key == NULL || dh->g == NULL || dh->priv_key == NULL) return -1; fp_init(&p); BN2mpz(&p, dh->p); fp_init(&peer_pub); BN2mpz(&peer_pub, pub); /* check if peers pubkey is reasonable */ if (fp_isneg(&peer_pub) || fp_cmp(&peer_pub, &p) >= 0 || fp_cmp_d(&peer_pub, 1) <= 0) { fp_zero(&p); fp_zero(&peer_pub); return -1; } fp_init(&priv_key); BN2mpz(&priv_key, dh->priv_key); fp_init(&s); ret = fp_exptmod(&peer_pub, &priv_key, &p, &s); fp_zero(&p); fp_zero(&peer_pub); fp_zero(&priv_key); if (ret != 0) return -1; size = fp_unsigned_bin_size(&s); fp_to_unsigned_bin(&s, shared); fp_zero(&s); return size; }
void fp_rshd(fp_int *a, int x) { int y; /* too many digits just zero and return */ if (x >= a->used) { fp_zero(a); return; } /* shift */ for (y = 0; y < a->used - x; y++) { a->dp[y] = a->dp[y+x]; } /* zero rest */ for (; y < a->used; y++) { a->dp[y] = 0; } /* decrement count */ a->used -= x; fp_clamp(a); }
void fp_rand(fp_int *a, int digits) { fp_digit d; fp_zero(a); if (digits <= 0) { return; } /* first place a random non-zero digit */ do { d = fp_gen_random(); } while (d == 0); fp_add_d (a, d, a); while (--digits > 0) { fp_lshd (a, 1); fp_add_d (a, fp_gen_random(), a); } return; }
static int tfm_rsa_public_decrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p; int res; size_t size; fp_int s, us, n, e; if (padding != RSA_PKCS1_PADDING) return -1; if (flen > RSA_size(rsa)) return -2; BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); #if 0 /* Check that the exponent is larger then 3 */ if (mp_int_compare_value(&e, 3) <= 0) { fp_zero_multi(&e, &n, NULL); return -3; } #endif fp_init_multi(&s, &us, NULL); fp_read_unsigned_bin(&s, rk_UNCONST(from), flen); if (fp_cmp(&s, &n) >= 0) { fp_zero_multi(&e, &n, NULL); return -4; } res = fp_exptmod(&s, &e, &n, &us); fp_zero_multi(&s, &e, &n, NULL); if (res != 0) return -5; p = to; size = fp_unsigned_bin_size(&us); assert(size <= RSA_size(rsa)); fp_to_unsigned_bin(&us, p); fp_zero(&us); /* head zero was skipped by fp_to_unsigned_bin */ if (*p == 0) return -6; if (*p != 1) return -7; size--; p++; while (size && *p == 0xff) { size--; p++; } if (size == 0 || *p != 0) return -8; size--; p++; memmove(to, p, size); return size; }
void ep_param_set(int param) { int plain = 0, endom = 0, super = 0; char str[2 * FP_BYTES + 2]; fp_t a, b, beta; ep_t g; bn_t r, h, lamb; fp_null(a); fp_null(b); fp_null(beta); bn_null(lamb); ep_null(g); bn_null(r); bn_null(h); TRY { fp_new(a); fp_new(b); fp_new(beta); bn_new(lamb); ep_new(g); bn_new(r); bn_new(h); core_get()->ep_id = 0; switch (param) { #if defined(EP_ENDOM) && FP_PRIME == 158 case BN_P158: ASSIGNK(BN_P158, BN_158); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 160 case SECG_P160: ASSIGN(SECG_P160, SECG_160); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 160 case SECG_K160: ASSIGNK(SECG_K160, SECG_160D); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 192 case NIST_P192: ASSIGN(NIST_P192, NIST_192); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 192 case SECG_K192: ASSIGNK(SECG_K192, SECG_192); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 221 case CURVE_22103: ASSIGN(CURVE_22103, PRIME_22103); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 224 case NIST_P224: ASSIGN(NIST_P224, NIST_224); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 224 case SECG_K224: ASSIGNK(SECG_K224, SECG_224); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 226 case CURVE_4417: ASSIGN(CURVE_4417, PRIME_22605); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 254 case BN_P254: ASSIGNK(BN_P254, BN_254); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 251 case CURVE_1174: ASSIGN(CURVE_1174, PRIME_25109); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 255 case CURVE_25519: ASSIGN(CURVE_25519, PRIME_25519); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 256 case NIST_P256: ASSIGN(NIST_P256, NIST_256); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 256 case SECG_K256: ASSIGNK(SECG_K256, SECG_256); endom = 1; break; case BN_P256: ASSIGNK(BN_P256, BN_256); endom = 1; break; #endif #if defined(EP_PLAIN) & FP_PRIME == 382 case CURVE_67254: ASSIGN(CURVE_67254, PRIME_382105); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 383 case CURVE_383187: ASSIGN(CURVE_383187, PRIME_383187); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 384 case NIST_P384: ASSIGN(NIST_P384, NIST_384); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 477 case B24_P477: ASSIGN(B24_P477, B24_477); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 508 case KSS_P508: ASSIGNK(KSS_P508, KSS_508); endom = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 511 case CURVE_511187: ASSIGN(CURVE_511187, PRIME_511187); plain = 1; break; #endif #if defined(EP_PLAIN) && FP_PRIME == 521 case NIST_P521: ASSIGN(NIST_P521, NIST_521); plain = 1; break; #endif #if defined(EP_ENDOM) && FP_PRIME == 638 case BN_P638: ASSIGNK(BN_P638, BN_638); endom = 1; break; case B12_P638: ASSIGNK(B12_P638, B12_638); endom = 1; break; #endif #if defined(EP_SUPER) && FP_PRIME == 1536 case SS_P1536: ASSIGN(SS_P1536, SS_1536); super = 1; break; #endif default: (void)str; THROW(ERR_NO_VALID); break; } /* Do not generate warnings. */ (void)endom; (void)plain; (void)beta; fp_zero(g->z); fp_set_dig(g->z, 1); g->norm = 1; #if defined(EP_PLAIN) if (plain) { ep_curve_set_plain(a, b, g, r, h); core_get()->ep_id = param; } #endif #if defined(EP_ENDOM) if (endom) { ep_curve_set_endom(b, g, r, h, beta, lamb); core_get()->ep_id = param; } #endif #if defined(EP_SUPER) if (super) { ep_curve_set_super(a, b, g, r, h); core_get()->ep_id = param; } #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp_free(a); fp_free(b); fp_free(beta); bn_free(lamb); ep_free(g); bn_free(r); bn_free(h); } }
/** * Doubles a point represented in affine coordinates on an ordinary prime * elliptic curve. * * @param[out] r - the result. * @param[out] s - the resulting slope. * @param[in] p - the point to double. */ static void ep2_dbl_basic_imp(ep2_t r, fp2_t s, ep2_t p) { fp2_t t0, t1, t2; fp2_null(t0); fp2_null(t1); fp2_null(t2); TRY { fp2_new(t0); fp2_new(t1); fp2_new(t2); /* t0 = 1/(2 * y1). */ fp2_dbl(t0, p->y); fp2_inv(t0, t0); /* t1 = 3 * x1^2 + a. */ fp2_sqr(t1, p->x); fp2_copy(t2, t1); fp2_dbl(t1, t1); fp2_add(t1, t1, t2); if (ep2_curve_is_twist()) { switch (ep_curve_opt_a()) { case OPT_ZERO: break; case OPT_ONE: fp_set_dig(t2[0], 1); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; case OPT_DIGIT: fp_set_dig(t2[0], ep_curve_get_a()[0]); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; default: fp_copy(t2[0], ep_curve_get_a()); fp_zero(t2[1]); fp2_mul_art(t2, t2); fp2_mul_art(t2, t2); fp2_add(t1, t1, t2); break; } } /* t1 = (3 * x1^2 + a)/(2 * y1). */ fp2_mul(t1, t1, t0); if (s != NULL) { fp2_copy(s, t1); } /* t2 = t1^2. */ fp2_sqr(t2, t1); /* x3 = t1^2 - 2 * x1. */ fp2_dbl(t0, p->x); fp2_sub(t0, t2, t0); /* y3 = t1 * (x1 - x3) - y1. */ fp2_sub(t2, p->x, t0); fp2_mul(t1, t1, t2); fp2_sub(r->y, t1, p->y); fp2_copy(r->x, t0); fp2_copy(r->z, p->z); r->norm = 1; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t0); fp2_free(t1); fp2_free(t2); } }
static int tfm_dh_generate_key(DH *dh) { fp_int pub, priv_key, g, p; int have_private_key = (dh->priv_key != NULL); int codes, times = 0; int res; if (dh->p == NULL || dh->g == NULL) return 0; while (times++ < DH_NUM_TRIES) { if (!have_private_key) { size_t bits = BN_num_bits(dh->p); if (dh->priv_key) BN_free(dh->priv_key); dh->priv_key = BN_new(); if (dh->priv_key == NULL) return 0; if (!BN_rand(dh->priv_key, bits - 1, 0, 0)) { BN_clear_free(dh->priv_key); dh->priv_key = NULL; return 0; } } if (dh->pub_key) BN_free(dh->pub_key); fp_init_multi(&pub, &priv_key, &g, &p, NULL); BN2mpz(&priv_key, dh->priv_key); BN2mpz(&g, dh->g); BN2mpz(&p, dh->p); res = fp_exptmod(&g, &priv_key, &p, &pub); fp_zero(&priv_key); fp_zero(&g); fp_zero(&p); if (res != 0) continue; dh->pub_key = mpz2BN(&pub); fp_zero(&pub); if (dh->pub_key == NULL) return 0; if (DH_check_pubkey(dh, dh->pub_key, &codes) && codes == 0) break; if (have_private_key) return 0; } if (times >= DH_NUM_TRIES) { if (!have_private_key && dh->priv_key) { BN_free(dh->priv_key); dh->priv_key = NULL; } if (dh->pub_key) { BN_free(dh->pub_key); dh->pub_key = NULL; } return 0; } return 1; }
void ep_set_infty(ep_t p) { fp_zero(p->x); fp_zero(p->y); fp_zero(p->z); p->norm = 1; }
void fp2_zero(fp2_t a) { fp_zero(a[0]); fp_zero(a[1]); }
static int tfm_rsa_private_decrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *ptr; int res; int size; fp_int in, out, n, e; if (padding != RSA_PKCS1_PADDING) return -1; size = RSA_size(rsa); if (flen > size) return -2; fp_init_multi(&in, &out, NULL); BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); fp_read_unsigned_bin(&in, rk_UNCONST(from), flen); if(fp_isneg(&in) || fp_cmp(&in, &n) >= 0) { size = -2; goto out; } if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) { fp_int p, q, dmp1, dmq1, iqmp; BN2mpz(&p, rsa->p); BN2mpz(&q, rsa->q); BN2mpz(&dmp1, rsa->dmp1); BN2mpz(&dmq1, rsa->dmq1); BN2mpz(&iqmp, rsa->iqmp); res = tfm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out); fp_zero_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL); if (res != 0) { size = -3; goto out; } } else { fp_int d; if(fp_isneg(&in) || fp_cmp(&in, &n) >= 0) return -4; BN2mpz(&d, rsa->d); res = fp_exptmod(&in, &d, &n, &out); fp_zero(&d); if (res != 0) { size = -5; goto out; } } ptr = to; { size_t ssize; ssize = fp_unsigned_bin_size(&out); assert(size >= ssize); fp_to_unsigned_bin(&out, ptr); size = ssize; } /* head zero was skipped by mp_int_to_unsigned */ if (*ptr != 2) { size = -6; goto out; } size--; ptr++; while (size && *ptr != 0) { size--; ptr++; } if (size == 0) return -7; size--; ptr++; memmove(to, ptr, size); out: fp_zero_multi(&e, &n, &in, &out, NULL); return size; }
static int tfm_rsa_private_encrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p, *p0; int res; int size; fp_int in, out, n, e; if (padding != RSA_PKCS1_PADDING) return -1; size = RSA_size(rsa); if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen) return -2; p0 = p = malloc(size); *p++ = 0; *p++ = 1; memset(p, 0xff, size - flen - 3); p += size - flen - 3; *p++ = 0; memcpy(p, from, flen); p += flen; assert((p - p0) == size); BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); fp_init_multi(&in, &out, NULL); fp_read_unsigned_bin(&in, p0, size); free(p0); if(fp_isneg(&in) || fp_cmp(&in, &n) >= 0) { size = -3; goto out; } if (rsa->p && rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) { fp_int p, q, dmp1, dmq1, iqmp; BN2mpz(&p, rsa->p); BN2mpz(&q, rsa->q); BN2mpz(&dmp1, rsa->dmp1); BN2mpz(&dmq1, rsa->dmq1); BN2mpz(&iqmp, rsa->iqmp); res = tfm_rsa_private_calculate(&in, &p, &q, &dmp1, &dmq1, &iqmp, &out); fp_zero_multi(&p, &q, &dmp1, &dmq1, &iqmp, NULL); if (res != 0) { size = -4; goto out; } } else { fp_int d; BN2mpz(&d, rsa->d); res = fp_exptmod(&in, &d, &n, &out); fp_zero(&d); if (res != 0) { size = -5; goto out; } } if (size > 0) { size_t ssize; ssize = fp_unsigned_bin_size(&out); assert(size >= ssize); fp_to_unsigned_bin(&out, to); size = ssize; } out: fp_zero_multi(&e, &n, &in, &out, NULL); return size; }
static int tfm_rsa_public_encrypt(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding) { unsigned char *p, *p0; int res; size_t size, padlen; fp_int enc, dec, n, e; if (padding != RSA_PKCS1_PADDING) return -1; size = RSA_size(rsa); if (size < RSA_PKCS1_PADDING_SIZE || size - RSA_PKCS1_PADDING_SIZE < flen) return -2; BN2mpz(&n, rsa->n); BN2mpz(&e, rsa->e); p = p0 = malloc(size - 1); if (p0 == NULL) { fp_zero_multi(&e, &n, NULL); return -3; } padlen = size - flen - 3; *p++ = 2; if (RAND_bytes(p, padlen) != 1) { fp_zero_multi(&e, &n, NULL); free(p0); return -4; } while(padlen) { if (*p == 0) *p = 1; padlen--; p++; } *p++ = 0; memcpy(p, from, flen); p += flen; assert((p - p0) == size - 1); fp_init_multi(&enc, &dec, NULL); fp_read_unsigned_bin(&dec, p0, size - 1); free(p0); res = fp_exptmod(&dec, &e, &n, &enc); fp_zero_multi(&dec, &e, &n, NULL); if (res != 0) return -4; { size_t ssize; ssize = fp_unsigned_bin_size(&enc); assert(size >= ssize); fp_to_unsigned_bin(&enc, to); size = ssize; } fp_zero(&enc); return size; }