comparison libtommath/bn_mp_toom_sqr.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 8bba51a55704
children
comparison
equal deleted inserted replaced
1654:cc0fc5131c5c 1655:f52919ffd3b1
1 #include <tommath_private.h> 1 #include "tommath_private.h"
2 #ifdef BN_MP_TOOM_SQR_C 2 #ifdef BN_MP_TOOM_SQR_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis 3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
4 * 4 *
5 * LibTomMath is a library that provides multiple-precision 5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality. 6 * integer arithmetic as well as number theoretic functionality.
7 * 7 *
8 * The library was designed directly after the MPI library by 8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with 9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place. 10 * additional optimizations in place.
11 * 11 *
12 * The library is free for all purposes without any express 12 * SPDX-License-Identifier: Unlicense
13 * guarantee it works.
14 *
15 * Tom St Denis, [email protected], http://libtom.org
16 */ 13 */
17 14
18 /* squaring using Toom-Cook 3-way algorithm */ 15 /* squaring using Toom-Cook 3-way algorithm */
19 int 16 int mp_toom_sqr(const mp_int *a, mp_int *b)
20 mp_toom_sqr(mp_int *a, mp_int *b)
21 { 17 {
22 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; 18 mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
23 int res, B; 19 int res, B;
24 20
25 /* init temps */ 21 /* init temps */
26 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { 22 if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
27 return res; 23 return res;
28 } 24 }
29 25
30 /* B */ 26 /* B */
31 B = a->used / 3; 27 B = a->used / 3;
32 28
33 /* a = a2 * B**2 + a1 * B + a0 */ 29 /* a = a2 * B**2 + a1 * B + a0 */
34 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { 30 if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
35 goto ERR; 31 goto LBL_ERR;
36 } 32 }
37 33
38 if ((res = mp_copy(a, &a1)) != MP_OKAY) { 34 if ((res = mp_copy(a, &a1)) != MP_OKAY) {
39 goto ERR; 35 goto LBL_ERR;
40 } 36 }
41 mp_rshd(&a1, B); 37 mp_rshd(&a1, B);
42 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { 38 if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) {
43 goto ERR; 39 goto LBL_ERR;
44 } 40 }
45 41
46 if ((res = mp_copy(a, &a2)) != MP_OKAY) { 42 if ((res = mp_copy(a, &a2)) != MP_OKAY) {
47 goto ERR; 43 goto LBL_ERR;
48 } 44 }
49 mp_rshd(&a2, B*2); 45 mp_rshd(&a2, B*2);
50 46
51 /* w0 = a0*a0 */ 47 /* w0 = a0*a0 */
52 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { 48 if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
53 goto ERR; 49 goto LBL_ERR;
54 } 50 }
55 51
56 /* w4 = a2 * a2 */ 52 /* w4 = a2 * a2 */
57 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { 53 if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
58 goto ERR; 54 goto LBL_ERR;
59 } 55 }
60 56
61 /* w1 = (a2 + 2(a1 + 2a0))**2 */ 57 /* w1 = (a2 + 2(a1 + 2a0))**2 */
62 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { 58 if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
63 goto ERR; 59 goto LBL_ERR;
64 } 60 }
65 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { 61 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
66 goto ERR; 62 goto LBL_ERR;
67 } 63 }
68 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { 64 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
69 goto ERR; 65 goto LBL_ERR;
70 } 66 }
71 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { 67 if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
72 goto ERR; 68 goto LBL_ERR;
73 } 69 }
74 70
75 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { 71 if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
76 goto ERR; 72 goto LBL_ERR;
77 } 73 }
78 74
79 /* w3 = (a0 + 2(a1 + 2a2))**2 */ 75 /* w3 = (a0 + 2(a1 + 2a2))**2 */
80 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { 76 if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
81 goto ERR; 77 goto LBL_ERR;
82 } 78 }
83 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { 79 if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
84 goto ERR; 80 goto LBL_ERR;
85 } 81 }
86 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { 82 if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
87 goto ERR; 83 goto LBL_ERR;
88 } 84 }
89 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { 85 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
90 goto ERR; 86 goto LBL_ERR;
91 } 87 }
92 88
93 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { 89 if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
94 goto ERR; 90 goto LBL_ERR;
95 } 91 }
96 92
97 93
98 /* w2 = (a2 + a1 + a0)**2 */ 94 /* w2 = (a2 + a1 + a0)**2 */
99 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { 95 if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
100 goto ERR; 96 goto LBL_ERR;
101 } 97 }
102 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { 98 if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
103 goto ERR; 99 goto LBL_ERR;
104 } 100 }
105 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { 101 if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
106 goto ERR; 102 goto LBL_ERR;
107 } 103 }
108 104
109 /* now solve the matrix 105 /* now solve the matrix
110 106
111 0 0 0 0 1 107 0 0 0 0 1
112 1 2 4 8 16 108 1 2 4 8 16
113 1 1 1 1 1 109 1 1 1 1 1
114 16 8 4 2 1 110 16 8 4 2 1
115 1 0 0 0 0 111 1 0 0 0 0
116 112
117 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. 113 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
118 */ 114 */
119 115
120 /* r1 - r4 */ 116 /* r1 - r4 */
121 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { 117 if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
122 goto ERR; 118 goto LBL_ERR;
123 } 119 }
124 /* r3 - r0 */ 120 /* r3 - r0 */
125 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { 121 if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
126 goto ERR; 122 goto LBL_ERR;
127 } 123 }
128 /* r1/2 */ 124 /* r1/2 */
129 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { 125 if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
130 goto ERR; 126 goto LBL_ERR;
131 } 127 }
132 /* r3/2 */ 128 /* r3/2 */
133 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { 129 if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
134 goto ERR; 130 goto LBL_ERR;
135 } 131 }
136 /* r2 - r0 - r4 */ 132 /* r2 - r0 - r4 */
137 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { 133 if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
138 goto ERR; 134 goto LBL_ERR;
139 } 135 }
140 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { 136 if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
141 goto ERR; 137 goto LBL_ERR;
142 } 138 }
143 /* r1 - r2 */ 139 /* r1 - r2 */
144 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { 140 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
145 goto ERR; 141 goto LBL_ERR;
146 } 142 }
147 /* r3 - r2 */ 143 /* r3 - r2 */
148 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { 144 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
149 goto ERR; 145 goto LBL_ERR;
150 } 146 }
151 /* r1 - 8r0 */ 147 /* r1 - 8r0 */
152 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { 148 if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
153 goto ERR; 149 goto LBL_ERR;
154 } 150 }
155 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { 151 if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
156 goto ERR; 152 goto LBL_ERR;
157 } 153 }
158 /* r3 - 8r4 */ 154 /* r3 - 8r4 */
159 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { 155 if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
160 goto ERR; 156 goto LBL_ERR;
161 } 157 }
162 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { 158 if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
163 goto ERR; 159 goto LBL_ERR;
164 } 160 }
165 /* 3r2 - r1 - r3 */ 161 /* 3r2 - r1 - r3 */
166 if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { 162 if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) {
167 goto ERR; 163 goto LBL_ERR;
168 } 164 }
169 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { 165 if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
170 goto ERR; 166 goto LBL_ERR;
171 } 167 }
172 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { 168 if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
173 goto ERR; 169 goto LBL_ERR;
174 } 170 }
175 /* r1 - r2 */ 171 /* r1 - r2 */
176 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { 172 if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
177 goto ERR; 173 goto LBL_ERR;
178 } 174 }
179 /* r3 - r2 */ 175 /* r3 - r2 */
180 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { 176 if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
181 goto ERR; 177 goto LBL_ERR;
182 } 178 }
183 /* r1/3 */ 179 /* r1/3 */
184 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { 180 if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
185 goto ERR; 181 goto LBL_ERR;
186 } 182 }
187 /* r3/3 */ 183 /* r3/3 */
188 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { 184 if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
189 goto ERR; 185 goto LBL_ERR;
190 } 186 }
191 187
192 /* at this point shift W[n] by B*n */ 188 /* at this point shift W[n] by B*n */
193 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { 189 if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
194 goto ERR; 190 goto LBL_ERR;
195 } 191 }
196 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { 192 if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
197 goto ERR; 193 goto LBL_ERR;
198 } 194 }
199 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { 195 if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
200 goto ERR; 196 goto LBL_ERR;
201 } 197 }
202 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { 198 if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
203 goto ERR; 199 goto LBL_ERR;
204 } 200 }
205 201
206 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { 202 if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
207 goto ERR; 203 goto LBL_ERR;
208 } 204 }
209 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { 205 if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
210 goto ERR; 206 goto LBL_ERR;
211 } 207 }
212 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { 208 if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
213 goto ERR; 209 goto LBL_ERR;
214 } 210 }
215 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { 211 if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
216 goto ERR; 212 goto LBL_ERR;
217 } 213 }
218 214
219 ERR: 215 LBL_ERR:
220 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); 216 mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
221 return res; 217 return res;
222 } 218 }
223 219
224 #endif 220 #endif
225 221
226 /* ref: $Format:%D$ */ 222 /* ref: HEAD -> master, tag: v1.1.0 */
227 /* git commit: $Format:%H$ */ 223 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
228 /* commit time: $Format:%ai$ */ 224 /* commit time: 2019-01-28 20:32:32 +0100 */