comparison libtommath/bn_s_mp_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 1051e4eea25a
comparison
equal deleted inserted replaced
1654:cc0fc5131c5c 1655:f52919ffd3b1
1 #include <tommath_private.h> 1 #include "tommath_private.h"
2 #ifdef BN_S_MP_SQR_C 2 #ifdef BN_S_MP_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 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ 15 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
19 int s_mp_sqr (mp_int * a, mp_int * b) 16 int s_mp_sqr(const mp_int *a, mp_int *b)
20 { 17 {
21 mp_int t; 18 mp_int t;
22 int res, ix, iy, pa; 19 int res, ix, iy, pa;
23 mp_word r; 20 mp_word r;
24 mp_digit u, tmpx, *tmpt; 21 mp_digit u, tmpx, *tmpt;
25 22
26 pa = a->used; 23 pa = a->used;
27 if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) { 24 if ((res = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
28 return res; 25 return res;
29 } 26 }
30 27
31 /* default used is maximum possible size */ 28 /* default used is maximum possible size */
32 t.used = (2 * pa) + 1; 29 t.used = (2 * pa) + 1;
33 30
34 for (ix = 0; ix < pa; ix++) { 31 for (ix = 0; ix < pa; ix++) {
35 /* first calculate the digit at 2*ix */ 32 /* first calculate the digit at 2*ix */
36 /* calculate double precision result */ 33 /* calculate double precision result */
37 r = (mp_word)t.dp[2*ix] + 34 r = (mp_word)t.dp[2*ix] +
38 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); 35 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
39 36
40 /* store lower part in result */ 37 /* store lower part in result */
41 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); 38 t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK);
42 39
43 /* get the carry */ 40 /* get the carry */
44 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); 41 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
45 42
46 /* left hand side of A[ix] * A[iy] */ 43 /* left hand side of A[ix] * A[iy] */
47 tmpx = a->dp[ix]; 44 tmpx = a->dp[ix];
48 45
49 /* alias for where to store the results */ 46 /* alias for where to store the results */
50 tmpt = t.dp + ((2 * ix) + 1); 47 tmpt = t.dp + ((2 * ix) + 1);
51
52 for (iy = ix + 1; iy < pa; iy++) {
53 /* first calculate the product */
54 r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
55 48
56 /* now calculate the double precision result, note we use 49 for (iy = ix + 1; iy < pa; iy++) {
57 * addition instead of *2 since it's easier to optimize 50 /* first calculate the product */
58 */ 51 r = (mp_word)tmpx * (mp_word)a->dp[iy];
59 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
60 52
61 /* store lower part */ 53 /* now calculate the double precision result, note we use
62 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); 54 * addition instead of *2 since it's easier to optimize
55 */
56 r = (mp_word)*tmpt + r + r + (mp_word)u;
63 57
64 /* get carry */ 58 /* store lower part */
65 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); 59 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
66 }
67 /* propagate upwards */
68 while (u != ((mp_digit) 0)) {
69 r = ((mp_word) *tmpt) + ((mp_word) u);
70 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
71 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
72 }
73 }
74 60
75 mp_clamp (&t); 61 /* get carry */
76 mp_exch (&t, b); 62 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
77 mp_clear (&t); 63 }
78 return MP_OKAY; 64 /* propagate upwards */
65 while (u != 0uL) {
66 r = (mp_word)*tmpt + (mp_word)u;
67 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
68 u = (mp_digit)(r >> (mp_word)DIGIT_BIT);
69 }
70 }
71
72 mp_clamp(&t);
73 mp_exch(&t, b);
74 mp_clear(&t);
75 return MP_OKAY;
79 } 76 }
80 #endif 77 #endif
81 78
82 /* ref: $Format:%D$ */ 79 /* ref: HEAD -> master, tag: v1.1.0 */
83 /* git commit: $Format:%H$ */ 80 /* git commit: 08549ad6bc8b0cede0b357a9c341c5c6473a9c55 */
84 /* commit time: $Format:%ai$ */ 81 /* commit time: 2019-01-28 20:32:32 +0100 */