Mercurial > dropbear
comparison libtommath/bn_mp_div_2d.c @ 293:9d110777f345 contrib-blacklist
propagate from branch 'au.asn.ucc.matt.dropbear' (head 7ad1775ed65e75dbece27fe6b65bf1a234db386a)
to branch 'au.asn.ucc.matt.dropbear.contrib.blacklist' (head 1d86a4f0a401cc68c2670d821a2f6366c37af143)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 10 Mar 2006 06:31:29 +0000 |
parents | eed26cff980b |
children | 5ff8218bcee9 |
comparison
equal
deleted
inserted
replaced
247:c07de41b53d7 | 293:9d110777f345 |
---|---|
1 #include <tommath.h> | |
2 #ifdef BN_MP_DIV_2D_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, [email protected], http://math.libtomcrypt.org | |
16 */ | |
17 | |
18 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ | |
19 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) | |
20 { | |
21 mp_digit D, r, rr; | |
22 int x, res; | |
23 mp_int t; | |
24 | |
25 | |
26 /* if the shift count is <= 0 then we do no work */ | |
27 if (b <= 0) { | |
28 res = mp_copy (a, c); | |
29 if (d != NULL) { | |
30 mp_zero (d); | |
31 } | |
32 return res; | |
33 } | |
34 | |
35 if ((res = mp_init (&t)) != MP_OKAY) { | |
36 return res; | |
37 } | |
38 | |
39 /* get the remainder */ | |
40 if (d != NULL) { | |
41 if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { | |
42 mp_clear (&t); | |
43 return res; | |
44 } | |
45 } | |
46 | |
47 /* copy */ | |
48 if ((res = mp_copy (a, c)) != MP_OKAY) { | |
49 mp_clear (&t); | |
50 return res; | |
51 } | |
52 | |
53 /* shift by as many digits in the bit count */ | |
54 if (b >= (int)DIGIT_BIT) { | |
55 mp_rshd (c, b / DIGIT_BIT); | |
56 } | |
57 | |
58 /* shift any bit count < DIGIT_BIT */ | |
59 D = (mp_digit) (b % DIGIT_BIT); | |
60 if (D != 0) { | |
61 register mp_digit *tmpc, mask, shift; | |
62 | |
63 /* mask */ | |
64 mask = (((mp_digit)1) << D) - 1; | |
65 | |
66 /* shift for lsb */ | |
67 shift = DIGIT_BIT - D; | |
68 | |
69 /* alias */ | |
70 tmpc = c->dp + (c->used - 1); | |
71 | |
72 /* carry */ | |
73 r = 0; | |
74 for (x = c->used - 1; x >= 0; x--) { | |
75 /* get the lower bits of this word in a temp */ | |
76 rr = *tmpc & mask; | |
77 | |
78 /* shift the current word and mix in the carry bits from the previous word */ | |
79 *tmpc = (*tmpc >> D) | (r << shift); | |
80 --tmpc; | |
81 | |
82 /* set the carry to the carry bits of the current word found above */ | |
83 r = rr; | |
84 } | |
85 } | |
86 mp_clamp (c); | |
87 if (d != NULL) { | |
88 mp_exch (&t, d); | |
89 } | |
90 mp_clear (&t); | |
91 return MP_OKAY; | |
92 } | |
93 #endif |