comparison bn_fast_mp_invmod.c @ 190:d8254fc979e9 libtommath-orig LTM_0.35

Initial import of libtommath 0.35
author Matt Johnston <matt@ucc.asn.au>
date Fri, 06 May 2005 08:59:30 +0000
parents d29b64170cf0
children
comparison
equal deleted inserted replaced
142:d29b64170cf0 190:d8254fc979e9
19 * that is c = 1/a mod b 19 * that is c = 1/a mod b
20 * 20 *
21 * Based on slow invmod except this is optimized for the case where b is 21 * Based on slow invmod except this is optimized for the case where b is
22 * odd as per HAC Note 14.64 on pp. 610 22 * odd as per HAC Note 14.64 on pp. 610
23 */ 23 */
24 int 24 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
25 fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
26 { 25 {
27 mp_int x, y, u, v, B, D; 26 mp_int x, y, u, v, B, D;
28 int res, neg; 27 int res, neg;
29 28
30 /* 2. [modified] b must be odd */ 29 /* 2. [modified] b must be odd */
37 return res; 36 return res;
38 } 37 }
39 38
40 /* x == modulus, y == value to invert */ 39 /* x == modulus, y == value to invert */
41 if ((res = mp_copy (b, &x)) != MP_OKAY) { 40 if ((res = mp_copy (b, &x)) != MP_OKAY) {
42 goto __ERR; 41 goto LBL_ERR;
43 } 42 }
44 43
45 /* we need y = |a| */ 44 /* we need y = |a| */
46 if ((res = mp_abs (a, &y)) != MP_OKAY) { 45 if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
47 goto __ERR; 46 goto LBL_ERR;
48 } 47 }
49 48
50 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ 49 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
51 if ((res = mp_copy (&x, &u)) != MP_OKAY) { 50 if ((res = mp_copy (&x, &u)) != MP_OKAY) {
52 goto __ERR; 51 goto LBL_ERR;
53 } 52 }
54 if ((res = mp_copy (&y, &v)) != MP_OKAY) { 53 if ((res = mp_copy (&y, &v)) != MP_OKAY) {
55 goto __ERR; 54 goto LBL_ERR;
56 } 55 }
57 mp_set (&D, 1); 56 mp_set (&D, 1);
58 57
59 top: 58 top:
60 /* 4. while u is even do */ 59 /* 4. while u is even do */
61 while (mp_iseven (&u) == 1) { 60 while (mp_iseven (&u) == 1) {
62 /* 4.1 u = u/2 */ 61 /* 4.1 u = u/2 */
63 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) { 62 if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
64 goto __ERR; 63 goto LBL_ERR;
65 } 64 }
66 /* 4.2 if B is odd then */ 65 /* 4.2 if B is odd then */
67 if (mp_isodd (&B) == 1) { 66 if (mp_isodd (&B) == 1) {
68 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) { 67 if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
69 goto __ERR; 68 goto LBL_ERR;
70 } 69 }
71 } 70 }
72 /* B = B/2 */ 71 /* B = B/2 */
73 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) { 72 if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
74 goto __ERR; 73 goto LBL_ERR;
75 } 74 }
76 } 75 }
77 76
78 /* 5. while v is even do */ 77 /* 5. while v is even do */
79 while (mp_iseven (&v) == 1) { 78 while (mp_iseven (&v) == 1) {
80 /* 5.1 v = v/2 */ 79 /* 5.1 v = v/2 */
81 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) { 80 if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
82 goto __ERR; 81 goto LBL_ERR;
83 } 82 }
84 /* 5.2 if D is odd then */ 83 /* 5.2 if D is odd then */
85 if (mp_isodd (&D) == 1) { 84 if (mp_isodd (&D) == 1) {
86 /* D = (D-x)/2 */ 85 /* D = (D-x)/2 */
87 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) { 86 if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
88 goto __ERR; 87 goto LBL_ERR;
89 } 88 }
90 } 89 }
91 /* D = D/2 */ 90 /* D = D/2 */
92 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) { 91 if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
93 goto __ERR; 92 goto LBL_ERR;
94 } 93 }
95 } 94 }
96 95
97 /* 6. if u >= v then */ 96 /* 6. if u >= v then */
98 if (mp_cmp (&u, &v) != MP_LT) { 97 if (mp_cmp (&u, &v) != MP_LT) {
99 /* u = u - v, B = B - D */ 98 /* u = u - v, B = B - D */
100 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) { 99 if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
101 goto __ERR; 100 goto LBL_ERR;
102 } 101 }
103 102
104 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) { 103 if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
105 goto __ERR; 104 goto LBL_ERR;
106 } 105 }
107 } else { 106 } else {
108 /* v - v - u, D = D - B */ 107 /* v - v - u, D = D - B */
109 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) { 108 if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
110 goto __ERR; 109 goto LBL_ERR;
111 } 110 }
112 111
113 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) { 112 if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
114 goto __ERR; 113 goto LBL_ERR;
115 } 114 }
116 } 115 }
117 116
118 /* if not zero goto step 4 */ 117 /* if not zero goto step 4 */
119 if (mp_iszero (&u) == 0) { 118 if (mp_iszero (&u) == 0) {
123 /* now a = C, b = D, gcd == g*v */ 122 /* now a = C, b = D, gcd == g*v */
124 123
125 /* if v != 1 then there is no inverse */ 124 /* if v != 1 then there is no inverse */
126 if (mp_cmp_d (&v, 1) != MP_EQ) { 125 if (mp_cmp_d (&v, 1) != MP_EQ) {
127 res = MP_VAL; 126 res = MP_VAL;
128 goto __ERR; 127 goto LBL_ERR;
129 } 128 }
130 129
131 /* b is now the inverse */ 130 /* b is now the inverse */
132 neg = a->sign; 131 neg = a->sign;
133 while (D.sign == MP_NEG) { 132 while (D.sign == MP_NEG) {
134 if ((res = mp_add (&D, b, &D)) != MP_OKAY) { 133 if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
135 goto __ERR; 134 goto LBL_ERR;
136 } 135 }
137 } 136 }
138 mp_exch (&D, c); 137 mp_exch (&D, c);
139 c->sign = neg; 138 c->sign = neg;
140 res = MP_OKAY; 139 res = MP_OKAY;
141 140
142 __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); 141 LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
143 return res; 142 return res;
144 } 143 }
145 #endif 144 #endif