Mercurial > dropbear
comparison libtommath/bn_mp_kronecker.c @ 1655:f52919ffd3b1
update ltm to 1.1.0 and enable FIPS 186.4 compliant key-generation (#79)
* make key-generation compliant to FIPS 186.4
* fix includes in tommath_class.h
* update fuzzcorpus instead of error-out
* fixup fuzzing make-targets
* update Makefile.in
* apply necessary patches to ltm sources
* clean-up not required ltm files
* update to vanilla ltm 1.1.0
this already only contains the required files
* remove set/get double
author | Steffen Jaeckel <s_jaeckel@gmx.de> |
---|---|
date | Mon, 16 Sep 2019 15:50:38 +0200 |
parents | |
children | 1051e4eea25a |
comparison
equal
deleted
inserted
replaced
1654:cc0fc5131c5c | 1655:f52919ffd3b1 |
---|---|
1 #include "tommath_private.h" | |
2 #ifdef BN_MP_KRONECKER_C | |
3 | |
4 /* LibTomMath, multiple-precision integer library -- Tom St Denis | |
5 * | |
6 * LibTomMath is a library that provides multiple-precision | |
7 * integer arithmetic as well as number theoretic functionality. | |
8 * | |
9 * The library was designed directly after the MPI library by | |
10 * Michael Fromberger but has been written from scratch with | |
11 * additional optimizations in place. | |
12 * | |
13 * SPDX-License-Identifier: Unlicense | |
14 */ | |
15 | |
16 /* | |
17 Kronecker symbol (a|p) | |
18 Straightforward implementation of algorithm 1.4.10 in | |
19 Henri Cohen: "A Course in Computational Algebraic Number Theory" | |
20 | |
21 @book{cohen2013course, | |
22 title={A course in computational algebraic number theory}, | |
23 author={Cohen, Henri}, | |
24 volume={138}, | |
25 year={2013}, | |
26 publisher={Springer Science \& Business Media} | |
27 } | |
28 */ | |
29 int mp_kronecker(const mp_int *a, const mp_int *p, int *c) | |
30 { | |
31 mp_int a1, p1, r; | |
32 | |
33 int e = MP_OKAY; | |
34 int v, k; | |
35 | |
36 static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; | |
37 | |
38 if (mp_iszero(p) != MP_NO) { | |
39 if ((a->used == 1) && (a->dp[0] == 1u)) { | |
40 *c = 1; | |
41 return e; | |
42 } else { | |
43 *c = 0; | |
44 return e; | |
45 } | |
46 } | |
47 | |
48 if ((mp_iseven(a) != MP_NO) && (mp_iseven(p) != MP_NO)) { | |
49 *c = 0; | |
50 return e; | |
51 } | |
52 | |
53 if ((e = mp_init_copy(&a1, a)) != MP_OKAY) { | |
54 return e; | |
55 } | |
56 if ((e = mp_init_copy(&p1, p)) != MP_OKAY) { | |
57 goto LBL_KRON_0; | |
58 } | |
59 | |
60 v = mp_cnt_lsb(&p1); | |
61 if ((e = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { | |
62 goto LBL_KRON_1; | |
63 } | |
64 | |
65 if ((v & 0x1) == 0) { | |
66 k = 1; | |
67 } else { | |
68 k = table[a->dp[0] & 7u]; | |
69 } | |
70 | |
71 if (p1.sign == MP_NEG) { | |
72 p1.sign = MP_ZPOS; | |
73 if (a1.sign == MP_NEG) { | |
74 k = -k; | |
75 } | |
76 } | |
77 | |
78 if ((e = mp_init(&r)) != MP_OKAY) { | |
79 goto LBL_KRON_1; | |
80 } | |
81 | |
82 for (;;) { | |
83 if (mp_iszero(&a1) != MP_NO) { | |
84 if (mp_cmp_d(&p1, 1uL) == MP_EQ) { | |
85 *c = k; | |
86 goto LBL_KRON; | |
87 } else { | |
88 *c = 0; | |
89 goto LBL_KRON; | |
90 } | |
91 } | |
92 | |
93 v = mp_cnt_lsb(&a1); | |
94 if ((e = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { | |
95 goto LBL_KRON; | |
96 } | |
97 | |
98 if ((v & 0x1) == 1) { | |
99 k = k * table[p1.dp[0] & 7u]; | |
100 } | |
101 | |
102 if (a1.sign == MP_NEG) { | |
103 /* | |
104 * Compute k = (-1)^((a1)*(p1-1)/4) * k | |
105 * a1.dp[0] + 1 cannot overflow because the MSB | |
106 * of the type mp_digit is not set by definition | |
107 */ | |
108 if (((a1.dp[0] + 1u) & p1.dp[0] & 2u) != 0u) { | |
109 k = -k; | |
110 } | |
111 } else { | |
112 /* compute k = (-1)^((a1-1)*(p1-1)/4) * k */ | |
113 if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) { | |
114 k = -k; | |
115 } | |
116 } | |
117 | |
118 if ((e = mp_copy(&a1, &r)) != MP_OKAY) { | |
119 goto LBL_KRON; | |
120 } | |
121 r.sign = MP_ZPOS; | |
122 if ((e = mp_mod(&p1, &r, &a1)) != MP_OKAY) { | |
123 goto LBL_KRON; | |
124 } | |
125 if ((e = mp_copy(&r, &p1)) != MP_OKAY) { | |
126 goto LBL_KRON; | |
127 } | |
128 } | |
129 | |
130 LBL_KRON: | |
131 mp_clear(&r); | |
132 LBL_KRON_1: | |
133 mp_clear(&p1); | |
134 LBL_KRON_0: | |
135 mp_clear(&a1); | |
136 | |
137 return e; | |
138 } | |
139 | |
140 #endif | |
141 | |
142 /* ref: HEAD -> master, tag: v1.1.0 */ | |
143 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */ | |
144 /* commit time: 2019-01-28 20:32:32 +0100 */ |