1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include <tommath.h>
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef BN_MP_SQRT_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/* this function is less generic than mp_n_root, simpler and faster */
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint mp_sqrt(mp_int *arg, mp_int *ret)
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  int res;
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_int t1,t2;
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* must be positive */
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if (arg->sign == MP_NEG) {
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return MP_VAL;
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* easy out */
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if (mp_iszero(arg) == MP_YES) {
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    mp_zero(ret);
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return MP_OKAY;
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    return res;
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_init(&t2)) != MP_OKAY) {
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    goto E2;
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* First approx. (not very bad for large arg) */
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_rshd (&t1,t1.used/2);
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* t1 > 0  */
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    goto E1;
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    goto E1;
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    goto E1;
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  }
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  /* And now t1 > sqrt(arg) */
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  do {
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      goto E1;
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      goto E1;
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project      goto E1;
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    }
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    /* t1 >= sqrt(arg) >= t2 at this point */
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  } while (mp_cmp_mag(&t1,&t2) == MP_GT);
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  mp_exch(&t1,ret);
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectE1: mp_clear(&t2);
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source ProjectE2: mp_clear(&t1);
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project  return res;
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Revision: 1.3 $ */
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* $Date: 2006/03/31 14:18:44 $ */
82