Annotation of OpenXM_contrib2/asir2000/builtin/ec.c, Revision 1.1.1.1
1.1 noro 1: /* $OpenXM: OpenXM/src/asir99/builtin/ec.c,v 1.1.1.1 1999/11/10 08:12:25 noro Exp $ */
2: #include "ca.h"
3: #include "parse.h"
4: #include "inline.h"
5:
6: /*
7: * Elliptic curve related functions
8: *
9: * Argument specifications
10: * Point = vector(x,y,z) (projective representation)
11: * ECInfo = vector(a,b,p)
12: * a,b : integer for GF(p), GF2N for GF(2^n)
13: * p : integer for GF(p), polynomial for GF(2^n)
14: *
15: */
16:
17: struct oKeyIndexPair {
18: unsigned int key;
19: int index;
20: };
21:
22: void Psha1();
23: void Psha1_ec();
24: void Pecm_add_ff();
25: void Pecm_chsgn_ff();
26: void Pecm_sub_ff();
27: void Pecm_compute_all_key_homo_ff();
28: void Pnextvect1(),Psort_ktarray(),Pecm_find_match(),Pseparate_vect();
29: void Pecm_set_addcounter();
30: void Pecm_count_order();
31:
32: void ecm_add_ff(VECT,VECT,VECT,VECT *);
33: void ecm_add_gfp(VECT,VECT,VECT,VECT *);
34: void ecm_add_gf2n(VECT,VECT,VECT,VECT *);
35:
36: void ecm_chsgn_ff(VECT,VECT *);
37: void ecm_sub_ff(VECT,VECT,VECT,VECT *);
38:
39: void compute_all_key_homo_gfp(VECT *,int,unsigned int *);
40: void compute_all_key_homo_gf2n(VECT *,int,unsigned int *);
41:
42: unsigned int separate_vect(double *,int);
43: void ecm_find_match(unsigned int *,int,unsigned int *,int,LIST *);
44: int find_match(unsigned int,unsigned int *,int);
45:
46: void sort_ktarray(VECT,VECT,LIST *);
47: int comp_kip(struct oKeyIndexPair *,struct oKeyIndexPair *);
48:
49: int nextvect1(VECT,VECT);
50:
51: unsigned int ecm_count_order_gfp(unsigned int,unsigned int,unsigned int);
52: unsigned int ecm_count_order_gf2n(UP2,GF2N,GF2N);
53:
54: void sha_memory(unsigned char *,unsigned int,unsigned int *);
55:
56: unsigned int ecm_addcounter;
57: extern int current_ff,lm_lazy;
58:
59: struct ftab ec_tab[] = {
60: /* point addition */
61: {"ecm_add_ff",Pecm_add_ff,3},
62:
63: /* point change sign */
64: {"ecm_chsgn_ff",Pecm_chsgn_ff,1},
65:
66: /* point subtraction */
67: {"ecm_sub_ff",Pecm_sub_ff,3},
68:
69: /* key computation for sort and match */
70: {"ecm_compute_all_key_homo_ff",Pecm_compute_all_key_homo_ff,1},
71:
72: /* exhausitve search of rational points */
73: {"ecm_count_order",Pecm_count_order,1},
74:
75: /* common functions */
76: {"nextvect1",Pnextvect1,2},
77: {"sort_ktarray",Psort_ktarray,2},
78: {"separate_vect",Pseparate_vect,1},
79: {"ecm_find_match",Pecm_find_match,2},
80: {"ecm_set_addcounter",Pecm_set_addcounter,-1},
81: {"sha1",Psha1,1},
82: #if 0
83: {"sha1_free",Psha1_free,1},
84: #endif
85: {0,0,0},
86: };
87:
88: void Psha1(arg,rp)
89: NODE arg;
90: Q *rp;
91: {
92: unsigned char *s;
93: unsigned int digest[5];
94: int i,j,l,bl,n;
95: unsigned int t;
96: N z,r;
97:
98: asir_assert(ARG0(arg),O_N,"sha1_free");
99: z = NM((Q)ARG0(arg));
100: n = PL(z);
101: l = n_bits(z);
102: bl = (l+7)/8;
103: s = (unsigned char *)MALLOC(bl);
104: for ( i = 0, j = bl-1; i < n; i++ ) {
105: t = BD(z)[i];
106: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
107: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
108: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
109: if ( j >= 0 ) s[j--] = t;
110: }
111: sha_memory(s,bl,digest);
112: r = NALLOC(5);
113: for ( i = 0; i < 5; i++ )
114: BD(r)[i] = digest[4-i];
115: for ( i = 4; i >= 0 && !BD(r)[i]; i-- );
116: if ( i < 0 )
117: *rp = 0;
118: else {
119: PL(r) = i+1;
120: NTOQ(r,1,*rp);
121: }
122: }
123:
124: #if 0
125: void Psha1_ec(arg,rp)
126: NODE arg;
127: Q *rp;
128: {
129: #include <fj_crypt.h>
130: SHS_CTX context;
131: unsigned char *s;
132: int i,j,l,bl,n;
133: unsigned int t;
134: N z,r;
135: extern int little_endian;
136:
137: asir_assert(ARG0(arg),O_N,"sha1");
138: z = NM((Q)ARG0(arg));
139: n = PL(z);
140: l = n_bits(z);
141: bl = (l+7)/8;
142: s = (unsigned char *)MALLOC(bl);
143: for ( i = 0, j = bl-1; i < n; i++ ) {
144: t = BD(z)[i];
145: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
146: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
147: if ( j >= 0 ) s[j--] = t&0xff; t>>=8;
148: if ( j >= 0 ) s[j--] = t;
149: }
150: SHSInit(&context);
151: SHSUpdate(&context,s,bl);
152: SHSFinal(&context);
153: r = NALLOC(5);
154: if ( little_endian )
155: for ( i = 0; i < 5; i++ ) {
156: t = context.digest[4-i];
157: BD(r)[i] = (t>>24)|((t&0xff0000)>>8)|((t&0xff00)<<8)|(t<<24);
158: } else
159: for ( i = 0; i < 5; i++ )
160: BD(r)[i] = context.digest[4-i];
161: for ( i = 4; i >= 0 && !BD(r)[i]; i-- );
162: if ( i < 0 )
163: *rp = 0;
164: else {
165: PL(r) = i+1;
166: NTOQ(r,1,*rp);
167: }
168: }
169: #endif
170:
171: void Pecm_count_order(arg,rp)
172: NODE arg;
173: Q *rp;
174: {
175: N p;
176: UP2 d;
177: Obj a,b;
178: unsigned int p0,a0,b0,ord;
179: VECT ec;
180: Obj *vb;
181:
182: switch ( current_ff ) {
183: case FF_GFP:
184: getmod_lm(&p);
185: if ( n_bits(p) > 32 )
186: error("ecm_count_order : ground field too large");
187: p0 = BD(p)[0];
188: ec = (VECT)ARG0(arg);
189: vb = (Obj *)BDY(ec); simp_ff(vb[0],&a); simp_ff(vb[1],&b);
190: a0 = a?BD(BDY((LM)a))[0]:0;
191: b0 = b?BD(BDY((LM)b))[0]:0;
192: ord = ecm_count_order_gfp(p0,a0,b0);
193: UTOQ(ord,*rp);
194: break;
195: case FF_GF2N:
196: getmod_gf2n(&d);
197: if ( degup2(d) > 10 )
198: error("ecm_count_order : ground field too large");
199: ec = (VECT)ARG0(arg);
200: vb = (Obj *)BDY(ec); simp_ff(vb[0],&a); simp_ff(vb[1],&b);
201: ord = ecm_count_order_gf2n(d,(GF2N)a,(GF2N)b);
202: UTOQ(ord,*rp);
203: break;
204: default:
205: error("ecm_count_order : current_ff is not set");
206: }
207: }
208:
209: void Pecm_set_addcounter(arg,rp)
210: NODE arg;
211: Q *rp;
212: {
213: if ( arg )
214: ecm_addcounter = QTOS((Q)ARG0(arg));
215: UTOQ(ecm_addcounter,*rp);
216: }
217:
218: void Pecm_compute_all_key_homo_ff(arg,rp)
219: NODE arg;
220: VECT *rp;
221: {
222: Obj mod;
223: unsigned int *ka;
224: int len,i;
225: VECT *pa;
226: VECT r,v;
227: LIST *vb;
228: USINT *b;
229:
230: v = (VECT)ARG0(arg);
231: len = v->len;
232: vb = (LIST *)v->body;
233: pa = (VECT *)ALLOCA(len*sizeof(VECT));
234: ka = (unsigned int *)ALLOCA(len*sizeof(unsigned int));
235: for ( i = 0; i < len; i++ )
236: pa[i] = (VECT)BDY(NEXT(BDY(vb[i])));
237: switch ( current_ff ) {
238: case FF_GFP:
239: compute_all_key_homo_gfp(pa,len,ka); break;
240: case FF_GF2N:
241: compute_all_key_homo_gf2n(pa,len,ka); break;
242: default:
243: error("ecm_compute_all_key_homo_ff : current_ff is not set");
244: }
245: MKVECT(r,len); *rp = r;
246: b = (USINT *)r->body;
247: for ( i = 0; i < len; i++ )
248: MKUSINT(b[i],ka[i]);
249: }
250:
251: void Psort_ktarray(arg,rp)
252: NODE arg;
253: LIST *rp;
254: {
255: sort_ktarray((VECT)ARG0(arg),(VECT)ARG1(arg),rp);
256: }
257:
258: void Pecm_add_ff(arg,rp)
259: NODE arg;
260: VECT *rp;
261: {
262: ecm_add_ff(ARG0(arg),ARG1(arg),ARG2(arg),rp);
263: }
264:
265: void Pecm_sub_ff(arg,rp)
266: NODE arg;
267: VECT *rp;
268: {
269: ecm_sub_ff(ARG0(arg),ARG1(arg),ARG2(arg),rp);
270: }
271:
272: void Pecm_chsgn_ff(arg,rp)
273: NODE arg;
274: VECT *rp;
275: {
276: ecm_chsgn_ff(ARG0(arg),rp);
277: }
278:
279: void Pnextvect1(arg,rp)
280: NODE arg;
281: Q *rp;
282: {
283: int index;
284:
285: index = nextvect1(ARG0(arg),ARG1(arg));
286: STOQ(index,*rp);
287: }
288:
289: /* XXX at least n < 32 must hold. What is the strict restriction for n ? */
290:
291: void Pseparate_vect(arg,rp)
292: NODE arg;
293: LIST *rp;
294: {
295: VECT v;
296: int n,i;
297: Q *b;
298: double *w;
299: unsigned int s;
300: NODE ns,nc,t,t1;
301: Q iq;
302: LIST ls,lc;
303:
304: v = (VECT)ARG0(arg);
305: n = v->len; b = (Q *)v->body;
306: w = (double *)ALLOCA(n*sizeof(double));
307: for ( i = 0; i < n; i++ )
308: w[i] = (double)QTOS(b[i]);
309: s = separate_vect(w,n);
310: ns = nc = 0;
311: for ( i = n-1; i >= 0; i-- )
312: if ( s & (1<<i) ) {
313: STOQ(i,iq); MKNODE(t,iq,ns); ns = t;
314: } else {
315: STOQ(i,iq); MKNODE(t,iq,nc); nc = t;
316: }
317: MKLIST(ls,ns); MKLIST(lc,nc);
318: MKNODE(t,lc,0); MKNODE(t1,ls,t);
319: MKLIST(*rp,t1);
320: }
321:
322: void Pecm_find_match(arg,rp)
323: NODE arg;
324: LIST *rp;
325: {
326: VECT g,b;
327: int ng,nb,i;
328: USINT *p;
329: unsigned int *kg,*kb;
330:
331: g = (VECT)ARG0(arg); ng = g->len;
332: kg = (unsigned int *)ALLOCA(ng*sizeof(unsigned int));
333: for ( i = 0, p = (USINT *)g->body; i < ng; i++ )
334: kg[i] = p[i]?BDY(p[i]):0;
335: b = (VECT)ARG1(arg); nb = b->len;
336: kb = (unsigned int *)ALLOCA(nb*sizeof(unsigned int));
337: for ( i = 0, p = (USINT *)b->body; i < nb; i++ )
338: kb[i] = p[i]?BDY(p[i]):0;
339: ecm_find_match(kg,ng,kb,nb,rp);
340: }
341:
342: void ecm_add_ff(p1,p2,ec,pr)
343: VECT p1,p2,ec;
344: VECT *pr;
345: {
346: if ( !p1 )
347: *pr = p2;
348: else if ( !p2 )
349: *pr = p1;
350: else {
351: switch ( current_ff ) {
352: case FF_GFP:
353: ecm_add_gfp(p1,p2,ec,pr); break;
354: case FF_GF2N:
355: ecm_add_gf2n(p1,p2,ec,pr); break;
356: default:
357: error("ecm_add_ff : current_ff is not set");
358: }
359: }
360: }
361:
362: /* ec = [AX,BC] */
363:
364: void ecm_add_gf2n(p1,p2,ec,rp)
365: VECT p1,p2,ec;
366: VECT *rp;
367: {
368: GF2N ax,bc,a0,a1,a2,b0,b1,b2;
369: GF2N a2b0,a0b2,a2b1,a1b2,a02,a04,a22,a24,a0a2,a0a22,a1a2;
370: GF2N t,s,u,r0,r1,r00,r01,r02,r002,r003,r022,r02q;
371: VECT r;
372: GF2N *vb,*rb;
373:
374: ecm_addcounter++;
375: /* addition with O */
376: if ( !p1 ) {
377: *rp = p2;
378: return;
379: }
380: if ( !p2 ) {
381: *rp = p1;
382: return;
383: }
384: vb = (GF2N *)BDY(ec); ax = vb[0]; bc = vb[1];
385: vb = (GF2N *)BDY(p1); a0 = vb[0]; a1 = vb[1]; a2 = vb[2];
386: vb = (GF2N *)BDY(p2); b0 = vb[0]; b1 = vb[1]; b2 = vb[2];
387:
388: mulgf2n(a2,b0,&a2b0); mulgf2n(a0,b2,&a0b2);
389: if ( !cmpgf2n(a2b0,a0b2) ) {
390: mulgf2n(a2,b1,&a2b1);
391: mulgf2n(a1,b2,&a1b2);
392: if ( !cmpgf2n(a2b1,a1b2) ) {
393: if ( !a0 )
394: *rp = 0;
395: else {
396: squaregf2n(a0,&a02); squaregf2n(a02,&a04);
397: squaregf2n(a2,&a22); squaregf2n(a22,&a24);
398: mulgf2n(a0,a2,&a0a2); squaregf2n(a0a2,&a0a22);
399: mulgf2n(bc,a24,&t); addgf2n(a04,t,&r0);
400: mulgf2n(a04,a0a2,&t); mulgf2n(a1,a2,&a1a2);
401: addgf2n(a02,a1a2,&s); addgf2n(s,a0a2,&u);
402: mulgf2n(u,r0,&s); addgf2n(t,s,&r1);
403:
404: MKVECT(r,3); rb = (GF2N *)r->body;
405: mulgf2n(r0,a0a2,&rb[0]); rb[1] = r1; mulgf2n(a0a22,a0a2,&rb[2]);
406: *rp = r;
407: }
408: } else
409: *rp = 0;
410: } else {
411: mulgf2n(a1,b2,&a1b2); addgf2n(a0b2,a2b0,&r00);
412: mulgf2n(a2,b1,&t); addgf2n(a1b2,t,&r01); mulgf2n(a2,b2,&r02);
413: squaregf2n(r00,&r002); mulgf2n(r002,r00,&r003);
414:
415: addgf2n(r00,r01,&t); mulgf2n(t,r01,&s); mulgf2n(s,r02,&t);
416: if ( ax ) {
417: mulgf2n(r02,ax,&r02q);
418: addgf2n(t,r003,&s); mulgf2n(r02q,r002,&t); addgf2n(s,t,&r0);
419: } else
420: addgf2n(t,r003,&r0);
421:
422: mulgf2n(a0b2,r002,&t); addgf2n(t,r0,&s); mulgf2n(r01,s,&t);
423: mulgf2n(r002,a1b2,&s); addgf2n(r0,s,&u); mulgf2n(r00,u,&s);
424: addgf2n(t,s,&r1);
425:
426: MKVECT(r,3); rb = (GF2N *)r->body;
427: mulgf2n(r0,r00,&rb[0]); rb[1] = r1; mulgf2n(r003,r02,&rb[2]);
428: *rp = r;
429: }
430: }
431:
432: extern LM THREE_LM,FOUR_LM,EIGHT_LM;
433:
434: /* 0 < p < 2^16, 0 <= a,b < p */
435:
436: unsigned int ecm_count_order_gfp(p,a,b)
437: unsigned int p,a,b;
438: {
439: unsigned int x,y,rhs,ord,t;
440:
441: for ( x = 0, ord = 1; x < p; x++ ) {
442: DMAR(x,x,a,p,t) /* t = x^2+a mod p */
443: DMAR(t,x,b,p,rhs) /* rhs = x*(x^2+a)+b mod p */
444: if ( !rhs )
445: ord++;
446: else if ( small_jacobi(rhs,p)==1 )
447: ord+=2;
448: }
449: return ord;
450: }
451:
452: unsigned int ecm_count_order_gf2n(d,a,b)
453: UP2 d;
454: GF2N a,b;
455: {
456: error("ecm_count_order_gf2n : not implemented yet");
457: }
458:
459: /* ec = [AX,BC] */
460:
461: void ecm_add_gfp(p1,p2,ec,pr)
462: VECT p1,p2,ec;
463: VECT *pr;
464: {
465: LM aa,bb,x1,y1,z1,x2,y2,z2,x1z2,v1,y1z2,u1,u2,v2,v3,z1z2;
466: LM v2x1z2,a1,x3,y3,z3,w1,s1,s2,s3,s1y1,b1,h1;
467: LM t,s,u;
468: LM *vb;
469: VECT r;
470:
471: ecm_addcounter++;
472: /* addition with O */
473: if( !p1 ) {
474: *pr = p2;
475: return;
476: }
477: if( !p2 ) {
478: *pr = p1;
479: return;
480: }
481:
482: /* set parameters */
483:
484: /* aa = ec[0]; bb = ec[1]; */
485: vb = (LM *)BDY(ec); aa = vb[0]; bb = vb[1];
486:
487: /* x1 = p1[0]; y1 = p1[1]; z1 = p1[2]; */
488: vb = (LM *)BDY(p1); x1 = vb[0]; y1 = vb[1]; z1 = vb[2];
489:
490: /* x2 = p2[0]; y2 = p2[1]; z2 = p2[2]; */
491: vb = (LM *)BDY(p2); x2 = vb[0]; y2 = vb[1]; z2 = vb[2];
492:
493: /* addition */
494:
495: /* x1z2 = (x1*z2) %p; */
496: mullm(x1,z2,&x1z2);
497:
498: /* v1 = (x2*z1-x1z2) %p; */
499: lm_lazy = 1;
500: mullm(x2,z1,&t); sublm(t,x1z2,&s);
501: lm_lazy = 0; simplm(s,&v1);
502:
503: /* y1z2 = (y1*z2) %p; */
504: mullm(y1,z2,&y1z2);
505:
506: /* u1 = (y2*z1-y1z2) %p; */
507: lm_lazy = 1;
508: mullm(y2,z1,&t); sublm(t,y1z2,&s);
509: lm_lazy = 0; simplm(s,&u1);
510:
511: if( v1 != 0 ) {
512: /* u2 = (u1*u1) %p; */
513: mullm(u1,u1,&u2);
514:
515: /* v2 = (v1*v1) %p; */
516: mullm(v1,v1,&v2);
517:
518: /* v3 = (v1*v2) %p; */
519: mullm(v1,v2,&v3);
520:
521: /* z1z2 = (z1*z2) %p; */
522: mullm(z1,z2,&z1z2);
523:
524: /* v2x1z2 = (v2*x1z2) %p; */
525: mullm(v2,x1z2,&v2x1z2);
526:
527: /* a1 = (u2*z1z2-v3-2*v2x1z2) %p; */
528: lm_lazy = 1;
529: mullm(u2,z1z2,&t); addlm(v2x1z2,v2x1z2,&s);
530: addlm(v3,s,&u); sublm(t,u,&s);
531: lm_lazy = 0; simplm(s,&a1);
532:
533: /* x3 = ( v1 * a1 ) %p; */
534: mullm(v1,a1,&x3);
535:
536: /* y3 = ( u1 * ( v2x1z2 - a1 ) - v3 * y1z2 ) %p; */
537: lm_lazy = 1;
538: sublm(v2x1z2,a1,&t); mullm(u1,t,&s); mullm(v3,y1z2,&u); sublm(s,u,&t);
539: lm_lazy = 0; simplm(t,&y3);
540:
541: /* z3 = ( v3 * z1z2 ) %p; */
542: mullm(v3,z1z2,&z3);
543: } else if( u1 == 0 ) {
544: /* w1 = (aa*z1*z1+3*x1*x1) %p; */
545: lm_lazy = 1;
546: mullm(z1,z1,&t); mullm(aa,t,&s);
547: mullm(x1,x1,&t); mullm(THREE_LM,t,&u); addlm(s,u,&t);
548: lm_lazy = 0; simplm(t,&w1);
549:
550: /* s1 = (y1*z1) %p; */
551: mullm(y1,z1,&s1);
552:
553: /* s2 = (s1*s1) %p; */
554: mullm(s1,s1,&s2);
555:
556: /* s3 = (s1*s2) %p; */
557: mullm(s1,s2,&s3);
558:
559: /* s1y1 = (s1*y1) %p; */
560: mullm(s1,y1,&s1y1);
561:
562: /* b1 = (s1y1*x1) %p; */
563: mullm(s1y1,x1,&b1);
564:
565: /* h1 = (w1*w1-8*b1) %p; */
566: lm_lazy = 1;
567: mullm(w1,w1,&t); mullm(EIGHT_LM,b1,&s); sublm(t,s,&u);
568: lm_lazy = 0; simplm(u,&h1);
569:
570: /* x3 = ( 2 * h1 * s1 ) %p; */
571: lm_lazy = 1;
572: mullm(h1,s1,&t); addlm(t,t,&s);
573: lm_lazy = 0; simplm(s,&x3);
574:
575: /* y3 = ( w1 * ( 4 * b1 - h1 ) - 8 * s1y1 * s1y1 ) %p; */
576: lm_lazy = 1;
577: mullm(FOUR_LM,b1,&t); sublm(t,h1,&s); mullm(w1,s,&u);
578: mullm(s1y1,s1y1,&t); mullm(EIGHT_LM,t,&s); sublm(u,s,&t);
579: lm_lazy = 0; simplm(t,&y3);
580:
581: /* z3 = ( 8 * s3 ) %p; */
582: mullm(EIGHT_LM,s3,&z3);
583: } else {
584: *pr = 0;
585: return;
586: }
587: if ( !z3 )
588: *pr = 0;
589: else {
590: MKVECT(r,3); *pr = r;
591: vb = (LM *)BDY(r); vb[0] = x3; vb[1] = y3; vb[2] = z3;
592: }
593: }
594:
595: void ecm_chsgn_ff(p,pr)
596: VECT p;
597: VECT *pr;
598: {
599: Obj m,x,y,z;
600: LM tl;
601: GF2N tg;
602: Obj *vb;
603: VECT r;
604:
605: if( !p ) {
606: *pr = 0;
607: return;
608: }
609:
610: /* x = p[0]; y = p[1]; z = p[2]; */
611: vb = (Obj *)BDY(p); x = vb[0]; y = vb[1]; z = vb[2];
612: switch ( current_ff ) {
613: case FF_GFP:
614: if ( !y )
615: *pr = p;
616: else {
617: chsgnlm((LM)y,&tl);
618: MKVECT(r,3); *pr = r;
619: vb = (Obj *)BDY(r); vb[0] = x; vb[1] = (Obj)tl; vb[2] = z;
620: }
621: break;
622: case FF_GF2N:
623: addgf2n((GF2N)x,(GF2N)y,&tg);
624: MKVECT(r,3); *pr = r;
625: vb = (Obj *)BDY(r); vb[0] = x; vb[1] = (Obj)tg; vb[2] = z;
626: break;
627: default:
628: error("ecm_chsgn_ff : current_ff is not set");
629: }
630: }
631:
632: void ecm_sub_ff(p1,p2,ec,pr)
633: VECT p1,p2,ec;
634: VECT *pr;
635: {
636: VECT mp2;
637:
638: ecm_chsgn_ff(p2,&mp2);
639: ecm_add_ff(p1,mp2,ec,pr);
640: }
641:
642: /* tplist = [[t,p],...]; t:interger, p=[p0,p1]:point (vector) */
643:
644: int comp_kip(a,b)
645: struct oKeyIndexPair *a,*b;
646: {
647: unsigned int ka,kb;
648:
649: ka = a->key; kb = b->key;
650: if ( ka > kb )
651: return 1;
652: else if ( ka < kb )
653: return -1;
654: else
655: return 0;
656: }
657:
658: #define EC_GET_XZ(p,x,z) \
659: if ( !(p) ) {\
660: (x)=0; (z)=(LM)ONE;\
661: } else { \
662: LM *vb;\
663: vb = (LM *)BDY((VECT)(p));\
664: (x) = vb[0]; (z) = vb[2];\
665: }
666:
667: #define EC_GET_XZ_GF2N(p,x,z) \
668: if ( !(p) ) {\
669: (x)=0; (z)=(GF2N)ONE;\
670: } else { \
671: GF2N *vb;\
672: vb = (GF2N *)BDY((VECT)(p));\
673: (x) = vb[0]; (z) = vb[2];\
674: }
675:
676: void compute_all_key_homo_gfp(pa,len,ka)
677: VECT *pa;
678: int len;
679: unsigned int *ka;
680: {
681: LM *b,*x,*z;
682: int i;
683: LM t,s,m;
684: N lm;
685: Q mod;
686:
687: b = (LM *)ALLOCA((len+1)*sizeof(LM));
688: x = (LM *)ALLOCA(len*sizeof(LM));
689: z = (LM *)ALLOCA(len*sizeof(LM));
690: MKLM(ONEN,b[0]);
691: for ( i = 1; i <= len; i++ ) {
692: EC_GET_XZ(pa[i-1],x[i-1],z[i-1]);
693: mullm(b[i-1],z[i-1],&b[i]);
694: }
695: /* b[0] = 1 */
696: divlm(b[0],b[len],&m);
697: for ( i = len-1; i >= 0; i-- ) {
698: mullm(m,b[i],&s); mullm(s,x[i],&t); s = t;
699: ka[i] = s ? s->body->b[0] : 0; ka[i] |= 0x80000000;
700: mullm(m,z[i],&s); m = s;
701: }
702: }
703:
704: void compute_all_key_homo_gf2n(pa,len,ka)
705: VECT *pa;
706: int len;
707: unsigned int *ka;
708: {
709: GF2N *b,*x,*z;
710: int i;
711: GF2N t,s,m;
712:
713: b = (GF2N *)ALLOCA((len+1)*sizeof(Q));
714: x = (GF2N *)ALLOCA(len*sizeof(Q));
715: z = (GF2N *)ALLOCA(len*sizeof(Q));
716: MKGF2N(ONEUP2,b[0]);
717: for ( i = 1; i <= len; i++ ) {
718: EC_GET_XZ_GF2N(pa[i-1],x[i-1],z[i-1]);
719: mulgf2n(b[i-1],z[i-1],&b[i]);
720: }
721: invgf2n(b[len],&m);
722: for ( i = len-1; i >= 0; i-- ) {
723: mulgf2n(m,b[i],&s); mulgf2n(s,x[i],&t); s = t;
724: ka[i] = s ? s->body->b[0] : 0; ka[i] |= 0x80000000;
725: mulgf2n(m,z[i],&s); m = s;
726: }
727: }
728:
729: unsigned int separate_vect(v,n)
730: double *v;
731: int n;
732: {
733: unsigned int max = 1<<n;
734: unsigned int i,j,i0;
735: double all,a,total,m;
736:
737: for ( i = 0, all = 1; i < (unsigned int)n; i++ )
738: all *= v[i];
739:
740: for ( i = 0, m = 0; i < max; i++ ) {
741: for ( a = 1, j = 0; j < (unsigned int)n; j++ )
742: if ( i & (1<<j) )
743: a *= v[j];
744: total = a+(all/a)*2;
745: if ( !m || total < m ) {
746: m = total;
747: i0 = i;
748: }
749: }
750: return i0;
751: }
752:
753: void ecm_find_match(g,ng,b,nb,r)
754: unsigned int *g;
755: int ng;
756: unsigned int *b;
757: int nb;
758: LIST *r;
759: {
760: int i,j;
761: Q iq,jq;
762: NODE n0,n1,c0,c;
763: LIST l;
764:
765: for ( i = 0, c0 = 0; i < ng; i++ ) {
766: j = find_match(g[i],b,nb);
767: if ( j >= 0 ) {
768: STOQ(i,iq); STOQ(j,jq);
769: MKNODE(n1,jq,0); MKNODE(n0,iq,n1); MKLIST(l,n0);
770: NEXTNODE(c0,c);
771: BDY(c) = (pointer)l;
772: }
773: }
774: if ( c0 )
775: NEXT(c) = 0;
776: MKLIST(*r,c0);
777: }
778:
779: int find_match(k,key,n)
780: unsigned int k;
781: unsigned int *key;
782: int n;
783: {
784: int s,e,m;
785:
786: for ( s = 0, e = n; (e-s) > 1; ) {
787: m = (s+e)/2;
788: if ( k==key[m] )
789: return m;
790: else if ( k > key[m] )
791: s = m;
792: else
793: e = m;
794: }
795: if ( k == key[s] )
796: return s;
797: else
798: return -1;
799: }
800:
801: int nextvect1(vect,bound)
802: VECT vect,bound;
803: {
804: int size,i,a;
805: Q *vb,*bb;
806:
807: size = vect->len;
808: vb = (Q *)vect->body;
809: bb = (Q *)bound->body;
810: for ( i = size-1; i >= 0; i-- )
811: if ( (a=QTOS(vb[i])) < QTOS(bb[i]) ) {
812: a++; STOQ(a,vb[i]);
813: break;
814: } else
815: vb[i] = 0;
816: return i;
817: }
818:
819: void sort_ktarray(karray,tarray,rp)
820: VECT karray,tarray;
821: LIST *rp;
822: {
823: LIST *lb;
824: NODE r,r1;
825: int i,i0,k,len,same,tsame;
826: struct oKeyIndexPair *kip;
827: VECT key,value,v;
828: Q *tb,*samebuf;
829: USINT *kb;
830: Obj *svb;
831: USINT *skb;
832:
833: len = karray->len;
834: kb = (USINT *)karray->body;
835:
836: kip = (struct oKeyIndexPair *)ALLOCA(len*sizeof(struct oKeyIndexPair));
837: for ( i = 0; i < len; i++ ) {
838: kip[i].key = BDY(kb[i]); kip[i].index = i;
839: }
840: qsort((void *)kip,len,sizeof(struct oKeyIndexPair),
841: (int (*)(const void *,const void *))comp_kip);
842:
843: for ( same = tsame = i = i0 = 0, k = 1; i < len; i++, tsame++ )
844: if ( kip[i0].key != kip[i].key ) {
845: i0 = i; k++;
846: same = MAX(tsame,same);
847: tsame = 0;
848: }
849: same = MAX(tsame,same);
850: samebuf = (Q *)ALLOCA(same*sizeof(Q));
851:
852: MKVECT(key,k); skb = (USINT *)BDY(key);
853: MKVECT(value,k); svb = (Obj *)BDY(value);
854:
855: tb = (Q *)tarray->body;
856: for ( same = i = i0 = k = 0; i <= len; i++ ) {
857: if ( i == len || kip[i0].key != kip[i].key ) {
858: skb[k] = kb[kip[i0].index];
859: if ( same > 1 ) {
860: MKVECT(v,same);
861: bcopy((char *)samebuf,(char *)v->body,same*sizeof(Q));
862: svb[k] = (Obj)v;
863: } else
864: svb[k] = (Obj)samebuf[0];
865: i0 = i;
866: k++;
867: same = 0;
868: if ( i == len )
869: break;
870: }
871: samebuf[same++] = tb[kip[i].index];
872: }
873: MKNODE(r1,value,0); MKNODE(r,key,r1); MKLIST(*rp,r);
874: }
875:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>