2 #ifdef BN_MP_KARATSUBA_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://libtom.org
18 /* Karatsuba squaring, computes b = a*a using three
21 * See comments of karatsuba_mul for details. It
22 * is essentially the same algorithm but merely
23 * tuned to perform recursive squarings.
25 int mp_karatsuba_sqr (mp_int
* a
, mp_int
* b
)
27 mp_int x0
, x1
, t1
, t2
, x0x0
, x1x1
;
35 /* now divide in two */
38 /* init copy all the temps */
39 if (mp_init_size (&x0
, B
) != MP_OKAY
)
41 if (mp_init_size (&x1
, a
->used
- B
) != MP_OKAY
)
45 if (mp_init_size (&t1
, a
->used
* 2) != MP_OKAY
)
47 if (mp_init_size (&t2
, a
->used
* 2) != MP_OKAY
)
49 if (mp_init_size (&x0x0
, B
* 2) != MP_OKAY
)
51 if (mp_init_size (&x1x1
, (a
->used
- B
) * 2) != MP_OKAY
)
56 register mp_digit
*dst
, *src
;
60 /* now shift the digits */
62 for (x
= 0; x
< B
; x
++) {
67 for (x
= B
; x
< a
->used
; x
++) {
73 x1
.used
= a
->used
- B
;
77 /* now calc the products x0*x0 and x1*x1 */
78 if (mp_sqr (&x0
, &x0x0
) != MP_OKAY
)
79 goto X1X1
; /* x0x0 = x0*x0 */
80 if (mp_sqr (&x1
, &x1x1
) != MP_OKAY
)
81 goto X1X1
; /* x1x1 = x1*x1 */
83 /* now calc (x1+x0)**2 */
84 if (s_mp_add (&x1
, &x0
, &t1
) != MP_OKAY
)
85 goto X1X1
; /* t1 = x1 - x0 */
86 if (mp_sqr (&t1
, &t1
) != MP_OKAY
)
87 goto X1X1
; /* t1 = (x1 - x0) * (x1 - x0) */
90 if (s_mp_add (&x0x0
, &x1x1
, &t2
) != MP_OKAY
)
91 goto X1X1
; /* t2 = x0x0 + x1x1 */
92 if (s_mp_sub (&t1
, &t2
, &t1
) != MP_OKAY
)
93 goto X1X1
; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
96 if (mp_lshd (&t1
, B
) != MP_OKAY
)
97 goto X1X1
; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
98 if (mp_lshd (&x1x1
, B
* 2) != MP_OKAY
)
99 goto X1X1
; /* x1x1 = x1x1 << 2*B */
101 if (mp_add (&x0x0
, &t1
, &t1
) != MP_OKAY
)
102 goto X1X1
; /* t1 = x0x0 + t1 */
103 if (mp_add (&t1
, &x1x1
, b
) != MP_OKAY
)
104 goto X1X1
; /* t1 = x0x0 + t1 + x1x1 */
108 X1X1
:mp_clear (&x1x1
);
109 X0X0
:mp_clear (&x0x0
);
119 /* $Source: /cvs/libtom/libtommath/bn_mp_karatsuba_sqr.c,v $ */
120 /* $Revision: 1.6 $ */
121 /* $Date: 2006/12/28 01:25:13 $ */