[BACK]Return to ec.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / builtin

Annotation of OpenXM_contrib2/asir2000/builtin/ec.c, Revision 1.6

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>