bn_mp_sqrt.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <tommath.h>
  2. #ifdef BN_MP_SQRT_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4. *
  5. * LibTomMath is a library that provides multiple-precision
  6. * integer arithmetic as well as number theoretic functionality.
  7. *
  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.
  11. *
  12. * The library is free for all purposes without any express
  13. * guarantee it works.
  14. *
  15. * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
  16. */
  17. /* this function is less generic than mp_n_root, simpler and faster */
  18. int mp_sqrt(mp_int *arg, mp_int *ret)
  19. {
  20. int res;
  21. mp_int t1,t2;
  22. /* must be positive */
  23. if (arg->sign == MP_NEG) {
  24. return MP_VAL;
  25. }
  26. /* easy out */
  27. if (mp_iszero(arg) == MP_YES) {
  28. mp_zero(ret);
  29. return MP_OKAY;
  30. }
  31. if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
  32. return res;
  33. }
  34. if ((res = mp_init(&t2)) != MP_OKAY) {
  35. goto E2;
  36. }
  37. /* First approx. (not very bad for large arg) */
  38. mp_rshd (&t1,t1.used/2);
  39. /* t1 > 0 */
  40. if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
  41. goto E1;
  42. }
  43. if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
  44. goto E1;
  45. }
  46. if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
  47. goto E1;
  48. }
  49. /* And now t1 > sqrt(arg) */
  50. do {
  51. if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
  52. goto E1;
  53. }
  54. if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
  55. goto E1;
  56. }
  57. if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
  58. goto E1;
  59. }
  60. /* t1 >= sqrt(arg) >= t2 at this point */
  61. } while (mp_cmp_mag(&t1,&t2) == MP_GT);
  62. mp_exch(&t1,ret);
  63. E1: mp_clear(&t2);
  64. E2: mp_clear(&t1);
  65. return res;
  66. }
  67. #endif
  68. /* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */
  69. /* $Revision: 1.3 $ */
  70. /* $Date: 2006/03/31 14:18:44 $ */