2 #ifdef BN_MP_TOOM_SQR_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
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.
12 * The library is free for all purposes without any express
15 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
18 /* squaring using Toom-Cook 3-way algorithm */
20 mp_toom_sqr(mp_int
*a
, mp_int
*b
)
22 mp_int w0
, w1
, w2
, w3
, w4
, tmp1
, a0
, a1
, a2
;
26 if ((res
= mp_init_multi(&w0
, &w1
, &w2
, &w3
, &w4
, &a0
, &a1
, &a2
, &tmp1
, NULL
)) != MP_OKAY
) {
33 /* a = a2 * B**2 + a1 * B + a0 */
34 if ((res
= mp_mod_2d(a
, DIGIT_BIT
* B
, &a0
)) != MP_OKAY
) {
38 if ((res
= mp_copy(a
, &a1
)) != MP_OKAY
) {
42 mp_mod_2d(&a1
, DIGIT_BIT
* B
, &a1
);
44 if ((res
= mp_copy(a
, &a2
)) != MP_OKAY
) {
50 if ((res
= mp_sqr(&a0
, &w0
)) != MP_OKAY
) {
55 if ((res
= mp_sqr(&a2
, &w4
)) != MP_OKAY
) {
59 /* w1 = (a2 + 2(a1 + 2a0))**2 */
60 if ((res
= mp_mul_2(&a0
, &tmp1
)) != MP_OKAY
) {
63 if ((res
= mp_add(&tmp1
, &a1
, &tmp1
)) != MP_OKAY
) {
66 if ((res
= mp_mul_2(&tmp1
, &tmp1
)) != MP_OKAY
) {
69 if ((res
= mp_add(&tmp1
, &a2
, &tmp1
)) != MP_OKAY
) {
73 if ((res
= mp_sqr(&tmp1
, &w1
)) != MP_OKAY
) {
77 /* w3 = (a0 + 2(a1 + 2a2))**2 */
78 if ((res
= mp_mul_2(&a2
, &tmp1
)) != MP_OKAY
) {
81 if ((res
= mp_add(&tmp1
, &a1
, &tmp1
)) != MP_OKAY
) {
84 if ((res
= mp_mul_2(&tmp1
, &tmp1
)) != MP_OKAY
) {
87 if ((res
= mp_add(&tmp1
, &a0
, &tmp1
)) != MP_OKAY
) {
91 if ((res
= mp_sqr(&tmp1
, &w3
)) != MP_OKAY
) {
96 /* w2 = (a2 + a1 + a0)**2 */
97 if ((res
= mp_add(&a2
, &a1
, &tmp1
)) != MP_OKAY
) {
100 if ((res
= mp_add(&tmp1
, &a0
, &tmp1
)) != MP_OKAY
) {
103 if ((res
= mp_sqr(&tmp1
, &w2
)) != MP_OKAY
) {
107 /* now solve the matrix
115 using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
119 if ((res
= mp_sub(&w1
, &w4
, &w1
)) != MP_OKAY
) {
123 if ((res
= mp_sub(&w3
, &w0
, &w3
)) != MP_OKAY
) {
127 if ((res
= mp_div_2(&w1
, &w1
)) != MP_OKAY
) {
131 if ((res
= mp_div_2(&w3
, &w3
)) != MP_OKAY
) {
135 if ((res
= mp_sub(&w2
, &w0
, &w2
)) != MP_OKAY
) {
138 if ((res
= mp_sub(&w2
, &w4
, &w2
)) != MP_OKAY
) {
142 if ((res
= mp_sub(&w1
, &w2
, &w1
)) != MP_OKAY
) {
146 if ((res
= mp_sub(&w3
, &w2
, &w3
)) != MP_OKAY
) {
150 if ((res
= mp_mul_2d(&w0
, 3, &tmp1
)) != MP_OKAY
) {
153 if ((res
= mp_sub(&w1
, &tmp1
, &w1
)) != MP_OKAY
) {
157 if ((res
= mp_mul_2d(&w4
, 3, &tmp1
)) != MP_OKAY
) {
160 if ((res
= mp_sub(&w3
, &tmp1
, &w3
)) != MP_OKAY
) {
164 if ((res
= mp_mul_d(&w2
, 3, &w2
)) != MP_OKAY
) {
167 if ((res
= mp_sub(&w2
, &w1
, &w2
)) != MP_OKAY
) {
170 if ((res
= mp_sub(&w2
, &w3
, &w2
)) != MP_OKAY
) {
174 if ((res
= mp_sub(&w1
, &w2
, &w1
)) != MP_OKAY
) {
178 if ((res
= mp_sub(&w3
, &w2
, &w3
)) != MP_OKAY
) {
182 if ((res
= mp_div_3(&w1
, &w1
, NULL
)) != MP_OKAY
) {
186 if ((res
= mp_div_3(&w3
, &w3
, NULL
)) != MP_OKAY
) {
190 /* at this point shift W[n] by B*n */
191 if ((res
= mp_lshd(&w1
, 1*B
)) != MP_OKAY
) {
194 if ((res
= mp_lshd(&w2
, 2*B
)) != MP_OKAY
) {
197 if ((res
= mp_lshd(&w3
, 3*B
)) != MP_OKAY
) {
200 if ((res
= mp_lshd(&w4
, 4*B
)) != MP_OKAY
) {
204 if ((res
= mp_add(&w0
, &w1
, b
)) != MP_OKAY
) {
207 if ((res
= mp_add(&w2
, &w3
, &tmp1
)) != MP_OKAY
) {
210 if ((res
= mp_add(&w4
, &tmp1
, &tmp1
)) != MP_OKAY
) {
213 if ((res
= mp_add(&tmp1
, b
, b
)) != MP_OKAY
) {
218 mp_clear_multi(&w0
, &w1
, &w2
, &w3
, &w4
, &a0
, &a1
, &a2
, &tmp1
, NULL
);
224 /* $Source: /cvs/libtom/libtommath/bn_mp_toom_sqr.c,v $ */
225 /* $Revision: 1.3 $ */
226 /* $Date: 2006/03/31 14:18:44 $ */