/ external / libecc / src / nn / nn_modinv.c
nn_modinv.c
  1  /*
  2   *  Copyright (C) 2017 - This file is part of libecc project
  3   *
  4   *  Authors:
  5   *      Ryad BENADJILA <ryadbenadjila@gmail.com>
  6   *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
  7   *      Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
  8   *
  9   *  Contributors:
 10   *      Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
 11   *      Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
 12   *
 13   *  This software is licensed under a dual BSD and GPL v2 license.
 14   *  See LICENSE file at the root folder of the project.
 15   */
 16  #include <libecc/nn/nn_modinv.h>
 17  #include <libecc/nn/nn_div_public.h>
 18  #include <libecc/nn/nn_logical.h>
 19  #include <libecc/nn/nn_add.h>
 20  #include <libecc/nn/nn_mod_pow.h>
 21  #include <libecc/nn/nn.h>
 22  /* Include the "internal" header as we use non public API here */
 23  #include "../nn/nn_mul.h"
 24  
 25  /*
 26   * Compute out = x^-1 mod m, i.e. out such that (out * x) = 1 mod m
 27   * out is initialized by the function, i.e. caller needs not initialize
 28   * it; only provide the associated storage space. Done in *constant
 29   * time* if underlying routines are.
 30   *
 31   * Asserts that m is odd and that x is smaller than m.
 32   * This second condition is not strictly necessary,
 33   * but it allows to perform all operations on nn's of the same length,
 34   * namely the length of m.
 35   *
 36   * Uses a binary xgcd algorithm,
 37   * only keeps track of coefficient for inverting x,
 38   * and performs reduction modulo m at each step.
 39   *
 40   * This does not normalize out on return.
 41   *
 42   * 0 is returned on success (everything went ok and x has reciprocal), -1
 43   * on error or if x has no reciprocal. On error, out is not meaningful.
 44   *
 45   * The function is an internal helper: caller MUST check params have been
 46   * initialized, i.e. this is not done by the function.
 47   *
 48   */
 49  ATTRIBUTE_WARN_UNUSED_RET static int _nn_modinv_odd(nn_t out, nn_src_t x, nn_src_t m)
 50  {
 51  	int isodd, swap, smaller, ret, cmp, iszero, tmp_isodd;
 52  	nn a, b, u, tmp, mp1d2;
 53  	nn_t uu = out;
 54  	bitcnt_t cnt;
 55  	a.magic = b.magic = u.magic = tmp.magic = mp1d2.magic = WORD(0);
 56  
 57  	ret = nn_init(out, 0); EG(ret, err);
 58  	ret = nn_init(&a, (u16)(m->wlen * WORD_BYTES)); EG(ret, err);
 59  	ret = nn_init(&b, (u16)(m->wlen * WORD_BYTES)); EG(ret, err);
 60  	ret = nn_init(&u, (u16)(m->wlen * WORD_BYTES)); EG(ret, err);
 61  	ret = nn_init(&mp1d2, (u16)(m->wlen * WORD_BYTES)); EG(ret, err);
 62  	/*
 63  	 * Temporary space needed to only deal with positive stuff.
 64  	 */
 65  	ret = nn_init(&tmp, (u16)(m->wlen * WORD_BYTES)); EG(ret, err);
 66  
 67  	MUST_HAVE((!nn_isodd(m, &isodd)) && isodd, ret, err);
 68  	MUST_HAVE((!nn_cmp(x, m, &cmp)) && (cmp < 0), ret, err);
 69  	MUST_HAVE((!nn_iszero(x, &iszero)) && (!iszero), ret, err);
 70  
 71  	/*
 72  	 * Maintain:
 73  	 *
 74  	 * a = u * x (mod m)
 75  	 * b = uu * x (mod m)
 76  	 *
 77  	 * and b odd at all times. Initially,
 78  	 *
 79  	 * a = x, u = 1
 80  	 * b = m, uu = 0
 81  	 */
 82  	ret = nn_copy(&a, x); EG(ret, err);
 83  	ret = nn_set_wlen(&a, m->wlen); EG(ret, err);
 84  	ret = nn_copy(&b, m); EG(ret, err);
 85  	ret = nn_one(&u); EG(ret, err);
 86  	ret = nn_zero(uu); EG(ret, err);
 87  
 88  	/*
 89  	 * The lengths of u and uu should not affect constant timeness but it
 90  	 * does not hurt to set them already.
 91  	 * They will always be strictly smaller than m.
 92  	 */
 93  	ret = nn_set_wlen(&u, m->wlen); EG(ret, err);
 94  	ret = nn_set_wlen(uu, m->wlen); EG(ret, err);
 95  
 96  	/*
 97  	 * Precompute inverse of 2 mod m:
 98  	 *	2^-1 = (m+1)/2
 99  	 * computed as (m >> 1) + 1.
100  	 */
101  	ret = nn_rshift_fixedlen(&mp1d2, m, 1); EG(ret, err);
102  
103  	ret = nn_inc(&mp1d2, &mp1d2); EG(ret, err); /* no carry can occur here
104  						       because of prev. shift */
105  
106  	cnt = (bitcnt_t)((a.wlen + b.wlen) * WORD_BITS);
107  	while (cnt > 0) {
108  		cnt = (bitcnt_t)(cnt - 1);
109  		/*
110  		 * Always maintain b odd. The logic of the iteration is as
111  		 * follows.
112  		 */
113  
114  		/*
115  		 * For a, b:
116  		 *
117  		 * odd = a & 1
118  		 * swap = odd & (a < b)
119  		 * if (swap)
120  		 *      swap(a, b)
121  		 * if (odd)
122  		 *      a -= b
123  		 * a /= 2
124  		 */
125  
126  		MUST_HAVE((!nn_isodd(&b, &tmp_isodd)) && tmp_isodd, ret, err);
127  
128  		ret = nn_isodd(&a, &isodd); EG(ret, err);
129  		ret = nn_cmp(&a, &b, &cmp); EG(ret, err);
130  		swap = isodd & (cmp == -1);
131  
132  		ret = nn_cnd_swap(swap, &a, &b); EG(ret, err);
133  		ret = nn_cnd_sub(isodd, &a, &a, &b); EG(ret, err);
134  
135  		MUST_HAVE((!nn_isodd(&a, &tmp_isodd)) && (!tmp_isodd), ret, err); /* a is now even */
136  
137  		ret = nn_rshift_fixedlen(&a, &a, 1);  EG(ret, err);/* division by 2 */
138  
139  		/*
140  		 * For u, uu:
141  		 *
142  		 * if (swap)
143  		 *      swap u, uu
144  		 * smaller = (u < uu)
145  		 * if (odd)
146  		 *      if (smaller)
147  		 *              u += m - uu
148  		 *      else
149  		 *              u -= uu
150  		 * u >>= 1
151  		 * if (u was odd)
152  		 *      u += (m+1)/2
153  		 */
154  		ret = nn_cnd_swap(swap, &u, uu); EG(ret, err);
155  
156  		/* This parameter is used to avoid handling negative numbers. */
157  		ret = nn_cmp(&u, uu, &cmp); EG(ret, err);
158  		smaller = (cmp == -1);
159  
160  		/* Computation of 'm - uu' can always be performed. */
161  		ret = nn_sub(&tmp, m, uu); EG(ret, err);
162  
163  		/* Selection btw 'm-uu' and '-uu' is made by the following function calls. */
164  		ret = nn_cnd_add(isodd & smaller, &u, &u, &tmp); EG(ret, err); /* no carry can occur as 'u+(m-uu) = m-(uu-u) < m' */
165  		ret = nn_cnd_sub(isodd & (!smaller), &u, &u, uu); EG(ret, err);
166  
167  		/* Divide u by 2 */
168  		ret = nn_isodd(&u, &isodd); EG(ret, err);
169  		ret = nn_rshift_fixedlen(&u, &u, 1); EG(ret, err);
170  		ret = nn_cnd_add(isodd, &u, &u, &mp1d2); EG(ret, err); /* no carry can occur as u=1+u' with u'<m-1 and u' even so u'/2+(m+1)/2<(m-1)/2+(m+1)/2=m */
171  
172  		MUST_HAVE((!nn_cmp(&u, m, &cmp)) && (cmp < 0), ret, err);
173  		MUST_HAVE((!nn_cmp(uu, m, &cmp)) && (cmp < 0), ret, err);
174  
175  		/*
176  		 * As long as a > 0, the quantity
177  		 * (bitsize of a) + (bitsize of b)
178  		 * is reduced by at least one bit per iteration,
179  		 * hence after (bitsize of x) + (bitsize of m) - 1
180  		 * iterations we surely have a = 0. Then b = gcd(x, m)
181  		 * and if b = 1 then also uu = x^{-1} (mod m).
182  		 */
183  	}
184  
185  	MUST_HAVE((!nn_iszero(&a, &iszero)) && iszero, ret, err);
186  
187  	/* Check that gcd is one. */
188  	ret = nn_cmp_word(&b, WORD(1), &cmp); EG(ret, err);
189  
190  	/* If not, set "inverse" to zero. */
191  	ret = nn_cnd_sub(cmp != 0, uu, uu, uu); EG(ret, err);
192  
193  	ret = cmp ? -1 : 0;
194  
195  err:
196  	nn_uninit(&a);
197  	nn_uninit(&b);
198  	nn_uninit(&u);
199  	nn_uninit(&mp1d2);
200  	nn_uninit(&tmp);
201  
202  	PTR_NULLIFY(uu);
203  
204  	return ret;
205  }
206  
207  /*
208   * Same as above without restriction on m.
209   * No attempt to make it constant time.
210   * Uses the above constant-time binary xgcd when m is odd
211   * and a not constant time plain Euclidean xgcd when m is even.
212   *
213   * _out parameter need not be initialized; this will be done by the function.
214   * x and m must be initialized nn.
215   *
216   * Return -1 on error or if if x has no reciprocal modulo m. out is zeroed.
217   * Return  0 if x has reciprocal modulo m.
218   *
219   * The function supports aliasing.
220   */
221  int nn_modinv(nn_t _out, nn_src_t x, nn_src_t m)
222  {
223  	int sign, ret, cmp, isodd, isone;
224  	nn_t x_mod_m;
225  	nn u, v, out; /* Out to support aliasing */
226  	out.magic = u.magic = v.magic = WORD(0);
227  
228  	ret = nn_check_initialized(x); EG(ret, err);
229  	ret = nn_check_initialized(m); EG(ret, err);
230  
231  	/* Initialize out */
232  	ret = nn_init(&out, 0); EG(ret, err);
233  	ret = nn_isodd(m, &isodd); EG(ret, err);
234  	if (isodd) {
235  		ret = nn_cmp(x, m, &cmp); EG(ret, err);
236  		if (cmp >= 0) {
237  			/*
238  			 * If x >= m, (x^-1) mod m = ((x mod m)^-1) mod m
239  			 * Hence, compute x mod m. In order to avoid
240  			 * additional stack usage, we use 'u' (not
241  			 * already useful at that point in the function).
242  			 */
243  			x_mod_m = &u;
244  			ret = nn_mod(x_mod_m, x, m); EG(ret, err);
245  			ret = _nn_modinv_odd(&out, x_mod_m, m); EG(ret, err);
246  		} else {
247  			ret = _nn_modinv_odd(&out, x, m); EG(ret, err);
248  		}
249  		ret = nn_copy(_out, &out);
250  		goto err;
251  	}
252  
253  	/* Now m is even */
254  	ret = nn_isodd(x, &isodd); EG(ret, err);
255  	MUST_HAVE(isodd, ret, err);
256  
257  	ret = nn_init(&u, 0); EG(ret, err);
258  	ret = nn_init(&v, 0); EG(ret, err);
259  	ret = nn_xgcd(&out, &u, &v, x, m, &sign); EG(ret, err);
260  	ret = nn_isone(&out, &isone); EG(ret, err);
261  	MUST_HAVE(isone, ret, err);
262  
263  	ret = nn_mod(&out, &u, m); EG(ret, err);
264  	if (sign == -1) {
265  		ret = nn_sub(&out, m, &out); EG(ret, err);
266  	}
267  	ret = nn_copy(_out, &out);
268  
269  err:
270  	nn_uninit(&out);
271  	nn_uninit(&u);
272  	nn_uninit(&v);
273  
274  	PTR_NULLIFY(x_mod_m);
275  
276  	return ret;
277  }
278  
279  /*
280   * Compute (A - B) % 2^(storagebitsizeof(B) + 1). A and B must be initialized nn.
281   * the function is an internal helper and does not verify params have been
282   * initialized; this must be done by the caller. No assumption on A and B values
283   * such as A >= B. Done in *constant time. Returns 0 on success, -1 on error.
284   */
285  ATTRIBUTE_WARN_UNUSED_RET static inline int _nn_sub_mod_2exp(nn_t A, nn_src_t B)
286  {
287  	u8 Awlen = A->wlen;
288  	int ret;
289  
290  	ret = nn_set_wlen(A, (u8)(Awlen + 1)); EG(ret, err);
291  
292  	/* Make sure A > B */
293  	/* NOTE: A->wlen - 1 is not an issue here thant to the nn_set_wlen above */
294  	A->val[A->wlen - 1] = WORD(1);
295  	ret = nn_sub(A, A, B); EG(ret, err);
296  
297  	/* The artificial word will be cleared in the following function call */
298  	ret = nn_set_wlen(A, Awlen);
299  
300  err:
301  	return ret;
302  }
303  
304  /*
305   * Invert x modulo 2^exp using Hensel lifting. Returns 0 on success, -1 on
306   * error. On success, x_isodd is 1 if x is odd, 0 if it is even.
307   * Please note that the result is correct (inverse of x) only when x is prime
308   * to 2^exp, i.e. x is odd (x_odd is 1).
309   *
310   * Operations are done in *constant time*.
311   *
312   * Aliasing is supported.
313   */
314  int nn_modinv_2exp(nn_t _out, nn_src_t x, bitcnt_t exp, int *x_isodd)
315  {
316  	bitcnt_t cnt;
317  	u8 exp_wlen = (u8)BIT_LEN_WORDS(exp);
318  	bitcnt_t exp_cnt = exp % WORD_BITS;
319  	word_t mask = (word_t)((exp_cnt == 0) ? WORD_MASK : (word_t)((WORD(1) << exp_cnt) - WORD(1)));
320  	nn tmp_sqr, tmp_mul;
321  	/* for aliasing */
322  	int isodd, ret;
323  	nn out;
324  	out.magic = tmp_sqr.magic = tmp_mul.magic = WORD(0);
325  
326  	MUST_HAVE((x_isodd != NULL), ret, err);
327  	ret = nn_check_initialized(x); EG(ret, err);
328  	ret = nn_check_initialized(_out); EG(ret, err);
329  
330  	ret = nn_init(&out, 0); EG(ret, err);
331  	ret = nn_init(&tmp_sqr, 0); EG(ret, err);
332  	ret = nn_init(&tmp_mul, 0); EG(ret, err);
333  	ret = nn_isodd(x, &isodd); EG(ret, err);
334  	if (exp == (bitcnt_t)0){
335  		/* Specific case of zero exponent, output 0 */
336  		(*x_isodd) = isodd;
337  		goto err;
338  	}
339  	if (!isodd) {
340  		ret = nn_zero(_out); EG(ret, err);
341  		(*x_isodd) = 0;
342  		goto err;
343  	}
344  
345  	/*
346  	 * Inverse modulo 2.
347  	 */
348  	cnt = 1;
349  	ret = nn_one(&out); EG(ret, err);
350  
351  	/*
352  	 * Inverse modulo 2^(2^i) <= 2^WORD_BITS.
353  	 * Assumes WORD_BITS is a power of two.
354  	 */
355  	for (; cnt < WORD_MIN(WORD_BITS, exp); cnt = (bitcnt_t)(cnt << 1)) {
356  		ret = nn_sqr_low(&tmp_sqr, &out, out.wlen); EG(ret, err);
357  		ret = nn_mul_low(&tmp_mul, &tmp_sqr, x, out.wlen); EG(ret, err);
358  		ret = nn_lshift_fixedlen(&out, &out, 1); EG(ret, err);
359  
360  		/*
361  		 * Allowing "negative" results for a subtraction modulo
362  		 * a power of two would allow to use directly:
363  		 * nn_sub(out, out, tmp_mul)
364  		 * which is always negative in ZZ except when x is one.
365  		 *
366  		 * Another solution is to add the opposite of tmp_mul.
367  		 * nn_modopp_2exp(tmp_mul, tmp_mul);
368  		 * nn_add(out, out, tmp_mul);
369  		 *
370  		 * The current solution is to add a sufficiently large power
371  		 * of two to out unconditionally to absorb the potential
372  		 * borrow. The result modulo 2^(2^i) is correct whether the
373  		 * borrow occurs or not.
374  		 */
375  		ret = _nn_sub_mod_2exp(&out, &tmp_mul); EG(ret, err);
376  	}
377  
378  	/*
379  	 * Inverse modulo 2^WORD_BITS < 2^(2^i) < 2^exp.
380  	 */
381  	for (; cnt < ((exp + 1) >> 1); cnt = (bitcnt_t)(cnt << 1)) {
382  		ret = nn_set_wlen(&out, (u8)(2 * out.wlen)); EG(ret, err);
383  		ret = nn_sqr_low(&tmp_sqr, &out, out.wlen); EG(ret, err);
384  		ret = nn_mul_low(&tmp_mul, &tmp_sqr, x, out.wlen); EG(ret, err);
385  		ret = nn_lshift_fixedlen(&out, &out, 1); EG(ret, err);
386  		ret = _nn_sub_mod_2exp(&out, &tmp_mul); EG(ret, err);
387  	}
388  
389  	/*
390  	 * Inverse modulo 2^(2^i + j) >= 2^exp.
391  	 */
392  	if (exp > WORD_BITS) {
393  		ret = nn_set_wlen(&out, exp_wlen); EG(ret, err);
394  		ret = nn_sqr_low(&tmp_sqr, &out, out.wlen); EG(ret, err);
395  		ret = nn_mul_low(&tmp_mul, &tmp_sqr, x, out.wlen); EG(ret, err);
396  		ret = nn_lshift_fixedlen(&out, &out, 1); EG(ret, err);
397  		ret = _nn_sub_mod_2exp(&out, &tmp_mul); EG(ret, err);
398  	}
399  
400  	/*
401  	 * Inverse modulo 2^exp.
402  	 */
403  	out.val[exp_wlen - 1] &= mask;
404  
405  	ret = nn_copy(_out, &out); EG(ret, err);
406  
407  	(*x_isodd) = 1;
408  
409  err:
410  	nn_uninit(&out);
411  	nn_uninit(&tmp_sqr);
412  	nn_uninit(&tmp_mul);
413  
414  	return ret;
415  }
416  
417  /*
418   * Invert word w modulo m.
419   *
420   * The function supports aliasing.
421   */
422  int nn_modinv_word(nn_t out, word_t w, nn_src_t m)
423  {
424  	nn nn_tmp;
425  	int ret;
426  	nn_tmp.magic = WORD(0);
427  
428  	ret = nn_init(&nn_tmp, 0); EG(ret, err);
429  	ret = nn_set_word_value(&nn_tmp, w); EG(ret, err);
430  	ret = nn_modinv(out, &nn_tmp, m);
431  
432  err:
433  	nn_uninit(&nn_tmp);
434  
435  	return ret;
436  }
437  
438  
439  /*
440   * Internal function for nn_modinv_fermat and nn_modinv_fermat_redc used
441   * hereafter.
442   */
443  ATTRIBUTE_WARN_UNUSED_RET static int _nn_modinv_fermat_common(nn_t out, nn_src_t x, nn_src_t p, nn_t p_minus_two, int *lesstwo)
444  {
445  	int ret, cmp, isodd;
446  	nn two;
447  	two.magic = WORD(0);
448  
449  	/* Sanity checks on inputs */
450  	ret = nn_check_initialized(x); EG(ret, err);
451  	ret = nn_check_initialized(p); EG(ret, err);
452  	/* NOTE: since this is an internal function, we are ensured that p_minus_two,
453  	 * two and regular are OK.
454  	 */
455  
456  	/* 0 is not invertible in any case */
457  	ret = nn_iszero(x, &cmp); EG(ret, err);
458  	if(cmp){
459  		/* Zero the output and return an error */
460  		ret = nn_init(out, 0); EG(ret, err);
461  		ret = nn_zero(out); EG(ret, err);
462  		ret = -1;
463  		goto err;
464  	}
465  
466  	/* For p <= 2, p being prime either p = 1 or p = 2.
467  	 * When p = 2, only 1 has an inverse, if p = 1 no one has an inverse.
468  	 */
469  	(*lesstwo) = 0;
470  	ret = nn_cmp_word(p, WORD(2), &cmp); EG(ret, err);
471          if(cmp == 0){
472  		/* This is the p = 2 case, parity of x provides the result */
473  		ret = nn_isodd(x, &isodd); EG(ret, err);
474  		if(isodd){
475  			/* x is odd, 1 is its inverse */
476  			ret = nn_init(out, 0); EG(ret, err);
477  			ret = nn_one(out); EG(ret, err);
478  			ret = 0;
479  		}
480  		else{
481  			/* x is even, no inverse. Zero the output */
482  			ret = nn_init(out, 0); EG(ret, err);
483  			ret = nn_zero(out); EG(ret, err);
484  			ret = -1;
485  		}
486  		(*lesstwo) = 1;
487  		goto err;
488          } else if (cmp < 0){
489  		/* This is the p = 1 case, no inverse here: hence return an error */
490  		/* Zero the output */
491  		ret = nn_init(out, 0); EG(ret, err);
492  		ret = nn_zero(out); EG(ret, err);
493  		ret = -1;
494  		(*lesstwo) = 1;
495  		goto err;
496  	}
497  
498  	/* Else we compute (p-2) for the upper layer */
499  	if(p != p_minus_two){
500  		/* Handle aliasing of p and p_minus_two */
501  		ret = nn_init(p_minus_two, 0); EG(ret, err);
502  	}
503  
504  	ret = nn_init(&two, 0); EG(ret, err);
505  	ret = nn_set_word_value(&two, WORD(2)); EG(ret, err);
506  	ret = nn_sub(p_minus_two, p, &two);
507  
508  err:
509  	nn_uninit(&two);
510  
511  	return ret;
512  }
513  
514  /*
515   * Invert NN x modulo p using Fermat's little theorem for our inversion:
516   *
517   *    p prime means that:
518   *    x^(p-1) = 1 mod (p)
519   *    which means that x^(p-2) mod(p) is the modular inverse of x mod (p)
520   *    for x != 0
521   *
522   * NOTE: the input hypothesis is that p is prime.
523   * XXX WARNING: using this function with p not prime will produce wrong
524   * results without triggering an error!
525   *
526   * The function returns 0 on success, -1 on error
527   * (e.g. if x has no inverse modulo p, i.e. x = 0).
528   *
529   * Aliasing is supported.
530   */
531  int nn_modinv_fermat(nn_t out, nn_src_t x, nn_src_t p)
532  {
533  	int ret, lesstwo;
534  	nn p_minus_two;
535  	p_minus_two.magic = WORD(0);
536  
537  	/* Call our helper.
538  	 * NOTE: "marginal" cases where x = 0 and p <= 2 should be caught in this helper.
539  	 */
540  	ret = _nn_modinv_fermat_common(out, x, p, &p_minus_two, &lesstwo); EG(ret, err);
541  
542  	if(!lesstwo){
543  		/* Compute x^(p-2) mod (p) */
544  		ret = nn_mod_pow(out, x, &p_minus_two, p);
545  	}
546  
547  err:
548  	nn_uninit(&p_minus_two);
549  
550  	return ret;
551  }
552  
553  /*
554   * Invert NN x modulo m using Fermat's little theorem for our inversion.
555   *
556   * This is a version with already (pre)computed Montgomery coefficients.
557   *
558   * NOTE: the input hypothesis is that p is prime.
559   * XXX WARNING: using this function with p not prime will produce wrong
560   * results without triggering an error!
561   *
562   * The function returns 0 on success, -1 on error
563   * (e.g. if x has no inverse modulo p, i.e. x = 0).
564   *
565   * Aliasing is supported.
566   */
567  int nn_modinv_fermat_redc(nn_t out, nn_src_t x, nn_src_t p, nn_src_t r, nn_src_t r_square, word_t mpinv)
568  {
569  	int ret, lesstwo;
570  	nn p_minus_two;
571  	p_minus_two.magic = WORD(0);
572  
573  	/* Call our helper.
574  	 * NOTE: "marginal" cases where x = 0 and p <= 2 should be caught in this helper.
575  	 */
576  	ret = _nn_modinv_fermat_common(out, x, p, &p_minus_two, &lesstwo); EG(ret, err);
577  
578  	if(!lesstwo){
579  		/* Compute x^(p-2) mod (p) using precomputed Montgomery coefficients as input */
580  		ret = nn_mod_pow_redc(out, x, &p_minus_two, p, r, r_square, mpinv);
581  	}
582  
583  err:
584  	nn_uninit(&p_minus_two);
585  
586  	return ret;
587  }