1*f0865ec9SKyle Evans /* 2*f0865ec9SKyle Evans * Copyright (C) 2017 - This file is part of libecc project 3*f0865ec9SKyle Evans * 4*f0865ec9SKyle Evans * Authors: 5*f0865ec9SKyle Evans * Ryad BENADJILA <ryadbenadjila@gmail.com> 6*f0865ec9SKyle Evans * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr> 7*f0865ec9SKyle Evans * Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr> 8*f0865ec9SKyle Evans * 9*f0865ec9SKyle Evans * Contributors: 10*f0865ec9SKyle Evans * Nicolas VIVET <nicolas.vivet@ssi.gouv.fr> 11*f0865ec9SKyle Evans * Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr> 12*f0865ec9SKyle Evans * 13*f0865ec9SKyle Evans * This software is licensed under a dual BSD and GPL v2 license. 14*f0865ec9SKyle Evans * See LICENSE file at the root folder of the project. 15*f0865ec9SKyle Evans */ 16*f0865ec9SKyle Evans #include <libecc/nn/nn_logical.h> 17*f0865ec9SKyle Evans #include <libecc/nn/nn_mod_pow.h> 18*f0865ec9SKyle Evans #include <libecc/fp/fp_pow.h> 19*f0865ec9SKyle Evans #include <libecc/fp/fp.h> 20*f0865ec9SKyle Evans 21*f0865ec9SKyle Evans /* 22*f0865ec9SKyle Evans * NOT constant time with regard to the bitlength of exp. 23*f0865ec9SKyle Evans * Aliasing not supported. Expects caller to check parameters 24*f0865ec9SKyle Evans * have been initialized. This is an internal helper. 25*f0865ec9SKyle Evans * 26*f0865ec9SKyle Evans * Returns 0 on success, -1 on error. 27*f0865ec9SKyle Evans */ 28*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _fp_pow(fp_t out, fp_src_t base, nn_src_t exp) 29*f0865ec9SKyle Evans { 30*f0865ec9SKyle Evans /* Use the lower layer modular exponentiation */ 31*f0865ec9SKyle Evans return nn_mod_pow_redc(&(out->fp_val), &(base->fp_val), exp, &(out->ctx->p), &(out->ctx->r), &(out->ctx->r_square), out->ctx->mpinv); 32*f0865ec9SKyle Evans } 33*f0865ec9SKyle Evans 34*f0865ec9SKyle Evans /* 35*f0865ec9SKyle Evans * Same purpose as above but handles aliasing of 'base' and 'out', i.e. 36*f0865ec9SKyle Evans * base is passed via 'out'. Expects caller to check parameters 37*f0865ec9SKyle Evans * have been initialized. This is an internal helper. 38*f0865ec9SKyle Evans */ 39*f0865ec9SKyle Evans ATTRIBUTE_WARN_UNUSED_RET static int _fp_pow_aliased(fp_t out, nn_src_t exp) 40*f0865ec9SKyle Evans { 41*f0865ec9SKyle Evans fp base; 42*f0865ec9SKyle Evans int ret; 43*f0865ec9SKyle Evans base.magic = WORD(0); 44*f0865ec9SKyle Evans 45*f0865ec9SKyle Evans ret = fp_init(&base, out->ctx); EG(ret, err); 46*f0865ec9SKyle Evans ret = fp_copy(&base, out); EG(ret, err); 47*f0865ec9SKyle Evans ret = _fp_pow(out, &base, exp); EG(ret, err); 48*f0865ec9SKyle Evans 49*f0865ec9SKyle Evans err: 50*f0865ec9SKyle Evans fp_uninit(&base); 51*f0865ec9SKyle Evans 52*f0865ec9SKyle Evans return ret; 53*f0865ec9SKyle Evans } 54*f0865ec9SKyle Evans 55*f0865ec9SKyle Evans /* 56*f0865ec9SKyle Evans * Compute out = base^exp (p). 'base', 'exp' and 'out' are supposed to be initialized. 57*f0865ec9SKyle Evans * Aliased version of previous one. 58*f0865ec9SKyle Evans * 59*f0865ec9SKyle Evans * Aliasing is supported. 60*f0865ec9SKyle Evans */ 61*f0865ec9SKyle Evans int fp_pow(fp_t out, fp_src_t base, nn_src_t exp) 62*f0865ec9SKyle Evans { 63*f0865ec9SKyle Evans int ret; 64*f0865ec9SKyle Evans 65*f0865ec9SKyle Evans ret = fp_check_initialized(base); EG(ret, err); 66*f0865ec9SKyle Evans ret = nn_check_initialized(exp); EG(ret, err); 67*f0865ec9SKyle Evans ret = fp_check_initialized(out); EG(ret, err); 68*f0865ec9SKyle Evans MUST_HAVE(((&(out->ctx->p)) == (&(base->ctx->p))), ret, err); 69*f0865ec9SKyle Evans 70*f0865ec9SKyle Evans /* Handle output aliasing */ 71*f0865ec9SKyle Evans if (out == base) { 72*f0865ec9SKyle Evans ret = _fp_pow_aliased(out, exp); 73*f0865ec9SKyle Evans } else { 74*f0865ec9SKyle Evans ret = _fp_pow(out, base, exp); 75*f0865ec9SKyle Evans } 76*f0865ec9SKyle Evans 77*f0865ec9SKyle Evans err: 78*f0865ec9SKyle Evans return ret; 79*f0865ec9SKyle Evans } 80