// SPDX-License-Identifier: BSD-2-Clause /* * Copyright (c) 2014, STMicroelectronics International N.V. */ #include "mpa.h" /************************************************************* * * LIB FUNCTIONS * *************************************************************/ /*------------------------------------------------------------ * * mpa_mod * */ void mpa_mod(mpanum dest, const mpanum op, const mpanum n, mpa_scratch_mem pool) { mpa_div(NULL, dest, op, n, pool); } /*------------------------------------------------------------ * * mpa_add_mod * */ void mpa_add_mod(mpanum dest, const mpanum op1, const mpanum op2, const mpanum n, mpa_scratch_mem pool) { mpanum tmp_dest; mpa_alloc_static_temp_var(&tmp_dest, pool); mpa_add(tmp_dest, op1, op2, pool); mpa_div(NULL, dest, tmp_dest, n, pool); mpa_free_static_temp_var(&tmp_dest, pool); } /*------------------------------------------------------------ * * mpa_sub_mod * */ void mpa_sub_mod(mpanum dest, const mpanum op1, const mpanum op2, const mpanum n, mpa_scratch_mem pool) { mpanum tmp_dest; mpa_alloc_static_temp_var(&tmp_dest, pool); mpa_sub(tmp_dest, op1, op2, pool); mpa_div(NULL, dest, tmp_dest, n, pool); mpa_free_static_temp_var(&tmp_dest, pool); } /*------------------------------------------------------------ * * mpa_mul_mod * */ void mpa_mul_mod(mpanum dest, const mpanum op1, const mpanum op2, const mpanum n, mpa_scratch_mem pool) { mpanum tmp_dest; mpa_alloc_static_temp_var(&tmp_dest, pool); mpa_mul(tmp_dest, op1, op2, pool); mpa_div(NULL, dest, tmp_dest, n, pool); mpa_free_static_temp_var(&tmp_dest, pool); } /*------------------------------------------------------------ * * mpa_inv_mod * */ int mpa_inv_mod(mpanum dest, const mpanum op, const mpanum n, mpa_scratch_mem pool) { mpanum gcd; mpanum tmp_dest; int mem_marker; int res; if (mpa_cmp_short(op, 1) == 0) { mpa_set_S32(dest, 1); return 0; } mem_marker = (dest == op); if (mem_marker) mpa_alloc_static_temp_var(&tmp_dest, pool); else tmp_dest = dest; mpa_alloc_static_temp_var(&gcd, pool); /* The function mpa_extended_gcd behaves badly if tmp_dest = op */ mpa_extended_gcd(gcd, tmp_dest, NULL, op, n, pool); res = mpa_cmp_short(gcd, 1); if (mem_marker) { mpa_copy(dest, tmp_dest); mpa_free_static_temp_var(&tmp_dest, pool); } mpa_free_static_temp_var(&gcd, pool); if (res == 0) { while (mpa_cmp_short(dest, 0) < 0) mpa_add(dest, dest, n, pool); return 0; } else { return -1; } }