Annotation of OpenXM_contrib2/asir2000/engine/gfs.c, Revision 1.5
1.1 noro 1: /*
2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
3: * All rights reserved.
4: *
5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a ligfsted,
6: * non-exclusive and royalty-free license to use, copy, modify and
7: * redistribute, solely for non-commercial and non-profit purposes, the
8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
9: * conditions of this Agreement. For the avoidance of doubt, you acquire
10: * only a ligfsted right to use the SOFTWARE hereunder, and FLL or any
11: * third party developer retains all rights, including but not ligfsted to
12: * copyrights, in and to the SOFTWARE.
13: *
14: * (1) FLL does not grant you a license in any way for commercial
15: * purposes. You may use the SOFTWARE only for non-commercial and
16: * non-profit purposes only, such as acadegfsc, research and internal
17: * business use.
18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
19: * international copyright treaties. If you make copies of the SOFTWARE,
20: * with or without modification, as pergfstted hereunder, you shall affix
21: * to all such copies of the SOFTWARE the above copyright notice.
22: * (3) An explicit reference to this SOFTWARE and its copyright owner
23: * shall be made on your publication or presentation in any form of the
24: * results obtained by use of the SOFTWARE.
25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
26: * e-mail at risa-adgfsn@sec.flab.fujitsu.co.jp of the detailed specification
27: * for such modification or the source code of the modified part of the
28: * SOFTWARE.
29: *
30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
47: *
1.5 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/gfs.c,v 1.4 2001/03/29 09:49:58 noro Exp $
1.1 noro 49: */
50: #include "ca.h"
51:
52: /* q = p^n */
53:
1.2 noro 54: P current_gfs_ext;
55: int current_gfs_p;
1.1 noro 56: int current_gfs_q;
57: int current_gfs_q1;
58: int *current_gfs_plus1;
59: int *current_gfs_ntoi;
60: int *current_gfs_iton;
61:
62: void chsgngfs();
1.2 noro 63: void generate_defpoly_um();
64:
65: void dec_um(p,a,u)
66: int p,a;
67: UM u;
68: {
69: int i;
70:
71: for ( i = 0; a; i++, a /= p )
72: COEF(u)[i] = a%p;
73: DEG(u) = i-1;
74: }
1.1 noro 75:
76: /*
1.2 noro 77: * an element of GF(p^n) f(x)=a(n-1)*x^(n-1)+...+a(0)
78: * is encodeded to f(p).
1.1 noro 79: * current_gfs_iton[i] = r^i mod p (i=0,...,p-2)
80: * current_gfs_iton[p-1] = 0
81: */
82:
83: void setmod_sf(p,n)
84: int p,n;
85: {
1.2 noro 86: int r,i,q1,q,t,t1;
87: UM dp;
1.1 noro 88:
1.2 noro 89: for ( i = 0, q = 1; i < n; i++ )
90: q *= p;
91: dp = UMALLOC(n);
92: generate_defpoly_um(p,n,dp);
93: r = generate_primitive_root_enc(p,n,dp);
94: current_gfs_p = p;
95: current_gfs_q = q;
96: current_gfs_q1 = q1 = q-1;
1.1 noro 97: if ( n > 1 )
1.2 noro 98: umtop(CO->v,dp,¤t_gfs_ext);
99: else
100: current_gfs_ext = 0;
101: current_gfs_iton = (int *)MALLOC(q1*sizeof(int));
102: current_gfs_iton[0] = 1;
103: for ( i = 1; i < q1; i++ )
104: current_gfs_iton[i] = mulremum_enc(p,n,dp,current_gfs_iton[i-1],r);
105:
106: current_gfs_ntoi = (int *)MALLOC(q*sizeof(int));
107: current_gfs_ntoi[0] = -1;
108: for ( i = 0; i < q1; i++ )
109: current_gfs_ntoi[current_gfs_iton[i]] = i;
110:
111: current_gfs_plus1 = (int *)MALLOC(q*sizeof(int));
112: for ( i = 0; i < q1; i++ ) {
113: t = current_gfs_iton[i];
114: /* add 1 to the constant part */
115: t1 = (t/p)*p+((t+1)%p);
116: current_gfs_plus1[i] = current_gfs_ntoi[t1];
1.1 noro 117: }
118: }
119:
1.2 noro 120: void generate_defpoly_um(p,n,dp)
121: int p,n;
122: UM dp;
1.1 noro 123: {
1.2 noro 124: int i,j,a,c,q;
125: UM wf,wdf,wgcd;
1.1 noro 126:
1.2 noro 127: wf = W_UMALLOC(n);
128: wdf = W_UMALLOC(n);
129: wgcd = W_UMALLOC(n);
130: COEF(dp)[n] = 1;
131: DEG(dp) = n;
132: for ( i = 0, q = 1; i < n; i++ )
133: q *= p;
134: for ( i = 0; i < q; i++ ) {
135: for ( j = 0, a = i; a; j++, a /= p )
136: COEF(dp)[j] = a%p;
137: for ( ; j < n; j++ )
138: COEF(dp)[j] = 0;
139: cpyum(dp,wf);
140: diffum(p,dp,wdf);
141: gcdum(p,wf,wdf,wgcd);
142: if ( DEG(wgcd) >= 1 )
143: continue;
144: mini(p,dp,wf);
145: if ( DEG(wf) <= 0 )
146: return;
147: }
148: }
149:
150: int generate_primitive_root_enc(p,n,dp)
151: int p,n;
152: UM dp;
153: {
154: int i,r,rj,j,q;
155:
1.5 ! noro 156: if ( p == 2 && n == 1 )
! 157: return 1;
! 158:
1.2 noro 159: for ( i = 0, q = 1; i < n; i++ )
160: q *= p;
161: for ( r = n==1?2:p; r < q; r++ ) {
1.1 noro 162: rj = r;
1.2 noro 163: for ( j = 1; j < q-1 && rj != 1; j++ )
164: rj = mulremum_enc(p,n,dp,rj,r);
165: if ( j == q-1 )
1.1 noro 166: return r;
167: }
1.2 noro 168: }
169:
170: /* [a(p)]*[b(p)] in GF(p^n) -> [a(x)*b(x) mod dp(x)]_{x->p} */
171:
172: int mulremum_enc(p,n,dp,a,b)
173: int p,n;
174: UM dp;
175: int a,b;
176: {
177: int i,dr,r;
178: UM wa,wb,wc,wq;
179:
180: if ( n == 1 )
181: return (a*b)%p;
182: if ( !a || !b )
183: return 0;
184:
185: wa = W_UMALLOC(n);
186: dec_um(p,a,wa);
187:
188: wb = W_UMALLOC(n);
189: dec_um(p,b,wb);
190:
191: wc = W_UMALLOC(2*n);
192: wq = W_UMALLOC(2*n);
193: mulum(p,wa,wb,wc);
194: dr = divum(p,wc,dp,wq);
195: for ( i = dr, r = 0; i >= 0; i-- )
196: r = r*p+COEF(wc)[i];
197: return r;
1.5 ! noro 198: }
! 199:
! 200: void gfs_galois_action(a,e,c)
! 201: GFS a;
! 202: Q e;
! 203: GFS *c;
! 204: {
! 205: Q p;
! 206: int i,k;
! 207: GFS t,s;
! 208:
! 209: t = a;
! 210: k = QTOS(e);
! 211: STOQ(current_gfs_p,p);
! 212: for ( i = 0; i < k; i++ ) {
! 213: pwrgfs(t,p,&s); t = s;
! 214: }
! 215: *c = t;
! 216: }
! 217:
! 218: void qtogfs(a,c)
! 219: Q a;
! 220: GFS *c;
! 221: {
! 222: int s;
! 223:
! 224: s = QTOS(a)%current_gfs_q;
! 225: if ( s < 0 )
! 226: s += current_gfs_q;
! 227: if ( !s )
! 228: *c = 0;
! 229: else
! 230: MKGFS(current_gfs_ntoi[s],*c);
1.1 noro 231: }
232:
233: void mqtogfs(a,c)
234: MQ a;
235: GFS *c;
236: {
237: if ( !a )
238: *c = 0;
239: else {
240: MKGFS(current_gfs_ntoi[CONT(a)],*c);
241: }
242: }
243:
244: void gfstomq(a,c)
245: GFS a;
246: MQ *c;
247: {
248: if ( !a )
249: *c = 0;
250: else {
251: UTOMQ(current_gfs_iton[CONT(a)],*c);
252: }
253: }
254:
255: void ntogfs(a,b)
256: Obj a;
257: GFS *b;
258: {
259: P t;
260:
261: if ( !current_gfs_q1 )
262: error("addgfs : current_gfs_q is not set");
263: if ( !a || (OID(a)==O_N && NID(a) == N_GFS) )
264: *b = (GFS)a;
265: else if ( OID(a) == O_N && NID(a) == N_M )
266: mqtogfs(a,b);
267: else if ( OID(a) == O_N && NID(a) == N_Q ) {
1.4 noro 268: ptomp(current_gfs_p,(P)a,&t); mqtogfs(t,b);
1.1 noro 269: } else
270: error("ntogfs : invalid argument");
271: }
272:
273: void addgfs(a,b,c)
274: GFS a,b;
275: GFS *c;
276: {
277: int ai,bi,ci;
278: GFS z;
279:
280: ntogfs(a,&z); a = z;
281: ntogfs(b,&z); b = z;
282: if ( !a )
283: *c = b;
284: else if ( !b )
285: *c = a;
286: else {
287: ai = CONT(a); bi = CONT(b);
288: if ( ai > bi ) {
289: /* tab[ai]+tab[bi] = tab[bi](tab[ai-bi]+1) */
290: ci = current_gfs_plus1[ai-bi];
291: if ( ci < 0 )
292: *c = 0;
293: else {
294: ci += bi;
295: if ( ci >= current_gfs_q1 )
296: ci -= current_gfs_q1;
297: MKGFS(ci,*c);
298: }
299: } else {
300: /* tab[ai]+tab[bi] = tab[ai](tab[bi-ai]+1) */
301: ci = current_gfs_plus1[bi-ai];
302: if ( ci < 0 )
303: *c = 0;
304: else {
305: ci += ai;
306: if ( ci >= current_gfs_q1 )
307: ci -= current_gfs_q1;
308: MKGFS(ci,*c);
309: }
310: }
311: }
312: }
313:
314: void subgfs(a,b,c)
315: GFS a,b;
316: GFS *c;
317: {
318: GFS t,z;
319:
320: ntogfs(a,&z); a = z;
321: ntogfs(b,&z); b = z;
322: if ( !b )
323: *c = a;
324: else {
325: chsgngfs(b,&t);
326: addgfs(a,t,c);
327: }
328: }
329:
330: void mulgfs(a,b,c)
331: GFS a,b;
332: GFS *c;
333: {
334: int ai;
335: GFS z;
336:
337: ntogfs(a,&z); a = z;
338: ntogfs(b,&z); b = z;
339: if ( !a || !b )
340: *c = 0;
341: else {
342: ai = CONT(a) + CONT(b);
343: if ( ai >= current_gfs_q1 )
344: ai -= current_gfs_q1;
345: MKGFS(ai,*c);
346: }
347: }
348:
349: void divgfs(a,b,c)
350: GFS a,b;
351: GFS *c;
352: {
353: int ai;
354: GFS z;
355:
356: ntogfs(a,&z); a = z;
357: ntogfs(b,&z); b = z;
358: if ( !b )
359: error("divgfs : division by 0");
360: else if ( !a )
361: *c = 0;
362: else {
363: ai = CONT(a) - CONT(b);
364: if ( ai < 0 )
365: ai += current_gfs_q1;
366: MKGFS(ai,*c);
367: }
368: }
369:
370: void chsgngfs(a,c)
371: GFS a,*c;
372: {
373: int ai;
374: GFS z;
375:
376: ntogfs(a,&z); a = z;
377: if ( !a )
378: *c = 0;
379: else if ( current_gfs_q1&1 )
380: *c = a;
381: else {
382: /* r^((q-1)/2) = -1 */
383: ai = CONT(a)+(current_gfs_q1>>1);
384: if ( ai >= current_gfs_q1 )
385: ai -= current_gfs_q1;
386: MKGFS(ai,*c);
387: }
388: }
389:
390: void pwrgfs(a,b,c)
391: GFS a;
392: Q b;
393: GFS *c;
394: {
395: N an,tn,rn;
396: GFS t,s,z;
397:
398: ntogfs(a,&z); a = z;
399: if ( !b )
400: MKGFS(0,*c);
401: else if ( !a )
402: *c = 0;
403: else {
404: STON(CONT(a),an); muln(an,NM(b),&tn);
405: STON(current_gfs_q1,an); remn(tn,an,&rn);
406: if ( !rn )
407: MKGFS(0,*c);
408: else if ( SGN(b) > 0 )
409: MKGFS(BD(rn)[0],*c);
410: else {
411: MKGFS(0,t);
412: MKGFS(BD(rn)[0],s);
413: divgfs(t,s,c);
414: }
415: }
416: }
417:
418: int cmpgfs(a,b)
419: GFS a,b;
420: {
421: GFS z;
422:
423: ntogfs(a,&z); a = z;
424: if ( !a )
425: return !b ? 0 : -1;
426: else
427: if ( !b )
428: return 1;
429: else {
430: if ( CONT(a) > CONT(b) )
431: return 1;
432: else if ( CONT(a) < CONT(b) )
433: return -1;
434: else
435: return 0;
436: }
1.3 noro 437: }
438:
439: void randomgfs(r)
440: GFS *r;
441: {
442: unsigned int t;
443:
444: if ( !current_gfs_q1 )
445: error("addgfs : current_gfs_q is not set");
446: t = mt_genrand()%current_gfs_q;
447: if ( !t )
448: *r = 0;
449: else {
450: if ( t == current_gfs_q1 )
451: t = 0;
452: MKGFS(t,*r);
453: }
1.1 noro 454: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>