Remove building with NOCRYPTO option
[minix.git] / crypto / external / bsd / heimdal / dist / lib / hcrypto / libtommath / bn_mp_reduce.c
blobd533bd2d6e8d2f44ac9d8cfa811cffa7ecbea5fb
1 /* $NetBSD: bn_mp_reduce.c,v 1.1.1.2 2014/04/24 12:45:31 pettai Exp $ */
3 #include <tommath.h>
4 #ifdef BN_MP_REDUCE_C
5 /* LibTomMath, multiple-precision integer library -- Tom St Denis
7 * LibTomMath is a library that provides multiple-precision
8 * integer arithmetic as well as number theoretic functionality.
10 * The library was designed directly after the MPI library by
11 * Michael Fromberger but has been written from scratch with
12 * additional optimizations in place.
14 * The library is free for all purposes without any express
15 * guarantee it works.
17 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
20 /* reduces x mod m, assumes 0 < x < m**2, mu is
21 * precomputed via mp_reduce_setup.
22 * From HAC pp.604 Algorithm 14.42
24 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
26 mp_int q;
27 int res, um = m->used;
29 /* q = x */
30 if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
31 return res;
34 /* q1 = x / b**(k-1) */
35 mp_rshd (&q, um - 1);
37 /* according to HAC this optimization is ok */
38 if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
39 if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
40 goto CLEANUP;
42 } else {
43 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
44 if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
45 goto CLEANUP;
47 #elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
48 if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
49 goto CLEANUP;
51 #else
53 res = MP_VAL;
54 goto CLEANUP;
56 #endif
59 /* q3 = q2 / b**(k+1) */
60 mp_rshd (&q, um + 1);
62 /* x = x mod b**(k+1), quick (no division) */
63 if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
64 goto CLEANUP;
67 /* q = q * m mod b**(k+1), quick (no division) */
68 if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
69 goto CLEANUP;
72 /* x = x - q */
73 if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
74 goto CLEANUP;
77 /* If x < 0, add b**(k+1) to it */
78 if (mp_cmp_d (x, 0) == MP_LT) {
79 mp_set (&q, 1);
80 if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
81 goto CLEANUP;
82 if ((res = mp_add (x, &q, x)) != MP_OKAY)
83 goto CLEANUP;
86 /* Back off if it's too big */
87 while (mp_cmp (x, m) != MP_LT) {
88 if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
89 goto CLEANUP;
93 CLEANUP:
94 mp_clear (&q);
96 return res;
98 #endif
100 /* Source: /cvs/libtom/libtommath/bn_mp_reduce.c,v */
101 /* Revision: 1.4 */
102 /* Date: 2006/12/28 01:25:13 */