Mercurial > dropbear
comparison gf.c @ 0:d7da3b1e1540 libtomcrypt
put back the 0.95 makefile which was inadvertently merged over
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:21:40 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d7da3b1e1540 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 /* polynomial basis GF(2^w) routines */ | |
12 #include "mycrypt.h" | |
13 | |
14 #ifdef GF | |
15 | |
16 #define FORLOOP for (i = 0; i < LSIZE; i++) | |
17 | |
18 /* c = a + b */ | |
19 void gf_add(gf_intp a, gf_intp b, gf_intp c) | |
20 { | |
21 int i; | |
22 FORLOOP c[i] = a[i]^b[i]; | |
23 } | |
24 | |
25 /* b = a */ | |
26 void gf_copy(gf_intp a, gf_intp b) | |
27 { | |
28 int i; | |
29 FORLOOP b[i] = a[i]; | |
30 } | |
31 | |
32 /* a = 0 */ | |
33 void gf_zero(gf_intp a) | |
34 { | |
35 int i; | |
36 FORLOOP a[i] = 0; | |
37 } | |
38 | |
39 /* is a zero? */ | |
40 int gf_iszero(gf_intp a) | |
41 { | |
42 int i; | |
43 FORLOOP if (a[i]) { | |
44 return 0; | |
45 } | |
46 return 1; | |
47 } | |
48 | |
49 /* is a one? */ | |
50 int gf_isone(gf_intp a) | |
51 { | |
52 int i; | |
53 for (i = 1; i < LSIZE; i++) { | |
54 if (a[i]) { | |
55 return 0; | |
56 } | |
57 } | |
58 return a[0] == 1; | |
59 } | |
60 | |
61 /* b = a << 1*/ | |
62 void gf_shl(gf_intp a, gf_intp b) | |
63 { | |
64 int i; | |
65 gf_int tmp; | |
66 | |
67 gf_copy(a, tmp); | |
68 for (i = LSIZE-1; i > 0; i--) | |
69 b[i] = ((tmp[i]<<1)|((tmp[i-1]&0xFFFFFFFFUL)>>31))&0xFFFFFFFFUL; | |
70 b[0] = (tmp[0] << 1)&0xFFFFFFFFUL; | |
71 gf_zero(tmp); | |
72 } | |
73 | |
74 /* b = a >> 1 */ | |
75 void gf_shr(gf_intp a, gf_intp b) | |
76 { | |
77 int i; | |
78 gf_int tmp; | |
79 | |
80 gf_copy(a, tmp); | |
81 for (i = 0; i < LSIZE-1; i++) | |
82 b[i] = (((tmp[i]&0xFFFFFFFFUL)>>1)|(tmp[i+1]<<31))&0xFFFFFFFFUL; | |
83 b[LSIZE-1] = (tmp[LSIZE-1]&0xFFFFFFFFUL)>>1; | |
84 gf_zero(tmp); | |
85 } | |
86 | |
87 /* returns -1 if its zero, otherwise degree of a */ | |
88 int gf_deg(gf_intp a) | |
89 { | |
90 int i, ii; | |
91 unsigned long t; | |
92 | |
93 ii = -1; | |
94 for (i = LSIZE-1; i >= 0; i--) | |
95 if (a[i]) { | |
96 for (t = a[i], ii = 0; t; t >>= 1, ++ii); | |
97 break; | |
98 } | |
99 if (i == -1) i = 0; | |
100 return (i<<5)+ii; | |
101 } | |
102 | |
103 /* c = ab */ | |
104 void gf_mul(gf_intp a, gf_intp b, gf_intp c) | |
105 { | |
106 gf_int ta, tb; | |
107 int i, n; | |
108 | |
109 gf_copy(a, ta); | |
110 gf_copy(b, tb); | |
111 gf_zero(c); | |
112 n = gf_deg(ta)+1; | |
113 for (i = 0; i < n; i++) { | |
114 if (ta[i>>5]&(1<<(i&31))) | |
115 gf_add(c, tb, c); | |
116 gf_shl(tb, tb); | |
117 } | |
118 gf_zero(ta); | |
119 gf_zero(tb); | |
120 } | |
121 | |
122 /* q = a/b, r = a%b */ | |
123 void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r) | |
124 { | |
125 gf_int ta, tb, shifts[LSIZE*32]; | |
126 int i, magb, mag; | |
127 | |
128 mag = gf_deg(a); | |
129 magb = gf_deg(b); | |
130 | |
131 /* special cases */ | |
132 if (magb > mag) { | |
133 gf_copy(a, r); | |
134 gf_zero(q); | |
135 return; | |
136 } | |
137 if (magb == -1) { | |
138 return; | |
139 } | |
140 | |
141 /* copy locally */ | |
142 gf_copy(a, ta); | |
143 gf_copy(b, tb); | |
144 gf_zero(q); | |
145 | |
146 /* make shifted versions of "b" */ | |
147 gf_copy(tb, shifts[0]); | |
148 for (i = 1; i <= (mag-magb); i++) | |
149 gf_shl(shifts[i-1], shifts[i]); | |
150 | |
151 while (mag >= magb) { | |
152 i = (mag - magb); | |
153 q[i>>5] |= (1<<(i&31)); | |
154 gf_add(ta, shifts[i], ta); | |
155 mag = gf_deg(ta); | |
156 } | |
157 gf_copy(ta, r); | |
158 gf_zero(ta); | |
159 gf_zero(tb); | |
160 zeromem(shifts, sizeof(shifts)); | |
161 } | |
162 | |
163 /* b = a mod m */ | |
164 void gf_mod(gf_intp a, gf_intp m, gf_intp b) | |
165 { | |
166 gf_int tmp; | |
167 gf_div(a,m,tmp,b); | |
168 gf_zero(tmp); | |
169 } | |
170 | |
171 /* c = ab (mod m) */ | |
172 void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c) | |
173 { | |
174 gf_int tmp; | |
175 gf_mul(a, b, tmp); | |
176 gf_mod(tmp, m, c); | |
177 gf_zero(tmp); | |
178 } | |
179 | |
180 /* B = 1/A mod M */ | |
181 void gf_invmod(gf_intp A, gf_intp M, gf_intp B) | |
182 { | |
183 gf_int m, n, p0, p1, p2, r, q, tmp; | |
184 | |
185 /* put all variables in known setup state */ | |
186 gf_zero(p0); | |
187 gf_zero(p2); | |
188 gf_copy(M, m); | |
189 gf_copy(A, n); | |
190 p0[0] = 1; | |
191 gf_div(m, n, p1, r); | |
192 gf_copy(p1, q); | |
193 | |
194 /* loop until r == 0 */ | |
195 while (!gf_iszero(r)) { | |
196 gf_copy(n, m); | |
197 gf_copy(r, n); | |
198 gf_div(m, n, q, r); | |
199 gf_mul(q, p1, tmp); | |
200 gf_add(tmp, p0, p2); | |
201 gf_copy(p1, p0); | |
202 gf_copy(p2, p1); | |
203 } | |
204 gf_copy(p0, B); | |
205 gf_zero(p0); | |
206 } | |
207 | |
208 /* find a square root modulo a prime. Note the number of | |
209 * elements is 2^k - 1, so we must square k-2 times to get the | |
210 * square root.. | |
211 */ | |
212 void gf_sqrt(gf_intp a, gf_intp M, gf_intp b) | |
213 { | |
214 int k; | |
215 k = gf_deg(M)-2; | |
216 gf_copy(a, b); | |
217 while (k--) | |
218 gf_mulmod(b, b, M, b); | |
219 } | |
220 | |
221 /* c = gcd(A,B) */ | |
222 void gf_gcd(gf_intp A, gf_intp B, gf_intp c) | |
223 { | |
224 gf_int a, b, r; | |
225 int n; | |
226 | |
227 gf_add(A, B, r); | |
228 n = gf_deg(r); | |
229 if (gf_deg(A) > n) { | |
230 gf_copy(A, a); | |
231 gf_copy(B, b); | |
232 } else { | |
233 gf_copy(A, b); | |
234 gf_copy(B, a); | |
235 } | |
236 | |
237 do { | |
238 gf_mod(a, b, r); | |
239 gf_copy(b, a); | |
240 gf_copy(r, b); | |
241 } while (!gf_iszero(r)); | |
242 gf_copy(a, c); | |
243 gf_zero(a); | |
244 gf_zero(b); | |
245 } | |
246 | |
247 /* returns non-zero if 'a' is irreducible */ | |
248 int gf_is_prime(gf_intp a) | |
249 { | |
250 gf_int u, tmp; | |
251 int m, n; | |
252 | |
253 gf_zero(u); | |
254 u[0] = 2; /* u(x) = x */ | |
255 m = gf_deg(a); | |
256 for (n = 0; n < (m/2); n++) { | |
257 gf_mulmod(u, u, a, u); /* u(x) = u(x)^2 mod a(x) */ | |
258 gf_copy(u, tmp); | |
259 tmp[0] ^= 2; /* tmp(x) = u(x) - x */ | |
260 gf_gcd(tmp, a, tmp); /* tmp(x) = gcd(a(x), u(x) - x) */ | |
261 if (!gf_isone(tmp)) { | |
262 return 0; | |
263 } | |
264 } | |
265 return 1; | |
266 } | |
267 | |
268 /* returns bytes required to store a gf_int */ | |
269 int gf_size(gf_intp a) | |
270 { | |
271 int n; | |
272 | |
273 n = gf_deg(a); | |
274 if (n == -1) { | |
275 return 4; | |
276 } | |
277 n = n + (32 - (n&31)); | |
278 return n/8; | |
279 } | |
280 | |
281 /* store a gf_int */ | |
282 void gf_toraw(gf_intp a, unsigned char *dst) | |
283 { | |
284 int x, n; | |
285 n = gf_size(a)/4; | |
286 for (x = 0; x < n; x++) { | |
287 STORE32L(a[x], dst); | |
288 dst += 4; | |
289 } | |
290 } | |
291 | |
292 /* read a gf_int (len == in bytes) */ | |
293 void gf_readraw(gf_intp a, unsigned char *str, int len) | |
294 { | |
295 int x; | |
296 gf_zero(a); | |
297 for (x = 0; x < len/4; x++) { | |
298 LOAD32L(a[x], str); | |
299 str += 4; | |
300 } | |
301 } | |
302 | |
303 #endif | |
304 | |
305 |