1 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 * LibTomMath is library that provides for multiple-precision
4 * integer arithmetic as well as number theoretic functionality.
6 * The library is designed directly after the MPI library by
7 * Michael Fromberger but has been written from scratch with
8 * additional optimizations in place.
10 * The library is free for all purposes without any express
13 * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
17 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
19 s_mp_sqr (mp_int * a, mp_int * b)
24 mp_digit u, tmpx, *tmpt;
27 if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
32 for (ix = 0; ix < pa; ix++) {
33 /* first calculate the digit at 2*ix */
34 /* calculate double precision result */
35 r = ((mp_word) t.dp[2*ix]) +
36 ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
38 /* store lower part in result */
39 t.dp[2*ix] = (mp_digit) (r & ((mp_word) MP_MASK));
42 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
44 /* left hand side of A[ix] * A[iy] */
47 /* alias for where to store the results */
48 tmpt = t.dp + (2*ix + 1);
50 for (iy = ix + 1; iy < pa; iy++) {
51 /* first calculate the product */
52 r = ((mp_word) tmpx) * ((mp_word) a->dp[iy]);
54 /* now calculate the double precision result, note we use
55 * addition instead of *2 since it's easier to optimize
57 r = ((mp_word) * tmpt) + r + r + ((mp_word) u);
59 /* store lower part */
60 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
63 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
65 /* propagate upwards */
66 while (u != ((mp_digit) 0)) {
67 r = ((mp_word) * tmpt) + ((mp_word) u);
68 *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
69 u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));