change some parameters in the library to meet the needs of the website httpbin.org

Fork of MiniTLS-GPL by Donatien Garnier

Committer:
shiyilei
Date:
Fri Feb 06 06:17:33 2015 +0000
Revision:
5:95f70ebfe61f
Parent:
0:35aa5be3b78d
change some parameters in the library to meet the needs of httpbin.org

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MiniTLS 0:35aa5be3b78d 1 /* TomsFastMath, a fast ISO C bignum library.
MiniTLS 0:35aa5be3b78d 2 *
MiniTLS 0:35aa5be3b78d 3 * This project is meant to fill in where LibTomMath
MiniTLS 0:35aa5be3b78d 4 * falls short. That is speed ;-)
MiniTLS 0:35aa5be3b78d 5 *
MiniTLS 0:35aa5be3b78d 6 * This project is public domain and free for all purposes.
MiniTLS 0:35aa5be3b78d 7 *
MiniTLS 0:35aa5be3b78d 8 * Tom St Denis, tomstdenis@gmail.com
MiniTLS 0:35aa5be3b78d 9 */
MiniTLS 0:35aa5be3b78d 10 #include <tfm.h>
MiniTLS 0:35aa5be3b78d 11
MiniTLS 0:35aa5be3b78d 12 static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
MiniTLS 0:35aa5be3b78d 13 {
MiniTLS 0:35aa5be3b78d 14 fp_int x, y, u, v, A, B, C, D;
MiniTLS 0:35aa5be3b78d 15 int res;
MiniTLS 0:35aa5be3b78d 16
MiniTLS 0:35aa5be3b78d 17 /* b cannot be negative */
MiniTLS 0:35aa5be3b78d 18 if (b->sign == FP_NEG || fp_iszero(b) == 1) {
MiniTLS 0:35aa5be3b78d 19 return FP_VAL;
MiniTLS 0:35aa5be3b78d 20 }
MiniTLS 0:35aa5be3b78d 21
MiniTLS 0:35aa5be3b78d 22 /* init temps */
MiniTLS 0:35aa5be3b78d 23 fp_init(&x); fp_init(&y);
MiniTLS 0:35aa5be3b78d 24 fp_init(&u); fp_init(&v);
MiniTLS 0:35aa5be3b78d 25 fp_init(&A); fp_init(&B);
MiniTLS 0:35aa5be3b78d 26 fp_init(&C); fp_init(&D);
MiniTLS 0:35aa5be3b78d 27
MiniTLS 0:35aa5be3b78d 28 /* x = a, y = b */
MiniTLS 0:35aa5be3b78d 29 if ((res = fp_mod(a, b, &x)) != FP_OKAY) {
MiniTLS 0:35aa5be3b78d 30 return res;
MiniTLS 0:35aa5be3b78d 31 }
MiniTLS 0:35aa5be3b78d 32 fp_copy(b, &y);
MiniTLS 0:35aa5be3b78d 33
MiniTLS 0:35aa5be3b78d 34 /* 2. [modified] if x,y are both even then return an error! */
MiniTLS 0:35aa5be3b78d 35 if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) {
MiniTLS 0:35aa5be3b78d 36 return FP_VAL;
MiniTLS 0:35aa5be3b78d 37 }
MiniTLS 0:35aa5be3b78d 38
MiniTLS 0:35aa5be3b78d 39 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
MiniTLS 0:35aa5be3b78d 40 fp_copy (&x, &u);
MiniTLS 0:35aa5be3b78d 41 fp_copy (&y, &v);
MiniTLS 0:35aa5be3b78d 42 fp_set (&A, 1);
MiniTLS 0:35aa5be3b78d 43 fp_set (&D, 1);
MiniTLS 0:35aa5be3b78d 44
MiniTLS 0:35aa5be3b78d 45 top:
MiniTLS 0:35aa5be3b78d 46 /* 4. while u is even do */
MiniTLS 0:35aa5be3b78d 47 while (fp_iseven (&u) == 1) {
MiniTLS 0:35aa5be3b78d 48 /* 4.1 u = u/2 */
MiniTLS 0:35aa5be3b78d 49 fp_div_2 (&u, &u);
MiniTLS 0:35aa5be3b78d 50
MiniTLS 0:35aa5be3b78d 51 /* 4.2 if A or B is odd then */
MiniTLS 0:35aa5be3b78d 52 if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) {
MiniTLS 0:35aa5be3b78d 53 /* A = (A+y)/2, B = (B-x)/2 */
MiniTLS 0:35aa5be3b78d 54 fp_add (&A, &y, &A);
MiniTLS 0:35aa5be3b78d 55 fp_sub (&B, &x, &B);
MiniTLS 0:35aa5be3b78d 56 }
MiniTLS 0:35aa5be3b78d 57 /* A = A/2, B = B/2 */
MiniTLS 0:35aa5be3b78d 58 fp_div_2 (&A, &A);
MiniTLS 0:35aa5be3b78d 59 fp_div_2 (&B, &B);
MiniTLS 0:35aa5be3b78d 60 }
MiniTLS 0:35aa5be3b78d 61
MiniTLS 0:35aa5be3b78d 62 /* 5. while v is even do */
MiniTLS 0:35aa5be3b78d 63 while (fp_iseven (&v) == 1) {
MiniTLS 0:35aa5be3b78d 64 /* 5.1 v = v/2 */
MiniTLS 0:35aa5be3b78d 65 fp_div_2 (&v, &v);
MiniTLS 0:35aa5be3b78d 66
MiniTLS 0:35aa5be3b78d 67 /* 5.2 if C or D is odd then */
MiniTLS 0:35aa5be3b78d 68 if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) {
MiniTLS 0:35aa5be3b78d 69 /* C = (C+y)/2, D = (D-x)/2 */
MiniTLS 0:35aa5be3b78d 70 fp_add (&C, &y, &C);
MiniTLS 0:35aa5be3b78d 71 fp_sub (&D, &x, &D);
MiniTLS 0:35aa5be3b78d 72 }
MiniTLS 0:35aa5be3b78d 73 /* C = C/2, D = D/2 */
MiniTLS 0:35aa5be3b78d 74 fp_div_2 (&C, &C);
MiniTLS 0:35aa5be3b78d 75 fp_div_2 (&D, &D);
MiniTLS 0:35aa5be3b78d 76 }
MiniTLS 0:35aa5be3b78d 77
MiniTLS 0:35aa5be3b78d 78 /* 6. if u >= v then */
MiniTLS 0:35aa5be3b78d 79 if (fp_cmp (&u, &v) != FP_LT) {
MiniTLS 0:35aa5be3b78d 80 /* u = u - v, A = A - C, B = B - D */
MiniTLS 0:35aa5be3b78d 81 fp_sub (&u, &v, &u);
MiniTLS 0:35aa5be3b78d 82 fp_sub (&A, &C, &A);
MiniTLS 0:35aa5be3b78d 83 fp_sub (&B, &D, &B);
MiniTLS 0:35aa5be3b78d 84 } else {
MiniTLS 0:35aa5be3b78d 85 /* v - v - u, C = C - A, D = D - B */
MiniTLS 0:35aa5be3b78d 86 fp_sub (&v, &u, &v);
MiniTLS 0:35aa5be3b78d 87 fp_sub (&C, &A, &C);
MiniTLS 0:35aa5be3b78d 88 fp_sub (&D, &B, &D);
MiniTLS 0:35aa5be3b78d 89 }
MiniTLS 0:35aa5be3b78d 90
MiniTLS 0:35aa5be3b78d 91 /* if not zero goto step 4 */
MiniTLS 0:35aa5be3b78d 92 if (fp_iszero (&u) == 0)
MiniTLS 0:35aa5be3b78d 93 goto top;
MiniTLS 0:35aa5be3b78d 94
MiniTLS 0:35aa5be3b78d 95 /* now a = C, b = D, gcd == g*v */
MiniTLS 0:35aa5be3b78d 96
MiniTLS 0:35aa5be3b78d 97 /* if v != 1 then there is no inverse */
MiniTLS 0:35aa5be3b78d 98 if (fp_cmp_d (&v, 1) != FP_EQ) {
MiniTLS 0:35aa5be3b78d 99 return FP_VAL;
MiniTLS 0:35aa5be3b78d 100 }
MiniTLS 0:35aa5be3b78d 101
MiniTLS 0:35aa5be3b78d 102 /* if its too low */
MiniTLS 0:35aa5be3b78d 103 while (fp_cmp_d(&C, 0) == FP_LT) {
MiniTLS 0:35aa5be3b78d 104 fp_add(&C, b, &C);
MiniTLS 0:35aa5be3b78d 105 }
MiniTLS 0:35aa5be3b78d 106
MiniTLS 0:35aa5be3b78d 107 /* too big */
MiniTLS 0:35aa5be3b78d 108 while (fp_cmp_mag(&C, b) != FP_LT) {
MiniTLS 0:35aa5be3b78d 109 fp_sub(&C, b, &C);
MiniTLS 0:35aa5be3b78d 110 }
MiniTLS 0:35aa5be3b78d 111
MiniTLS 0:35aa5be3b78d 112 /* C is now the inverse */
MiniTLS 0:35aa5be3b78d 113 fp_copy(&C, c);
MiniTLS 0:35aa5be3b78d 114 return FP_OKAY;
MiniTLS 0:35aa5be3b78d 115 }
MiniTLS 0:35aa5be3b78d 116
MiniTLS 0:35aa5be3b78d 117 /* c = 1/a (mod b) for odd b only */
MiniTLS 0:35aa5be3b78d 118 int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
MiniTLS 0:35aa5be3b78d 119 {
MiniTLS 0:35aa5be3b78d 120 fp_int x, y, u, v, B, D;
MiniTLS 0:35aa5be3b78d 121 int neg;
MiniTLS 0:35aa5be3b78d 122
MiniTLS 0:35aa5be3b78d 123 /* 2. [modified] b must be odd */
MiniTLS 0:35aa5be3b78d 124 if (fp_iseven (b) == FP_YES) {
MiniTLS 0:35aa5be3b78d 125 return fp_invmod_slow(a,b,c);
MiniTLS 0:35aa5be3b78d 126 }
MiniTLS 0:35aa5be3b78d 127
MiniTLS 0:35aa5be3b78d 128 /* init all our temps */
MiniTLS 0:35aa5be3b78d 129 fp_init(&x); fp_init(&y);
MiniTLS 0:35aa5be3b78d 130 fp_init(&u); fp_init(&v);
MiniTLS 0:35aa5be3b78d 131 fp_init(&B); fp_init(&D);
MiniTLS 0:35aa5be3b78d 132
MiniTLS 0:35aa5be3b78d 133 /* x == modulus, y == value to invert */
MiniTLS 0:35aa5be3b78d 134 fp_copy(b, &x);
MiniTLS 0:35aa5be3b78d 135
MiniTLS 0:35aa5be3b78d 136 /* we need y = |a| */
MiniTLS 0:35aa5be3b78d 137 fp_abs(a, &y);
MiniTLS 0:35aa5be3b78d 138
MiniTLS 0:35aa5be3b78d 139 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
MiniTLS 0:35aa5be3b78d 140 fp_copy(&x, &u);
MiniTLS 0:35aa5be3b78d 141 fp_copy(&y, &v);
MiniTLS 0:35aa5be3b78d 142 fp_set (&D, 1);
MiniTLS 0:35aa5be3b78d 143
MiniTLS 0:35aa5be3b78d 144 top:
MiniTLS 0:35aa5be3b78d 145 /* 4. while u is even do */
MiniTLS 0:35aa5be3b78d 146 while (fp_iseven (&u) == FP_YES) {
MiniTLS 0:35aa5be3b78d 147 /* 4.1 u = u/2 */
MiniTLS 0:35aa5be3b78d 148 fp_div_2 (&u, &u);
MiniTLS 0:35aa5be3b78d 149
MiniTLS 0:35aa5be3b78d 150 /* 4.2 if B is odd then */
MiniTLS 0:35aa5be3b78d 151 if (fp_isodd (&B) == FP_YES) {
MiniTLS 0:35aa5be3b78d 152 fp_sub (&B, &x, &B);
MiniTLS 0:35aa5be3b78d 153 }
MiniTLS 0:35aa5be3b78d 154 /* B = B/2 */
MiniTLS 0:35aa5be3b78d 155 fp_div_2 (&B, &B);
MiniTLS 0:35aa5be3b78d 156 }
MiniTLS 0:35aa5be3b78d 157
MiniTLS 0:35aa5be3b78d 158 /* 5. while v is even do */
MiniTLS 0:35aa5be3b78d 159 while (fp_iseven (&v) == FP_YES) {
MiniTLS 0:35aa5be3b78d 160 /* 5.1 v = v/2 */
MiniTLS 0:35aa5be3b78d 161 fp_div_2 (&v, &v);
MiniTLS 0:35aa5be3b78d 162
MiniTLS 0:35aa5be3b78d 163 /* 5.2 if D is odd then */
MiniTLS 0:35aa5be3b78d 164 if (fp_isodd (&D) == FP_YES) {
MiniTLS 0:35aa5be3b78d 165 /* D = (D-x)/2 */
MiniTLS 0:35aa5be3b78d 166 fp_sub (&D, &x, &D);
MiniTLS 0:35aa5be3b78d 167 }
MiniTLS 0:35aa5be3b78d 168 /* D = D/2 */
MiniTLS 0:35aa5be3b78d 169 fp_div_2 (&D, &D);
MiniTLS 0:35aa5be3b78d 170 }
MiniTLS 0:35aa5be3b78d 171
MiniTLS 0:35aa5be3b78d 172 /* 6. if u >= v then */
MiniTLS 0:35aa5be3b78d 173 if (fp_cmp (&u, &v) != FP_LT) {
MiniTLS 0:35aa5be3b78d 174 /* u = u - v, B = B - D */
MiniTLS 0:35aa5be3b78d 175 fp_sub (&u, &v, &u);
MiniTLS 0:35aa5be3b78d 176 fp_sub (&B, &D, &B);
MiniTLS 0:35aa5be3b78d 177 } else {
MiniTLS 0:35aa5be3b78d 178 /* v - v - u, D = D - B */
MiniTLS 0:35aa5be3b78d 179 fp_sub (&v, &u, &v);
MiniTLS 0:35aa5be3b78d 180 fp_sub (&D, &B, &D);
MiniTLS 0:35aa5be3b78d 181 }
MiniTLS 0:35aa5be3b78d 182
MiniTLS 0:35aa5be3b78d 183 /* if not zero goto step 4 */
MiniTLS 0:35aa5be3b78d 184 if (fp_iszero (&u) == FP_NO) {
MiniTLS 0:35aa5be3b78d 185 goto top;
MiniTLS 0:35aa5be3b78d 186 }
MiniTLS 0:35aa5be3b78d 187
MiniTLS 0:35aa5be3b78d 188 /* now a = C, b = D, gcd == g*v */
MiniTLS 0:35aa5be3b78d 189
MiniTLS 0:35aa5be3b78d 190 /* if v != 1 then there is no inverse */
MiniTLS 0:35aa5be3b78d 191 if (fp_cmp_d (&v, 1) != FP_EQ) {
MiniTLS 0:35aa5be3b78d 192 return FP_VAL;
MiniTLS 0:35aa5be3b78d 193 }
MiniTLS 0:35aa5be3b78d 194
MiniTLS 0:35aa5be3b78d 195 /* b is now the inverse */
MiniTLS 0:35aa5be3b78d 196 neg = a->sign;
MiniTLS 0:35aa5be3b78d 197 while (D.sign == FP_NEG) {
MiniTLS 0:35aa5be3b78d 198 fp_add (&D, b, &D);
MiniTLS 0:35aa5be3b78d 199 }
MiniTLS 0:35aa5be3b78d 200 fp_copy (&D, c);
MiniTLS 0:35aa5be3b78d 201 c->sign = neg;
MiniTLS 0:35aa5be3b78d 202 return FP_OKAY;
MiniTLS 0:35aa5be3b78d 203 }
MiniTLS 0:35aa5be3b78d 204
MiniTLS 0:35aa5be3b78d 205 /* $Source: /cvs/libtom/tomsfastmath/src/numtheory/fp_invmod.c,v $ */
MiniTLS 0:35aa5be3b78d 206 /* $Revision: 1.1 $ */
MiniTLS 0:35aa5be3b78d 207 /* $Date: 2007/01/24 21:25:19 $ */