int main() { bi_initialize(); int k = 2; bigint f1 = int_to_bi(1), f2 = int_to_bi(1), f3, tmp; bigint zeros = int_to_bi(1000000000); while (1) { k++; f3 = bi_add(f1, bi_copy(f2)); int mod = bi_int_mod(bi_copy(f3), 1000000000); if (mod >= 100000000) { if (is_pandigital(mod)) { tmp = bi_copy(f3); while (bi_compare(bi_copy(tmp), bi_copy(zeros)) > 0) { tmp = bi_int_divide(tmp, 10); } if (is_pandigital(bi_to_int(tmp))) { break; } } } f1 = f2; f2 = f3; } bi_free(f2); bi_free(f3); bi_free(zeros); printf("%d\n", k); bi_terminate(); return 0; }
void DH_generate_key(DH_CTX *dh_ctx) { BI_CTX *bi_ctx = bi_initialize(); int len = dh_ctx->len; bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus bigint *g = bi_import(bi_ctx, dh_ctx->g, dh_ctx->glen); //generator bigint *x, *gx; bi_permanent(g); //generate private key X get_random_NZ(len, dh_ctx->x); x = bi_import(bi_ctx, dh_ctx->x, len); bi_permanent(x); //calculate public key gx = g^x mod p bi_set_mod(bi_ctx, p, BIGINT_M_OFFSET); bi_ctx->mod_offset = BIGINT_M_OFFSET; gx = bi_mod_power(bi_ctx, g, x); bi_permanent(gx); bi_export(bi_ctx, x, dh_ctx->x, len); bi_export(bi_ctx, gx, dh_ctx->gx, len); bi_depermanent(g); bi_depermanent(x); bi_depermanent(gx); bi_free(bi_ctx, g); bi_free(bi_ctx, x); bi_free(bi_ctx, gx); bi_free_mod(bi_ctx, BIGINT_M_OFFSET); bi_terminate(bi_ctx); }
/** * Free up any RSA context resources. */ void RSA_free(RSA_CTX *rsa_ctx) { BI_CTX *bi_ctx; if (rsa_ctx == NULL) /* deal with ptrs that are null */ return; bi_ctx = rsa_ctx->bi_ctx; bi_depermanent(rsa_ctx->e); bi_free(bi_ctx, rsa_ctx->e); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET); if (rsa_ctx->d) { bi_depermanent(rsa_ctx->d); bi_free(bi_ctx, rsa_ctx->d); bi_depermanent(rsa_ctx->dP); bi_depermanent(rsa_ctx->dQ); bi_depermanent(rsa_ctx->qInv); bi_free(bi_ctx, rsa_ctx->dP); bi_free(bi_ctx, rsa_ctx->dQ); bi_free(bi_ctx, rsa_ctx->qInv); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET); } bi_terminate(bi_ctx); free(rsa_ctx); }
/** * Free up any RSA context resources. */ void ICACHE_FLASH_ATTR RSA_free(RSA_CTX *rsa_ctx) { BI_CTX *bi_ctx; if (rsa_ctx == NULL) /* deal with ptrs that are null */ return; bi_ctx = rsa_ctx->bi_ctx; bi_depermanent(rsa_ctx->e); bi_free(bi_ctx, rsa_ctx->e); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_M_OFFSET); if (rsa_ctx->d) { bi_depermanent(rsa_ctx->d); bi_free(bi_ctx, rsa_ctx->d); #ifdef CONFIG_BIGINT_CRT bi_depermanent(rsa_ctx->dP); bi_depermanent(rsa_ctx->dQ); bi_depermanent(rsa_ctx->qInv); bi_free(bi_ctx, rsa_ctx->dP); bi_free(bi_ctx, rsa_ctx->dQ); bi_free(bi_ctx, rsa_ctx->qInv); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_P_OFFSET); bi_free_mod(rsa_ctx->bi_ctx, BIGINT_Q_OFFSET); #endif } bi_terminate(bi_ctx); os_free(rsa_ctx); }
void DH_compute_key(DH_CTX *dh_ctx) { BI_CTX *bi_ctx = bi_initialize(); int len = dh_ctx->len; bigint *p = bi_import(bi_ctx, dh_ctx->p, len); //p modulus bigint *x = bi_import(bi_ctx, dh_ctx->x, len); //private key bigint *gy = bi_import(bi_ctx, dh_ctx->gy, len); //public key(peer) bigint *k; //negotiated(session) key bi_permanent(x); bi_permanent(gy); //calculate session key k = gy^x mod p bi_set_mod(bi_ctx, p, BIGINT_M_OFFSET); bi_ctx->mod_offset = BIGINT_M_OFFSET; k = bi_mod_power(bi_ctx, gy, x); bi_permanent(k); bi_export(bi_ctx, k, dh_ctx->k, len); bi_depermanent(x); bi_depermanent(gy); bi_depermanent(k); bi_free(bi_ctx, x); bi_free(bi_ctx, gy); bi_free(bi_ctx, k); bi_free_mod(bi_ctx, BIGINT_M_OFFSET); bi_terminate(bi_ctx); }
static bigint * ICACHE_FLASH_ATTR regular_multiply(BI_CTX *ctx, bigint *bia, bigint *bib, int inner_partial, int outer_partial) { int i = 0, j; int n = bia->size; int t = bib->size; bigint *biR = alloc(ctx, n + t); comp *sr = biR->comps; comp *sa = bia->comps; comp *sb = bib->comps; check(bia); check(bib); /* clear things to start with */ memset(biR->comps, 0, ((n+t)*COMP_BYTE_SIZE)); do { long_comp tmp; comp carry = 0; int r_index = i; j = 0; if (outer_partial && outer_partial-i > 0 && outer_partial < n) { r_index = outer_partial-1; j = outer_partial-i-1; } do { if (inner_partial && r_index >= inner_partial) { break; } tmp = sr[r_index] + ((long_comp)sa[j])*sb[i] + carry; sr[r_index++] = (comp)tmp; /* downsize */ carry = tmp >> COMP_BIT_SIZE; } while (++j < n); sr[r_index] = carry; } while (++i < t); bi_free(ctx, bia); bi_free(ctx, bib); return trim(biR); }
/* * Karatsuba improves on regular multiplication due to only 3 multiplications * being done instead of 4. The additional additions/subtractions are O(N) * rather than O(N^2) and so for big numbers it saves on a few operations */ static bigint * ICACHE_FLASH_ATTR karatsuba(BI_CTX *ctx, bigint *bia, bigint *bib, int is_square) { bigint *x0, *x1; bigint *p0, *p1, *p2; int m; if (is_square) { m = (bia->size + 1)/2; } else { m = (max(bia->size, bib->size) + 1)/2; } x0 = bi_clone(ctx, bia); x0->size = m; x1 = bi_clone(ctx, bia); comp_right_shift(x1, m); bi_free(ctx, bia); /* work out the 3 partial products */ if (is_square) { p0 = bi_square(ctx, bi_copy(x0)); p2 = bi_square(ctx, bi_copy(x1)); p1 = bi_square(ctx, bi_add(ctx, x0, x1)); } else /* normal multiply */ { bigint *y0, *y1; y0 = bi_clone(ctx, bib); y0->size = m; y1 = bi_clone(ctx, bib); comp_right_shift(y1, m); bi_free(ctx, bib); p0 = bi_multiply(ctx, bi_copy(x0), bi_copy(y0)); p2 = bi_multiply(ctx, bi_copy(x1), bi_copy(y1)); p1 = bi_multiply(ctx, bi_add(ctx, x0, x1), bi_add(ctx, y0, y1)); } p1 = bi_subtract(ctx, bi_subtract(ctx, p1, bi_copy(p2), NULL), bi_copy(p0), NULL); comp_left_shift(p1, m); comp_left_shift(p2, 2*m); return bi_add(ctx, p1, bi_add(ctx, p0, p2)); }
/** * @brief Used when cleaning various bigints at the end of a session. * @param ctx [in] The bigint session context. * @param mod_offset [in] The offset to use. * @see bi_set_mod(). */ void ICACHE_FLASH_ATTR bi_free_mod(BI_CTX *ctx, int mod_offset) { bi_depermanent(ctx->bi_mod[mod_offset]); bi_free(ctx, ctx->bi_mod[mod_offset]); #if defined (CONFIG_BIGINT_MONTGOMERY) bi_depermanent(ctx->bi_RR_mod_m[mod_offset]); bi_depermanent(ctx->bi_R_mod_m[mod_offset]); bi_free(ctx, ctx->bi_RR_mod_m[mod_offset]); bi_free(ctx, ctx->bi_R_mod_m[mod_offset]); #elif defined(CONFIG_BIGINT_BARRETT) bi_depermanent(ctx->bi_mu[mod_offset]); bi_free(ctx, ctx->bi_mu[mod_offset]); #endif bi_depermanent(ctx->bi_normalised_mod[mod_offset]); bi_free(ctx, ctx->bi_normalised_mod[mod_offset]); }
// Initialize B object by placing all Raws into one Bi // Called on B construction void b_init(B *b) { unsigned int i, index; // Destruct existing clusters for(i=0; i<b->nclust; i++) { bi_free(b->bi[i]); } b->nclust=0; // Add the one cluster and initialize its "birth" information b_add_bi(b, bi_new(b->nraw)); strcpy(b->bi[0]->birth_type, "I"); b->bi[0]->birth_pval = 0.0; b->bi[0]->birth_fold = 1.0; b->bi[0]->birth_e = b->reads; b->nalign = 0; b->nshroud = 0; // Add all raws to that cluster for (index=0; index<b->nraw; index++) { bi_add_raw(b->bi[0], b->raw[index]); } bi_census(b->bi[0]); bi_assign_center(b->bi[0]); // Makes cluster center sequence }
/** * @brief Take a bigint and convert it into a byte sequence. * * This is useful after a decrypt operation. * @param ctx [in] The bigint session context. * @param x [in] The bigint to be converted. * @param data [out] The converted data as a byte stream. * @param size [in] The maximum size of the byte stream. Unused bytes will be * zeroed. */ void ICACHE_FLASH_ATTR bi_export(BI_CTX *ctx, bigint *x, uint8_t *data, int size) { int i, j, k = size-1; check(x); memset(data, 0, size); /* ensure all leading 0's are cleared */ for (i = 0; i < x->size; i++) { for (j = 0; j < COMP_BYTE_SIZE; j++) { comp mask = 0xff << (j*8); int num = (x->comps[i] & mask) >> (j*8); data[k--] = num; if (k < 0) { goto buf_done; } } } buf_done: bi_free(ctx, x); }
/** * @brief Perform a subtraction operation between two bigints. * @param ctx [in] The bigint session context. * @param bia [in] A bigint. * @param bib [in] Another bigint. * @param is_negative [out] If defined, indicates that the result was negative. * is_negative may be null. * @return The result of the subtraction. The result is always positive. */ bigint * ICACHE_FLASH_ATTR bi_subtract(BI_CTX *ctx, bigint *bia, bigint *bib, int *is_negative) { int n = bia->size; comp *pa, *pb, carry = 0; check(bia); check(bib); more_comps(bib, n); pa = bia->comps; pb = bib->comps; do { comp sl, rl, cy1; sl = *pa - *pb++; rl = sl - carry; cy1 = sl > *pa; carry = cy1 | (rl > sl); *pa++ = rl; } while (--n != 0); if (is_negative) /* indicate a negative result */ { *is_negative = carry; } bi_free(ctx, trim(bib)); /* put bib back to the way it was */ return trim(bia); }
static PGPError Teardown (PGPPipeline *myself) { DefModContext *context; PGPContextRef cdkContext; pgpAssertAddrValid( myself, PGPPipeline ); cdkContext = myself->cdkContext; pgpAssert (myself); pgpAssert (myself->magic == DEFMODMAGIC); context = (DefModContext *)myself->priv; pgpAssert (context); if (context->tail) context->tail->teardown (context->tail); bi_free (context->zbcontext); /* Free bits data structures */ ct_free (context->ztcontext); /* Free code tree buffers */ lm_free (context->zdcontext); /* Free longest match buffers */ byteFifoDestroy (context->fifo); pgpClearMemory( context, sizeof (*context)); pgpContextMemFree( cdkContext, context); return kPGPError_NoErr; }
/** * @brief Perform an addition operation between two bigints. * @param ctx [in] The bigint session context. * @param bia [in] A bigint. * @param bib [in] Another bigint. * @return The result of the addition. */ bigint * ICACHE_FLASH_ATTR bi_add(BI_CTX *ctx, bigint *bia, bigint *bib) { int n; comp carry = 0; comp *pa, *pb; check(bia); check(bib); n = max(bia->size, bib->size); more_comps(bia, n+1); more_comps(bib, n); pa = bia->comps; pb = bib->comps; do { comp sl, rl, cy1; sl = *pa + *pb++; rl = sl + carry; cy1 = sl < *pa; carry = cy1 | (rl < sl); *pa++ = rl; } while (--n != 0); *pa = carry; /* do overflow */ bi_free(ctx, bib); return trim(bia); }
/* from DAAUtil */ bi_ptr project_into_group_gamma( bi_ptr base, TSS_DAA_PK_internal *issuer_pk) { bi_t exponent; bi_new( exponent); bi_ptr capital_gamma = issuer_pk->capitalGamma; bi_ptr rho = issuer_pk->rho; bi_ptr zeta = bi_new_ptr(); if( capital_gamma == NULL || rho == NULL || zeta == NULL) return NULL; // exponent = capital_gamma - 1 bi_sub( exponent, capital_gamma, bi_1); // exponent = exponent / rho bi_div( exponent, exponent, rho); // zeta = ( base ^ exponent) % capital_gamma LogDebug("project_into_group_gamma: rho [%ld]:%s", bi_nbin_size( rho), bi_2_hex_char( rho)); LogDebug("project_into_group_gamma: base[%ld]:%s", bi_nbin_size( base), bi_2_hex_char( base)); LogDebug("project_into_group_gamma: exponent [%ld]:%s", bi_nbin_size( exponent), bi_2_hex_char( exponent)); LogDebug("project_into_group_gamma: capitalGamma[%ld]:%s", bi_nbin_size( capital_gamma), bi_2_hex_char( capital_gamma)); bi_mod_exp( zeta, base, exponent, capital_gamma); LogDebug("project_into_group_gamma: result:%s", bi_2_hex_char( zeta)); bi_free( exponent); return zeta; }
/** * @brief Perform a modular exponentiation using a temporary modulus. * * We need this function to check the signatures of certificates. The modulus * of this function is temporary as it's just used for authentication. * @param ctx [in] The bigint session context. * @param bi [in] The bigint to perform the exp/mod. * @param bim [in] The temporary modulus. * @param biexp [in] The bigint exponent. * @return The result of the mod exponentiation operation * @see bi_set_mod(). */ bigint *ICACHE_FLASH_ATTR bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp) { bigint *biR, *tmp_biR; /* Set up a temporary bigint context and transfer what we need between * them. We need to do this since we want to keep the original modulus * which is already in this context. This operation is only called when * doing peer verification, and so is not expensive :-) */ BI_CTX *tmp_ctx = bi_initialize(); bi_set_mod(tmp_ctx, bi_clone(tmp_ctx, bim), BIGINT_M_OFFSET); tmp_biR = bi_mod_power(tmp_ctx, bi_clone(tmp_ctx, bi), bi_clone(tmp_ctx, biexp)); biR = bi_clone(ctx, tmp_biR); bi_free(tmp_ctx, tmp_biR); bi_free_mod(tmp_ctx, BIGINT_M_OFFSET); bi_terminate(tmp_ctx); bi_free(ctx, bi); bi_free(ctx, bim); bi_free(ctx, biexp); return biR; }
inline bi_ptr apply_challenge( bi_ptr value, bi_ptr delta, bi_ptr c, bi_ptr capital_gamma) { bi_ptr delta_tilde = bi_new_ptr(); bi_t c_negate; if( delta_tilde == NULL) return NULL; bi_new( c_negate); bi_set( c_negate, c); bi_negate( c_negate); // delta_tilde = ( delta ^ (-c)) % capital_gamma bi_mod_exp( delta_tilde, delta, c_negate, capital_gamma); bi_free( c_negate); // delta_tilde = (delta_tilde * value) % capital_gamma return bi_mod( delta_tilde, bi_mul( delta_tilde, delta_tilde, value), capital_gamma); }
/* * Perform the actual square operion. It takes into account overflow. */ static bigint *ICACHE_FLASH_ATTR regular_square(BI_CTX *ctx, bigint *bi) { int t = bi->size; int i = 0, j; bigint *biR = alloc(ctx, t * 2 + 1); comp *w = biR->comps; comp *x = bi->comps; long_comp carry; os_memset(w, 0, biR->size * COMP_BYTE_SIZE); do { long_comp tmp = w[2 * i] + (long_comp)x[i] * x[i]; w[2 * i] = (comp)tmp; carry = tmp >> COMP_BIT_SIZE; for (j = i + 1; j < t; j++) { uint8_t c = 0; long_comp xx = (long_comp)x[i] * x[j]; if ((COMP_MAX - xx) < xx) { c = 1; } tmp = (xx << 1); if ((COMP_MAX - tmp) < w[i + j]) { c = 1; } tmp += w[i + j]; if ((COMP_MAX - tmp) < carry) { c = 1; } tmp += carry; w[i + j] = (comp)tmp; carry = tmp >> COMP_BIT_SIZE; if (c) { carry += COMP_RADIX; } } tmp = w[i + t] + carry; w[i + t] = (comp)tmp; w[i + t + 1] = tmp >> COMP_BIT_SIZE; } while (++i < t); bi_free(ctx, bi); return trim(biR); }
/** * @brief Close the bigint context and free any resources. * * Free up any used memory - a check is done if all objects were not * properly freed. * @param ctx [in] The bigint session context. */ void ICACHE_FLASH_ATTR bi_terminate(BI_CTX *ctx) { bi_depermanent(ctx->bi_radix); bi_free(ctx, ctx->bi_radix); if (ctx->active_count != 0) { #ifdef CONFIG_SSL_FULL_MODE ssl_printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); #endif return; /* wujg : org ---> abort(); */ } bi_clear_cache(ctx); os_free(ctx); }
/** * @brief Close the bigint context and free any resources. * * Free up any used memory - a check is done if all objects were not * properly freed. * @param ctx [in] The bigint session context. */ void bi_terminate(BI_CTX *ctx) { bi_depermanent(ctx->bi_radix); bi_free(ctx, ctx->bi_radix); if (ctx->active_count != 0) { #ifdef CONFIG_SSL_FULL_MODE printf("bi_terminate: there were %d un-freed bigints\n", ctx->active_count); #endif abort(); } bi_clear_cache(ctx); free(ctx); }
int main() { bi_initialize(); bigint sum = int_to_bi(1); bigint last = int_to_bi(1); int i, j; for (i = 1; i <= (SIZE-1)/2; ++i) { for (j = 0; j < 4; ++j) { last = bi_add(last, bi_int_multiply(int_to_bi(i), 2)); sum = bi_add(sum, bi_copy(last)); } } bi_print(stdout, sum); printf("\n"); bi_free(last); bi_terminate(); return 0; }
/** * Free an X.509 object's resources. */ void x509_free(X509_CTX *x509_ctx) { X509_CTX *next; int i; if (x509_ctx == NULL) /* if already null, then don't bother */ return; for (i = 0; i < X509_NUM_DN_TYPES; i++) { free(x509_ctx->ca_cert_dn[i]); free(x509_ctx->cert_dn[i]); } free(x509_ctx->signature); #ifdef CONFIG_SSL_CERT_VERIFICATION if (x509_ctx->digest) { bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest); } if (x509_ctx->fingerprint) { free(x509_ctx->fingerprint); } if (x509_ctx->spki_sha256) { free(x509_ctx->spki_sha256); } if (x509_ctx->subject_alt_dnsnames) { for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i) free(x509_ctx->subject_alt_dnsnames[i]); free(x509_ctx->subject_alt_dnsnames); } #endif RSA_free(x509_ctx->rsa_ctx); next = x509_ctx->next; free(x509_ctx); x509_free(next); /* clear the chain */ }
/* * Work out g1, g3, g5, g7... etc for the sliding-window algorithm */ static void ICACHE_FLASH_ATTR precompute_slide_window(BI_CTX *ctx, int window, bigint *g1) { int k = 1, i; bigint *g2; for (i = 0; i < window - 1; i++) { /* compute 2^(window-1) */ k <<= 1; } ctx->g = (bigint **)os_malloc(k * sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, g1); bi_permanent(ctx->g[0]); g2 = bi_residue(ctx, bi_square(ctx, ctx->g[0])); /* g^2 */ for (i = 1; i < k; i++) { ctx->g[i] = bi_residue(ctx, bi_multiply(ctx, ctx->g[i - 1], bi_copy(g2))); bi_permanent(ctx->g[i]); } bi_free(ctx, g2); ctx->window = k; }
/** * Perform a multiply between a bigint an an (unsigned) integer */ static bigint *ICACHE_FLASH_ATTR bi_int_multiply(BI_CTX *ctx, bigint *bia, comp b) { int j = 0, n = bia->size; bigint *biR = alloc(ctx, n + 1); comp carry = 0; comp *r = biR->comps; comp *a = bia->comps; check(bia); /* clear things to start with */ os_memset(r, 0, ((n + 1)*COMP_BYTE_SIZE)); do { long_comp tmp = *r + (long_comp)a[j] * b + carry; *r++ = (comp)tmp; /* downsize */ carry = (comp)(tmp >> COMP_BIT_SIZE); } while (++j < n); *r = carry; bi_free(ctx, bia); return trim(biR); }
static bool process_block(const struct bp_block *block, int64_t fpos) { struct blkinfo *bi = bi_new(); bu256_copy(&bi->hash, &block->sha256); bp_block_copy_hdr(&bi->hdr, block); bi->n_file = 0; bi->n_pos = fpos; struct blkdb_reorg reorg; if (!blkdb_add(&db, bi, &reorg)) { fprintf(plog, "brd: blkdb add fail\n"); goto err_out; } /* FIXME: support reorg */ assert(reorg.conn == 1); assert(reorg.disconn == 0); /* if best chain, mark TX's as spent */ if (bu256_equal(&db.best_chain->hash, &bi->hdr.sha256)) { if (!spend_block(&uset, block, bi->height)) { char hexstr[BU256_STRSZ]; bu256_hex(hexstr, &bi->hdr.sha256); fprintf(plog, "brd: block spend fail %u %s\n", bi->height, hexstr); /* FIXME: bad record is now in blkdb */ goto err_out; } } return true; err_out: bi_free(bi); return false; }
int main() { bi_initialize(); int a, b, n; int max_number, prod; for (a = -999; a < 1000; ++a) { for (b = -999; b < 1000; ++b) { n = 0; for (;;) { bigint a_ = int_to_bi(a); bigint b_ = int_to_bi(b); bigint n_ = int_to_bi(n); bigint n2 = bi_multiply( bi_copy( n_ ), bi_copy( n_ ) ); bigint an = bi_multiply(bi_copy(a_),bi_copy(n_)); bigint num = bi_add(bi_copy(n2), bi_copy(an)); bigint num2 = bi_add(bi_copy(num), bi_copy(b_)); int should_break = 0; if (bi_is_probable_prime(bi_copy(num2), 99)) { ++n; } else { if (n > max_number) { max_number = n; prod = a * b; } should_break = 1; } bi_free(num); bi_free(num2); bi_free(a_); bi_free(b_); bi_free(n_); bi_free(n2); bi_free(an); if (should_break) break; } } } printf("%d\n", prod); bi_terminate(); return 0; }
int main() { bi_initialize(); bigint last = int_to_bi(1); int i, j; int number_of_primes = 0; for (i = 1;; ++i) { for (j = 0; j < 4; ++j) { last = bi_add(last, bi_int_multiply(int_to_bi(i), 2)); if (j != 3 && bi_is_probable_prime(bi_copy(last), 4)) { ++number_of_primes; } } if ((double)number_of_primes / (4*i+1) < 0.1) { printf("%d\n", i*2+1); break; } #ifdef DEBUG printf("%d/%d on iteration %d ~%f\n", number_of_primes, (4*i+1), i, (float)number_of_primes/(4*i+1)); #endif } bi_free(last); bi_terminate(); return 0; }
static bool blkdb_read_rec(struct blkdb *db, const struct p2p_message *msg) { struct blkinfo *bi; struct const_buffer buf = { msg->data, msg->hdr.data_len }; if (strncmp(msg->hdr.command, "rec", 12)) return false; bi = bi_new(); if (!bi) return false; /* deserialize record */ if (!deser_u256(&bi->hash, &buf)) goto err_out; if (!deser_bp_block(&bi->hdr, &buf)) goto err_out; /* verify that provided hash matches block header, as an additional * self-verification step */ bp_block_calc_sha256(&bi->hdr); if (!bu256_equal(&bi->hash, &bi->hdr.sha256)) goto err_out; /* verify block may be added to chain, then add it */ struct blkdb_reorg dummy; if (!blkdb_connect(db, bi, &dummy)) goto err_out; return true; err_out: bi_free(bi); return false; }
/** * @brief Perform a modular exponentiation. * * This function requires bi_set_mod() to have been called previously. This is * one of the optimisations used for performance. * @param ctx [in] The bigint session context. * @param bi [in] The bigint on which to perform the mod power operation. * @param biexp [in] The bigint exponent. * @return The result of the mod exponentiation operation * @see bi_set_mod(). */ bigint * ICACHE_FLASH_ATTR bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp) { int i = find_max_exp_index(biexp), j, window_size = 1; bigint *biR = int_to_bi(ctx, 1); #if defined(CONFIG_BIGINT_MONTGOMERY) uint8_t mod_offset = ctx->mod_offset; if (!ctx->use_classical) { /* preconvert */ bi = bi_mont(ctx, bi_multiply(ctx, bi, ctx->bi_RR_mod_m[mod_offset])); /* x' */ bi_free(ctx, biR); biR = ctx->bi_R_mod_m[mod_offset]; /* A */ } #endif check(bi); check(biexp); #ifdef CONFIG_BIGINT_SLIDING_WINDOW for (j = i; j > 32; j /= 5) /* work out an optimum size */ window_size++; /* work out the slide constants */ precompute_slide_window(ctx, window_size, bi); #else /* just one constant */ ctx->g = (bigint **)SSL_MALLOC(sizeof(bigint *)); ctx->g[0] = bi_clone(ctx, bi); ctx->window = 1; bi_permanent(ctx->g[0]); #endif /* if sliding-window is off, then only one bit will be done at a time and * will reduce to standard left-to-right exponentiation */ do { if (exp_bit_is_one(biexp, i)) { int l = i-window_size+1; int part_exp = 0; if (l < 0) /* LSB of exponent will always be 1 */ l = 0; else { while (exp_bit_is_one(biexp, l) == 0) l++; /* go back up */ } /* build up the section of the exponent */ for (j = i; j >= l; j--) { biR = bi_residue(ctx, bi_square(ctx, biR)); if (exp_bit_is_one(biexp, j)) part_exp++; if (j != l) part_exp <<= 1; } part_exp = (part_exp-1)/2; /* adjust for array */ biR = bi_residue(ctx, bi_multiply(ctx, biR, ctx->g[part_exp])); i = l-1; } else /* square it */ { biR = bi_residue(ctx, bi_square(ctx, biR)); i--; } } while (i >= 0); /* cleanup */ for (i = 0; i < ctx->window; i++) { bi_depermanent(ctx->g[i]); bi_free(ctx, ctx->g[i]); } SSL_FREE(ctx->g); bi_free(ctx, bi); bi_free(ctx, biexp); #if defined CONFIG_BIGINT_MONTGOMERY return ctx->use_classical ? biR : bi_mont(ctx, biR); /* convert back */ #else /* CONFIG_BIGINT_CLASSICAL or CONFIG_BIGINT_BARRETT */ return biR; #endif }
/** * @brief Does both division and modulo calculations. * * Used extensively when doing classical reduction. * @param ctx [in] The bigint session context. * @param u [in] A bigint which is the numerator. * @param v [in] Either the denominator or the modulus depending on the mode. * @param is_mod [n] Determines if this is a normal division (0) or a reduction * (1). * @return The result of the division/reduction. */ bigint * ICACHE_FLASH_ATTR bi_divide(BI_CTX *ctx, bigint *u, bigint *v, int is_mod) { int n = v->size, m = u->size-n; int j = 0, orig_u_size = u->size; uint8_t mod_offset = ctx->mod_offset; comp d; bigint *quotient, *tmp_u; comp q_dash; check(u); check(v); /* if doing reduction and we are < mod, then return mod */ if (is_mod && bi_compare(v, u) > 0) { bi_free(ctx, v); return u; } quotient = alloc(ctx, m+1); tmp_u = alloc(ctx, n+1); v = trim(v); /* make sure we have no leading 0's */ d = (comp)((long_comp)COMP_RADIX/(V1+1)); /* clear things to start with */ memset(quotient->comps, 0, ((quotient->size)*COMP_BYTE_SIZE)); /* normalise */ if (d > 1) { u = bi_int_multiply(ctx, u, d); if (is_mod) { v = ctx->bi_normalised_mod[mod_offset]; } else { v = bi_int_multiply(ctx, v, d); } } if (orig_u_size == u->size) /* new digit position u0 */ { more_comps(u, orig_u_size + 1); } do { /* get a temporary short version of u */ memcpy(tmp_u->comps, &u->comps[u->size-n-1-j], (n+1)*COMP_BYTE_SIZE); /* calculate q' */ if (U(0) == V1) { q_dash = COMP_RADIX-1; } else { q_dash = (comp)(((long_comp)U(0)*COMP_RADIX + U(1))/V1); if (v->size > 1 && V2) { /* we are implementing the following: if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - q_dash*V1)*COMP_RADIX) + U(2))) ... */ comp inner = (comp)((long_comp)COMP_RADIX*U(0) + U(1) - (long_comp)q_dash*V1); if ((long_comp)V2*q_dash > (long_comp)inner*COMP_RADIX + U(2)) { q_dash--; } } } /* multiply and subtract */ if (q_dash) { int is_negative; tmp_u = bi_subtract(ctx, tmp_u, bi_int_multiply(ctx, bi_copy(v), q_dash), &is_negative); more_comps(tmp_u, n+1); Q(j) = q_dash; /* add back */ if (is_negative) { Q(j)--; tmp_u = bi_add(ctx, tmp_u, bi_copy(v)); /* lop off the carry */ tmp_u->size--; v->size--; } } else { Q(j) = 0; } /* copy back to u */ memcpy(&u->comps[u->size-n-1-j], tmp_u->comps, (n+1)*COMP_BYTE_SIZE); } while (++j <= m); bi_free(ctx, tmp_u); bi_free(ctx, v); if (is_mod) /* get the remainder */ { bi_free(ctx, quotient); return bi_int_divide(ctx, trim(u), d); } else /* get the quotient */ { bi_free(ctx, u); return trim(quotient); } }
/** * Do some basic checks on the certificate chain. * * Certificate verification consists of a number of checks: * - The date of the certificate is after the start date. * - The date of the certificate is before the finish date. * - A root certificate exists in the certificate store. * - That the certificate(s) are not self-signed. * - The certificate chain is valid. * - The signature of the certificate is valid. */ int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert) { int ret = X509_OK, i = 0; bigint *cert_sig; X509_CTX *next_cert = NULL; BI_CTX *ctx = NULL; bigint *mod = NULL, *expn = NULL; int match_ca_cert = 0; struct timeval tv; uint8_t is_self_signed = 0; if (cert == NULL) { ret = X509_VFY_ERROR_NO_TRUSTED_CERT; goto end_verify; } /* a self-signed certificate that is not in the CA store - use this to check the signature */ if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0) { is_self_signed = 1; ctx = cert->rsa_ctx->bi_ctx; mod = cert->rsa_ctx->m; expn = cert->rsa_ctx->e; } gettimeofday(&tv, NULL); /* check the not before date */ if (tv.tv_sec < cert->not_before) { ret = X509_VFY_ERROR_NOT_YET_VALID; goto end_verify; } /* check the not after date */ if (tv.tv_sec > cert->not_after) { ret = X509_VFY_ERROR_EXPIRED; goto end_verify; } next_cert = cert->next; /* last cert in the chain - look for a trusted cert */ if (next_cert == NULL) { if (ca_cert_ctx != NULL) { /* go thu the CA store */ while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) { if (asn1_compare_dn(cert->ca_cert_dn, ca_cert_ctx->cert[i]->cert_dn) == 0) { /* use this CA certificate for signature verification */ match_ca_cert = 1; ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx; mod = ca_cert_ctx->cert[i]->rsa_ctx->m; expn = ca_cert_ctx->cert[i]->rsa_ctx->e; break; } i++; } } /* couldn't find a trusted cert (& let self-signed errors be returned) */ if (!match_ca_cert && !is_self_signed) { ret = X509_VFY_ERROR_NO_TRUSTED_CERT; goto end_verify; } } else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0) { /* check the chain */ ret = X509_VFY_ERROR_INVALID_CHAIN; goto end_verify; } else /* use the next certificate in the chain for signature verify */ { ctx = next_cert->rsa_ctx->bi_ctx; mod = next_cert->rsa_ctx->m; expn = next_cert->rsa_ctx->e; } /* cert is self signed */ if (!match_ca_cert && is_self_signed) { ret = X509_VFY_ERROR_SELF_SIGNED; goto end_verify; } /* check the signature */ cert_sig = sig_verify(ctx, cert->signature, cert->sig_len, bi_clone(ctx, mod), bi_clone(ctx, expn)); if (cert_sig && cert->digest) { if (bi_compare(cert_sig, cert->digest) != 0) ret = X509_VFY_ERROR_BAD_SIGNATURE; bi_free(ctx, cert_sig); } else { ret = X509_VFY_ERROR_BAD_SIGNATURE; } if (ret) goto end_verify; /* go down the certificate chain using recursion. */ if (next_cert != NULL) { ret = x509_verify(ca_cert_ctx, next_cert); } end_verify: return ret; }