Annotation of OpenXM_contrib2/asir2000/builtin/ec.c, Revision 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>