comparison libtommath/bn_s_mp_sqr.c @ 1739:13d834efc376 fuzz

merge from main
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 19:55:15 +0800
parents 1051e4eea25a
children
comparison
equal deleted inserted replaced
1562:768ebf737aa0 1739:13d834efc376
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 /* SPDX-License-Identifier: Unlicense */
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
7 *
8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place.
11 *
12 * The library is free for all purposes without any express
13 * guarantee it works.
14 *
15 * Tom St Denis, [email protected], http://libtom.org
16 */
17 5
18 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ 6 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
19 int s_mp_sqr (mp_int * a, mp_int * b) 7 mp_err s_mp_sqr(const mp_int *a, mp_int *b)
20 { 8 {
21 mp_int t; 9 mp_int t;
22 int res, ix, iy, pa; 10 int ix, iy, pa;
23 mp_word r; 11 mp_err err;
24 mp_digit u, tmpx, *tmpt; 12 mp_word r;
13 mp_digit u, tmpx, *tmpt;
25 14
26 pa = a->used; 15 pa = a->used;
27 if ((res = mp_init_size (&t, (2 * pa) + 1)) != MP_OKAY) { 16 if ((err = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) {
28 return res; 17 return err;
29 } 18 }
30 19
31 /* default used is maximum possible size */ 20 /* default used is maximum possible size */
32 t.used = (2 * pa) + 1; 21 t.used = (2 * pa) + 1;
33 22
34 for (ix = 0; ix < pa; ix++) { 23 for (ix = 0; ix < pa; ix++) {
35 /* first calculate the digit at 2*ix */ 24 /* first calculate the digit at 2*ix */
36 /* calculate double precision result */ 25 /* calculate double precision result */
37 r = (mp_word)t.dp[2*ix] + 26 r = (mp_word)t.dp[2*ix] +
38 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]); 27 ((mp_word)a->dp[ix] * (mp_word)a->dp[ix]);
39 28
40 /* store lower part in result */ 29 /* store lower part in result */
41 t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK)); 30 t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK);
42 31
43 /* get the carry */ 32 /* get the carry */
44 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); 33 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
45 34
46 /* left hand side of A[ix] * A[iy] */ 35 /* left hand side of A[ix] * A[iy] */
47 tmpx = a->dp[ix]; 36 tmpx = a->dp[ix];
48 37
49 /* alias for where to store the results */ 38 /* alias for where to store the results */
50 tmpt = t.dp + ((2 * ix) + 1); 39 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 40
56 /* now calculate the double precision result, note we use 41 for (iy = ix + 1; iy < pa; iy++) {
57 * addition instead of *2 since it's easier to optimize 42 /* first calculate the product */
58 */ 43 r = (mp_word)tmpx * (mp_word)a->dp[iy];
59 r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
60 44
61 /* store lower part */ 45 /* now calculate the double precision result, note we use
62 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK)); 46 * addition instead of *2 since it's easier to optimize
47 */
48 r = (mp_word)*tmpt + r + r + (mp_word)u;
63 49
64 /* get carry */ 50 /* store lower part */
65 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT)); 51 *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 52
75 mp_clamp (&t); 53 /* get carry */
76 mp_exch (&t, b); 54 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
77 mp_clear (&t); 55 }
78 return MP_OKAY; 56 /* propagate upwards */
57 while (u != 0uL) {
58 r = (mp_word)*tmpt + (mp_word)u;
59 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
60 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
61 }
62 }
63
64 mp_clamp(&t);
65 mp_exch(&t, b);
66 mp_clear(&t);
67 return MP_OKAY;
79 } 68 }
80 #endif 69 #endif
81
82 /* ref: $Format:%D$ */
83 /* git commit: $Format:%H$ */
84 /* commit time: $Format:%ai$ */