/** * @brief Perform a single Barrett reduction. * @param ctx [in] The bigint session context. * @param bi [in] A bigint. * @return The result of the Barrett reduction. */ bigint * ICACHE_FLASH_ATTR bi_barrett(BI_CTX *ctx, bigint *bi) { bigint *q1, *q2, *q3, *r1, *r2, *r; uint8_t mod_offset = ctx->mod_offset; bigint *bim = ctx->bi_mod[mod_offset]; int k = bim->size; check(bi); check(bim); /* use Classical method instead - Barrett cannot help here */ if (bi->size > k*2) { return bi_mod(ctx, bi); } q1 = comp_right_shift(bi_clone(ctx, bi), k-1); /* do outer partial multiply */ q2 = regular_multiply(ctx, q1, ctx->bi_mu[mod_offset], 0, k-1); q3 = comp_right_shift(q2, k+1); r1 = comp_mod(bi, k+1); /* do inner partial multiply */ r2 = comp_mod(regular_multiply(ctx, q3, bim, k+1, 0), k+1); r = bi_subtract(ctx, r1, r2, NULL); /* if (r >= m) r = r - m; */ if (bi_compare(r, bim) >= 0) { r = bi_subtract(ctx, r, bim, NULL); } return r; }
/** * @brief Perform a multiplication 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 multiplication. */ bigint *ICACHE_FLASH_ATTR bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib) { check(bia); check(bib); #ifdef CONFIG_BIGINT_KARATSUBA if (min(bia->size, bib->size) < MUL_KARATSUBA_THRESH) { return regular_multiply(ctx, bia, bib, 0, 0); } return karatsuba(ctx, bia, bib, 0); #else return regular_multiply(ctx, bia, bib, 0, 0); #endif }