xref: /freebsd/crypto/libecc/src/fp/fp_pow.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
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  */
_fp_pow(fp_t out,fp_src_t base,nn_src_t exp)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  */
_fp_pow_aliased(fp_t out,nn_src_t exp)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  */
fp_pow(fp_t out,fp_src_t base,nn_src_t exp)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