Blame view

Giac_maj/libtommath-0.39/bn_mp_div_3.c 1.82 KB
6663b6c9   adorian   projet complet av...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
  #include <tommath.h>
  #ifdef BN_MP_DIV_3_C
  /* LibTomMath, multiple-precision integer library -- Tom St Denis
   *
   * LibTomMath is a library that provides multiple-precision
   * integer arithmetic as well as number theoretic functionality.
   *
   * The library was designed directly after the MPI library by
   * Michael Fromberger but has been written from scratch with
   * additional optimizations in place.
   *
   * The library is free for all purposes without any express
   * guarantee it works.
   *
   * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
   */
  
  /* divide by three (based on routine from MPI and the GMP manual) */
  int
  mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
  {
    mp_int   q;
    mp_word  w, t;
    mp_digit b;
    int      res, ix;
    
    /* b = 2**DIGIT_BIT / 3 */
    b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
  
    if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
       return res;
    }
    
    q.used = a->used;
    q.sign = a->sign;
    w = 0;
    for (ix = a->used - 1; ix >= 0; ix--) {
       w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
  
       if (w >= 3) {
          /* multiply w by [1/3] */
          t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
  
          /* now subtract 3 * [w/3] from w, to get the remainder */
          w -= t+t+t;
  
          /* fixup the remainder as required since
           * the optimization is not exact.
           */
          while (w >= 3) {
             t += 1;
             w -= 3;
          }
        } else {
          t = 0;
        }
        q.dp[ix] = (mp_digit)t;
    }
  
    /* [optional] store the remainder */
    if (d != NULL) {
       *d = (mp_digit)w;
    }
  
    /* [optional] store the quotient */
    if (c != NULL) {
       mp_clamp(&q);
       mp_exch(&q, c);
    }
    mp_clear(&q);
    
    return res;
  }
  
  #endif
  
  /* $Source: /cvs/libtom/libtommath/bn_mp_div_3.c,v $ */
  /* $Revision: 1.3 $ */
  /* $Date: 2006/03/31 14:18:44 $ */