Mercurial > dropbear
comparison libtommath/bn_mp_kronecker.c @ 1692:1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
* update C files
* update other files
* update headers
* update makefiles
* remove mp_set/get_double()
* use ltm 1.2.0 API
* update ltm_desc
* use bundled tommath if system-tommath is too old
* XMALLOC etc. were changed to MP_MALLOC etc.
author | Steffen Jaeckel <s@jaeckel.eu> |
---|---|
date | Tue, 26 May 2020 17:36:47 +0200 |
parents | f52919ffd3b1 |
children |
comparison
equal
deleted
inserted
replaced
1691:2d3745d58843 | 1692:1051e4eea25a |
---|---|
1 #include "tommath_private.h" | 1 #include "tommath_private.h" |
2 #ifdef BN_MP_KRONECKER_C | 2 #ifdef BN_MP_KRONECKER_C |
3 | 3 |
4 /* LibTomMath, multiple-precision integer library -- Tom St Denis | 4 /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
5 * | 5 /* SPDX-License-Identifier: Unlicense */ |
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 | 6 |
16 /* | 7 /* |
17 Kronecker symbol (a|p) | 8 Kronecker symbol (a|p) |
18 Straightforward implementation of algorithm 1.4.10 in | 9 Straightforward implementation of algorithm 1.4.10 in |
19 Henri Cohen: "A Course in Computational Algebraic Number Theory" | 10 Henri Cohen: "A Course in Computational Algebraic Number Theory" |
24 volume={138}, | 15 volume={138}, |
25 year={2013}, | 16 year={2013}, |
26 publisher={Springer Science \& Business Media} | 17 publisher={Springer Science \& Business Media} |
27 } | 18 } |
28 */ | 19 */ |
29 int mp_kronecker(const mp_int *a, const mp_int *p, int *c) | 20 mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) |
30 { | 21 { |
31 mp_int a1, p1, r; | 22 mp_int a1, p1, r; |
32 | 23 mp_err err; |
33 int e = MP_OKAY; | |
34 int v, k; | 24 int v, k; |
35 | 25 |
36 static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; | 26 static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; |
37 | 27 |
38 if (mp_iszero(p) != MP_NO) { | 28 if (MP_IS_ZERO(p)) { |
39 if ((a->used == 1) && (a->dp[0] == 1u)) { | 29 if ((a->used == 1) && (a->dp[0] == 1u)) { |
40 *c = 1; | 30 *c = 1; |
41 return e; | |
42 } else { | 31 } else { |
43 *c = 0; | 32 *c = 0; |
44 return e; | |
45 } | 33 } |
34 return MP_OKAY; | |
46 } | 35 } |
47 | 36 |
48 if ((mp_iseven(a) != MP_NO) && (mp_iseven(p) != MP_NO)) { | 37 if (MP_IS_EVEN(a) && MP_IS_EVEN(p)) { |
49 *c = 0; | 38 *c = 0; |
50 return e; | 39 return MP_OKAY; |
51 } | 40 } |
52 | 41 |
53 if ((e = mp_init_copy(&a1, a)) != MP_OKAY) { | 42 if ((err = mp_init_copy(&a1, a)) != MP_OKAY) { |
54 return e; | 43 return err; |
55 } | 44 } |
56 if ((e = mp_init_copy(&p1, p)) != MP_OKAY) { | 45 if ((err = mp_init_copy(&p1, p)) != MP_OKAY) { |
57 goto LBL_KRON_0; | 46 goto LBL_KRON_0; |
58 } | 47 } |
59 | 48 |
60 v = mp_cnt_lsb(&p1); | 49 v = mp_cnt_lsb(&p1); |
61 if ((e = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { | 50 if ((err = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { |
62 goto LBL_KRON_1; | 51 goto LBL_KRON_1; |
63 } | 52 } |
64 | 53 |
65 if ((v & 0x1) == 0) { | 54 if ((v & 1) == 0) { |
66 k = 1; | 55 k = 1; |
67 } else { | 56 } else { |
68 k = table[a->dp[0] & 7u]; | 57 k = table[a->dp[0] & 7u]; |
69 } | 58 } |
70 | 59 |
73 if (a1.sign == MP_NEG) { | 62 if (a1.sign == MP_NEG) { |
74 k = -k; | 63 k = -k; |
75 } | 64 } |
76 } | 65 } |
77 | 66 |
78 if ((e = mp_init(&r)) != MP_OKAY) { | 67 if ((err = mp_init(&r)) != MP_OKAY) { |
79 goto LBL_KRON_1; | 68 goto LBL_KRON_1; |
80 } | 69 } |
81 | 70 |
82 for (;;) { | 71 for (;;) { |
83 if (mp_iszero(&a1) != MP_NO) { | 72 if (MP_IS_ZERO(&a1)) { |
84 if (mp_cmp_d(&p1, 1uL) == MP_EQ) { | 73 if (mp_cmp_d(&p1, 1uL) == MP_EQ) { |
85 *c = k; | 74 *c = k; |
86 goto LBL_KRON; | 75 goto LBL_KRON; |
87 } else { | 76 } else { |
88 *c = 0; | 77 *c = 0; |
89 goto LBL_KRON; | 78 goto LBL_KRON; |
90 } | 79 } |
91 } | 80 } |
92 | 81 |
93 v = mp_cnt_lsb(&a1); | 82 v = mp_cnt_lsb(&a1); |
94 if ((e = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { | 83 if ((err = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { |
95 goto LBL_KRON; | 84 goto LBL_KRON; |
96 } | 85 } |
97 | 86 |
98 if ((v & 0x1) == 1) { | 87 if ((v & 1) == 1) { |
99 k = k * table[p1.dp[0] & 7u]; | 88 k = k * table[p1.dp[0] & 7u]; |
100 } | 89 } |
101 | 90 |
102 if (a1.sign == MP_NEG) { | 91 if (a1.sign == MP_NEG) { |
103 /* | 92 /* |
113 if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) { | 102 if ((a1.dp[0] & p1.dp[0] & 2u) != 0u) { |
114 k = -k; | 103 k = -k; |
115 } | 104 } |
116 } | 105 } |
117 | 106 |
118 if ((e = mp_copy(&a1, &r)) != MP_OKAY) { | 107 if ((err = mp_copy(&a1, &r)) != MP_OKAY) { |
119 goto LBL_KRON; | 108 goto LBL_KRON; |
120 } | 109 } |
121 r.sign = MP_ZPOS; | 110 r.sign = MP_ZPOS; |
122 if ((e = mp_mod(&p1, &r, &a1)) != MP_OKAY) { | 111 if ((err = mp_mod(&p1, &r, &a1)) != MP_OKAY) { |
123 goto LBL_KRON; | 112 goto LBL_KRON; |
124 } | 113 } |
125 if ((e = mp_copy(&r, &p1)) != MP_OKAY) { | 114 if ((err = mp_copy(&r, &p1)) != MP_OKAY) { |
126 goto LBL_KRON; | 115 goto LBL_KRON; |
127 } | 116 } |
128 } | 117 } |
129 | 118 |
130 LBL_KRON: | 119 LBL_KRON: |
132 LBL_KRON_1: | 121 LBL_KRON_1: |
133 mp_clear(&p1); | 122 mp_clear(&p1); |
134 LBL_KRON_0: | 123 LBL_KRON_0: |
135 mp_clear(&a1); | 124 mp_clear(&a1); |
136 | 125 |
137 return e; | 126 return err; |
138 } | 127 } |
139 | 128 |
140 #endif | 129 #endif |
141 | |
142 /* ref: HEAD -> master, tag: v1.1.0 */ | |
143 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */ | |
144 /* commit time: 2019-01-28 20:32:32 +0100 */ |