aboutsummaryrefslogblamecommitdiff
path: root/rtl/modexpng_parameters.vh
blob: 77230fe27ad8975907cbb327a603512e7bc07be7 (plain) (tree)
generated by cgit v1.2.3 (git 2.25.1) at 2024-11-25 15:01:53 +0000
n class="w"> NULL || a->mod_len > MODEXPA7_OPERAND_BYTES || a->result == NULL || a->result_len > MODEXPA7_OPERAND_BYTES || a->result_len < a->mod_len || a->coeff == NULL || a->coeff_len > MODEXPA7_OPERAND_BYTES || a->mont == NULL || a->mont_len > MODEXPA7_OPERAND_BYTES || ((a->msg_len | a->exp_len | a->mod_len) & 3) != 0) return HAL_ERROR_BAD_ARGUMENTS; return HAL_OK; } static inline hal_error_t setup_precalc(const int precalc, hal_modexp_arg_t *a) { hal_error_t err; /* * Check that operand size is compatabible with the core. */ uint32_t operand_max = 0; if ((err = get_register(a->core, MODEXPA7_ADDR_BUFFER_BITS, &operand_max)) != HAL_OK) return err; operand_max /= 8; if (a->msg_len > operand_max || a->exp_len > operand_max || a->mod_len > operand_max || a->coeff_len > operand_max || a->mont_len > operand_max) return HAL_ERROR_BAD_ARGUMENTS; /* * Set the modulus, then initiate calculation of modulus-dependent * speedup factors if necessary, by edge-triggering the "init" bit, * then return to caller so it can wait for precalc. */ if ((err = set_register(a->core, MODEXPA7_ADDR_MODULUS_BITS, a->mod_len * 8)) != HAL_OK || (err = set_buffer(a->core, MODEXPA7_ADDR_MODULUS, a->mod, a->mod_len)) != HAL_OK || (precalc && (err = hal_io_zero(a->core)) != HAL_OK) || (precalc && (err = hal_io_init(a->core)) != HAL_OK)) return err; return HAL_OK; } static inline hal_error_t setup_calc(const int precalc, hal_modexp_arg_t *a) { hal_error_t err; /* * Select CRT mode if and only if message is longer than exponent. */ const uint32_t mode = a->msg_len > a->mod_len ? MODEXPA7_MODE_CRT : MODEXPA7_MODE_PLAIN; /* * Copy out precalc results if necessary, then load everything and * start the calculation by edge-triggering the "next" bit. If * everything works, return to caller so it can wait for the * calculation to complete. */ if ((precalc && (err = get_buffer(a->core, MODEXPA7_ADDR_MODULUS_COEFF_OUT, a->coeff, a->coeff_len)) != HAL_OK) || (precalc && (err = get_buffer(a->core, MODEXPA7_ADDR_MONTGOMERY_FACTOR_OUT, a->mont, a->mont_len)) != HAL_OK) || (err = set_buffer(a->core, MODEXPA7_ADDR_MODULUS_COEFF_IN, a->coeff, a->coeff_len)) != HAL_OK || (err = set_buffer(a->core, MODEXPA7_ADDR_MONTGOMERY_FACTOR_IN, a->mont, a->mont_len)) != HAL_OK || (err = set_register(a->core, MODEXPA7_ADDR_MODE, mode)) != HAL_OK || (err = set_buffer(a->core, MODEXPA7_ADDR_MESSAGE, a->msg, a->msg_len)) != HAL_OK || (err = set_buffer(a->core, MODEXPA7_ADDR_EXPONENT, a->exp, a->exp_len)) != HAL_OK || (err = set_register(a->core, MODEXPA7_ADDR_EXPONENT_BITS, a->exp_len * 8)) != HAL_OK || (err = hal_io_zero(a->core)) != HAL_OK || (err = hal_io_next(a->core)) != HAL_OK) return err; return HAL_OK; } static inline hal_error_t extract_result(hal_modexp_arg_t *a) { /* * Extract results from the main calculation and we're done. * Hardly seems worth making this a separate function. */ return get_buffer(a->core, MODEXPA7_ADDR_RESULT, a->result, a->mod_len); } /* * Run one modexp operation. */ hal_error_t hal_modexp(const int precalc, hal_modexp_arg_t *a) { hal_error_t err; if ((err = check_args(a)) != HAL_OK) return err; if ((err = hal_core_alloc(MODEXPA7_NAME, &a->core)) == HAL_OK && (err = setup_precalc(precalc, a)) == HAL_OK && (!precalc || (err = hal_io_wait_ready(a->core)) == HAL_OK) && (err = setup_calc(precalc, a)) == HAL_OK && (err = hal_io_wait_valid(a->core)) == HAL_OK && (err = extract_result(a)) == HAL_OK) err = HAL_OK; hal_core_free(a->core); return err; } /* * Run two modexp operations in parallel. */ hal_error_t hal_modexp2(const int precalc, hal_modexp_arg_t *a1, hal_modexp_arg_t *a2) { hal_error_t err; if ((err = check_args(a1)) != HAL_OK || (err = check_args(a2)) != HAL_OK) return err; if ((err = hal_core_alloc2(MODEXPA7_NAME, &a1->core, MODEXPA7_NAME, &a2->core)) == HAL_OK && (err = setup_precalc(precalc, a1)) == HAL_OK && (err = setup_precalc(precalc, a2)) == HAL_OK && (!precalc || (err = hal_io_wait_ready2(a1->core, a2->core)) == HAL_OK) && (err = setup_calc(precalc, a1)) == HAL_OK && (err = setup_calc(precalc, a2)) == HAL_OK && (err = hal_io_wait_valid2(a1->core, a2->core)) == HAL_OK && (err = extract_result(a1)) == HAL_OK && (err = extract_result(a2)) == HAL_OK) err = HAL_OK; hal_core_free(a1->core); hal_core_free(a2->core); return err; } /* * Local variables: * indent-tabs-mode: nil * End: */