static void test_div_random(void) { int i; char str[MAX_RAND_STRING_SIZE]; TB_INFO(" Testing random divisions"); DEF_BIGINT(n, 2048); DEF_BIGINT(d, 2048); DEF_BIGINT(q, 2048); DEF_BIGINT(r, 2048); DEF_BIGINT(v, 2048); for (i = 0; i < 10000; i++) { tb_set_random_value(n, str, 1); /* don't divide by zero */ do { tb_set_random_value(d, str, 1); } while (TEE_BigIntCmpS32(d, 0) == 0); TEE_BigIntDiv(q, r, n, d); TEE_BigIntMul(v, q, d); TEE_BigIntAdd(v, v, r); TB_ASSERT_BIGINT_EQ(n, v); if (TEE_BigIntCmpS32(d, 0) > 0) TB_ASSERT_BIGINT_LESS(r, d); } DEL_BIGINT(n); DEL_BIGINT(d); DEL_BIGINT(q); DEL_BIGINT(r); DEL_BIGINT(v); }
void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n) { if (TEE_BigIntCmpS32(n, 2) < 0 || TEE_BigIntCmpS32(op, 0) == 0) API_PANIC("too small modulus or trying to invert zero"); mbedtls_mpi mpi_dest; mbedtls_mpi mpi_op; mbedtls_mpi mpi_n; mbedtls_mpi *pop = &mpi_op; get_mpi(&mpi_dest, dest); get_mpi(&mpi_n, n); if (op == dest) pop = &mpi_dest; else get_mpi(&mpi_op, op); MPI_CHECK(mbedtls_mpi_inv_mod(&mpi_dest, pop, &mpi_n)); MPI_CHECK(copy_mpi_to_bigint(&mpi_dest, dest)); mbedtls_mpi_free(&mpi_dest); mbedtls_mpi_free(&mpi_n); if (pop == &mpi_op) mbedtls_mpi_free(&mpi_op); }
/* * TEE_BigIntInvMod */ void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n) { mpanum mpa_dest = (mpa_num_base *)dest; mpanum mpa_op = (mpa_num_base *)op; mpanum mpa_n = (mpa_num_base *)n; if (TEE_BigIntCmpS32(n, 2) < 0 || TEE_BigIntCmpS32(op, 0) == 0) TEE_BigInt_Panic("too small modulus or trying to invert zero"); mpa_inv_mod(mpa_dest, mpa_op, mpa_n, mempool); }
/* * TEE_BigIntMulMod */ void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n) { mpanum mpa_dest = (mpa_num_base *)dest; mpanum mpa_op1 = (mpa_num_base *)op1; mpanum mpa_op2 = (mpa_num_base *)op2; mpanum mpa_n = (mpa_num_base *)n; mpanum tmp_dest; if (TEE_BigIntCmpS32(n, 2) < 0) TEE_BigInt_Panic("Modulus is too short"); /* * From the spec, mpa_dest must be of magnitude "mpa_n" * But internal computations in mpa do not have such assumptions * (as __mpa_div_q_r, where "r" must be of magnitude "op1", * whereas GP provides a magnitude of "op2") * This is a tempory variable is used, before storing the * final result. */ mpa_alloc_static_temp_var(&tmp_dest, mempool); mpa_mul_mod(tmp_dest, mpa_op1, mpa_op2, mpa_n, mempool); if (mpa_cmp_short(tmp_dest, 0) < 0) mpa_add(tmp_dest, tmp_dest, mpa_n, mempool); mpa_copy(mpa_dest, tmp_dest); mpa_free_static_temp_var(&tmp_dest, mempool); }
void TEE_BigIntMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n) { if (TEE_BigIntCmpS32(n, 2) < 0) API_PANIC("Modulus is too short"); bigint_binary(dest, op, n, mbedtls_mpi_mod_mpi); }
/* * TEE_BigIntDiv */ void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r, const TEE_BigInt *op1, const TEE_BigInt *op2) { mpanum mpa_dest_q = (mpa_num_base *)dest_q; mpanum mpa_dest_r = (mpa_num_base *)dest_r; mpanum mpa_op1 = (mpa_num_base *)op1; mpanum mpa_op2 = (mpa_num_base *)op2; if (TEE_BigIntCmpS32(op2, 0) == 0) TEE_BigInt_Panic("Divisor is zero"); mpa_div(mpa_dest_q, mpa_dest_r, mpa_op1, mpa_op2, mempool); }
/* * TEE_BigIntSubMod */ void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n) { mpanum mpa_dest = (mpa_num_base *)dest; mpanum mpa_op1 = (mpa_num_base *)op1; mpanum mpa_op2 = (mpa_num_base *)op2; mpanum mpa_n = (mpa_num_base *)n; if (TEE_BigIntCmpS32(n, 2) < 0) TEE_BigInt_Panic("Modulus is too short"); mpa_sub_mod(mpa_dest, mpa_op1, mpa_op2, mpa_n, mempool); if (mpa_cmp_short(mpa_dest, 0) < 0) mpa_add(mpa_dest, mpa_dest, mpa_n, mempool); }
static void bigint_binary_mod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n, int (*func)(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)) { if (TEE_BigIntCmpS32(n, 2) < 0) API_PANIC("Modulus is too short"); mbedtls_mpi mpi_dest; mbedtls_mpi mpi_op1; mbedtls_mpi mpi_op2; mbedtls_mpi mpi_n; mbedtls_mpi *pop1 = &mpi_op1; mbedtls_mpi *pop2 = &mpi_op2; mbedtls_mpi mpi_t; get_mpi(&mpi_dest, dest); get_mpi(&mpi_n, n); if (op1 == dest) pop1 = &mpi_dest; else get_mpi(&mpi_op1, op1); if (op2 == dest) pop2 = &mpi_dest; else if (op2 == op1) pop2 = pop1; else get_mpi(&mpi_op2, op2); get_mpi(&mpi_t, NULL); MPI_CHECK(func(&mpi_t, pop1, pop2)); MPI_CHECK(mbedtls_mpi_mod_mpi(&mpi_dest, &mpi_t, &mpi_n)); MPI_CHECK(copy_mpi_to_bigint(&mpi_dest, dest)); mbedtls_mpi_free(&mpi_dest); if (pop1 == &mpi_op1) mbedtls_mpi_free(&mpi_op1); if (pop2 == &mpi_op2) mbedtls_mpi_free(&mpi_op2); mbedtls_mpi_free(&mpi_t); }