1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include <tommath.h>
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef BN_S_MP_SQR_C
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* LibTomMath, multiple-precision integer library -- Tom St Denis
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LibTomMath is a library that provides multiple-precision
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * integer arithmetic as well as number theoretic functionality.
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library was designed directly after the MPI library by
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Michael Fromberger but has been written from scratch with
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * additional optimizations in place.
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The library is free for all purposes without any express
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * guarantee it works.
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint s_mp_sqr (mp_int * a, mp_int * b)
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_int  t;
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  int     res, ix, iy, pa;
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_word r;
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_digit u, tmpx, *tmpt;
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  pa = a->used;
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return res;
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* default used is maximum possible size */
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  t.used = 2*pa + 1;
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  for (ix = 0; ix < pa; ix++) {
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* first calculate the digit at 2*ix */
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* calculate double precision result */
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    r = ((mp_word) t.dp[2*ix]) +
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* store lower part in result */
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* get the carry */
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* left hand side of A[ix] * A[iy] */
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    tmpx        = a->dp[ix];
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* alias for where to store the results */
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    tmpt        = t.dp + (2*ix + 1);
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    for (iy = ix + 1; iy < pa; iy++) {
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* first calculate the product */
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* now calculate the double precision result, note we use
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       * addition instead of *2 since it's easier to optimize
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project       */
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* store lower part */
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      /* get carry */
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* propagate upwards */
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    while (u != ((mp_digit) 0)) {
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      r       = ((mp_word) *tmpt) + ((mp_word) u);
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_clamp (&t);
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_exch (&t, b);
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_clear (&t);
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  return MP_OKAY;
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtommath/bn_s_mp_sqr.c,v $ */
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.3 $ */
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/03/31 14:18:44 $ */
85