void PFC::add_to_hash(const GT& x) { ZZn4 u; ZZn12 v=x.g; ZZn2 h,l; Big a; ZZn xx[6]; int i,j,m; v.get(u); u.get(l,h); l.get(xx[0],xx[1]); h.get(xx[2],xx[3]); for (i=0;i<4;i++) { a=(Big)xx[i]; while (a>0) { m=a%256; shs256_process(&SH,m); a/=256; } } }
Big H2(ZZn12 x) { // Compress and hash an Fp12 to a big number sha256 sh; ZZn4 u; ZZn2 h,l; Big a,hash,p,xx[4]; char s[HASH_LEN]; int i,j,m; shs256_init(&sh); x.get(u); // compress to single ZZn4 u.get(l,h); xx[0]=real(l); xx[1]=imaginary(l); xx[2]=real(h); xx[3]=imaginary(h); for (i=0;i<4;i++) { a=xx[i]; while (a>0) { m=a%256; shs256_process(&sh,m); a/=256; } } shs256_hash(&sh,s); hash=from_binary(HASH_LEN,s); return hash; }
ZZn4 line(ECn& A,ECn& C,ECn& B,int type,ZZn& slope,ZZn& ex1,ZZn& ex2,ZZn2& Qx,ZZn2& Qy) { ZZn4 w; #ifdef AFFINE ZZn2 m=Qx; ZZn x,y extract(A,x,y); m-=x; m*=slope; w.set((ZZn2)-y,Qy); w-=m; #endif #ifdef PROJECTIVE if (type==MR_ADD) { ZZn x2,y2,x3,z3; extract(B,x2,y2); extract(C,x3,x3,z3); w.set(slope*(Qx-x2)+z3*y2,-z3*Qy); } if (type==MR_DOUBLE) { ZZn x,y,x3,z3; extract(A,x,y); extract(C,x3,x3,z3); w.set((slope*ex2)*Qx-slope*x+ex1,-(z3*ex2)*Qy); } #endif return w; }
ZZn4 line(ECn2& A,ZZn2& lam,ZZn& Qx,ZZn& Qy) { ZZn4 w; ZZn2 x,y,z,t; untwist(A,x,y); w.set(ZZn2(0,Qy),tx(y)-lam*(x-Qx)); return w; }
BOOL power_tate(ECn& P,ECn4 Q,Big& q,Big *cf,ZZn2 &Fr,Big &e,ZZn4& r) { int i,nb; ECn A; ZZn8 w,res,a[4]; ZZn4 Qx,Qy; ZZn2 x,y; Big carry,ex[4]; Big p=get_modulus(); Q.get(Qx,Qy); Qx=txd(Qx); Qy=txd(txd(Qy)); res=1; /* Left to right method */ A=P; nb=bits(q); for (i=nb-2;i>=0;i--) { res*=res; res*=g(A,A,Qx,Qy); if (bit(q,i)) res*=g(A,P,Qx,Qy); } if (!A.iszero() || res.iszero()) return FALSE; w=res; w.powq(Fr); w.powq(Fr); // ^(p^4-1) w.powq(Fr); w.powq(Fr); res=w/res; res.mark_as_unitary(); a[3]=res; a[2]=a[3]; a[2].powq(Fr); a[1]=a[2]; a[1].powq(Fr); a[0]=a[1]; a[0].powq(Fr); if (e.isone()) for (i=0;i<4;i++) ex[i]=cf[i]; else { // cf *= e carry=0; for (i=3;i>=0;i--) carry=mad(cf[i],e,carry,p,ex[i]); } res=pow(4,a,ex); r=real(res); // compression // r=powl(real(res),cf); // ^(p*p*p*p+1)/q if (r.isunity()) return FALSE; return TRUE; }
ECn4 hash4(char *ID) { ECn4 T; ZZn4 x; ZZn2 X,Y=0; Big x0,y0=0; x0=H1(ID); do { X.set(x0,y0); x.set(X,Y); x0+=1; } while (!is_on_curve(x)); T.set(x); return T; }
ZZn4 txd(const ZZn4& x) { ZZn2 u,v; x.get(u,v); u=txd(u); ZZn4 w(v,u); return w; }
BOOL qr(const ZZn4& x) { ZZn2 a,s; if (x.iszero()) return TRUE; x.get(a,s); if (s.iszero()) return TRUE; s*=s; a*=a; a-=txx(s); if (!qr(a)) return FALSE; return TRUE; // s=sqrt(a); // if (qr((x.a+s)/2) || qr((x.a-s)/2)) return TRUE; // return FALSE; }
ZZn4 sqrt(const ZZn4& x) { // sqrt(a+xb) = sqrt((a+sqrt(a*a-n*b*b))/2)+x.b/(2*sqrt((a+sqrt(a*a-n*b*b))/2)) // sqrt(a) = x.sqrt(a/n) // where x*x=n ZZn4 w; ZZn2 a,s,t; if (x.iszero()) return w; x.get(a,s); if (s.iszero()) { if (qr(a)) { s=sqrt(a); w.set(s,0); } else { s=sqrt(txd(a)); w.set(0,s); } return w; } s*=s; a*=a; a-=txx(s); s=sqrt(a); if (s.iszero()) return w; x.get(t); if (qr((ZZn2)((t+s)/2))) { a=sqrt((t+s)/2); } else { a=sqrt((t-s)/2); if (a.iszero()) return w; } x.geth(t); w.set(a,t/(2*a)); return w; }
Big H4(ZZn4 x) { // Hash an Fp2 to a big number sha sh; Big a,u,v; ZZn2 X,Y; char s[HASH_LEN]; int m; shs_init(&sh); x.get(X,Y); X.get(u,v); a=u; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } a=v; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } Y.get(u,v); a=u; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } a=v; while (a>0) { m=a%256; shs_process(&sh,m); a/=256; } shs_hash(&sh,s); a=from_binary(HASH_LEN,s); return a; }
ZZn2 imaginary(const ZZn4 &x) { ZZn2 i; x.geth(i); return i; }
ZZn2 real(const ZZn4 &x) { ZZn2 r; x.get(r); return r; }
int main(int argc, char **argv) { miracl *mip=&precision; Big p,R,B,mc,curve_b,cru,cof,tau[9]; Big m,x,y,w,t,c,n,r,a,b,gx,gy,r2modp; Big np,PP,TT,FF; int i,A,curve,bb,chunk,words,mbits,bytes,ip=0; int modtype,curvetype,curve_a,curve_b_i,cof_i,lang=0; ZZn2 X; ECn P; ECn2 Q; ECn4 QQ; ECn8 Q8; ZZn4 XA,YA,AA,BB; ZZn8 X8,Y8; ZZn2 Aa,Ab,Ba,Bb; ZZn2 Xa,Ya; ZZn zcru; char pre0[50],pre1[50],pre2[50],pre3[50],pre4[50],pre5[50],pre6[50]; char post0[50],post1[50],post2[50],post3[50],post4[50],post5[50],post6[50]; char pre7[50],post7[50],lg[50]; char xxx[20],yyy[20],zzz[20]; char curvename[30],fieldname[30]; argv++; argc--; if (argc<4) { help(); return 0; } strcpy(curvename,argv[0]); // curve=atoi(argv[ip++]); for (i=0;;i++) { if (curvename[i]==0) break; curvename[i]=toupper(curvename[i]); } //cout << "curvename= " << curvename << " " << strlen(curvename) << endl; curve=0; ip++; chunk=atoi(argv[ip++]); bb=atoi(argv[ip++]); strcpy(lg,argv[ip]); if (chunk !=16 && chunk!=32 && chunk!=64) {help(); return 0;} if (bb<0 || bb>=chunk) {help(); return 0;} // Specify curve constants if (strcmp(curvename,"ED25519")==0) { // ED25519 curve=1; printf("Curve= ED25519\n"); strcpy(fieldname,"25519"); mbits=255; // bits in modulus words=(1+((mbits-1)/bb)); // words per Big curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=-1; // Curve A parameter cof=8; p=pow((Big)2,mbits)-19; // Modulus r=pow((Big)2,252)+(char *)"27742317777372353535851937790883648493"; // group order mip->IOBASE=16; curve_b=(char *)"52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3"; // curve B parameter gx=(char *)"216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"; // generator point gy=(char *)"6666666666666666666666666666666666666666666666666666666666666658"; } if (strcmp(curvename,"C25519")==0) { curve=2; printf("Curve= C25519\n"); strcpy(fieldname,"25519"); mbits=255; words=(1+((mbits-1)/bb)); curvetype=MONTGOMERY; modtype=PSEUDO_MERSENNE; curve_a=486662; cof=8; p=pow((Big)2,mbits)-19; r=pow((Big)2,252)+(char *)"27742317777372353535851937790883648493"; curve_b=0; mip->IOBASE=16; gx=(char *)"9"; gy=0; } if (strcmp(curvename,"NIST256")==0) { curve=3; printf("Curve= NIST256\n"); strcpy(fieldname,curvename); mbits=256; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=-3; cof=1; p=(char *)"115792089210356248762697446949407573530086143415290314195533631308867097853951"; r=(char *)"115792089210356248762697446949407573529996955224135760342422259061068512044369"; mip->IOBASE=16; curve_b=(char *)"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b"; gx=(char *)"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296"; gy=(char *)"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"; } if (strcmp(curvename,"BRAINPOOL")==0) { curve=4; printf("Curve= BRAINPOOL\n"); strcpy(fieldname,curvename); mbits=256; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=-3; cof=1; p=(char *)"76884956397045344220809746629001649093037950200943055203735601445031516197751"; mip->IOBASE=16; r=(char *)"A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7"; mip->IOBASE=10; curve_b=(char *)"46214326585032579593829631435610129746736367449296220983687490401182983727876"; mip->IOBASE=16; gx=(char *)"a3e8eb3cc1cfe7b7732213b23a656149afa142c47aafbc2b79a191562e1305f4"; gy=(char *)"2d996c823439c56d7f7b22e14644417e69bcb6de39d027001dabe8f35b25c9be"; } if (strcmp(curvename,"ANSSI")==0) { curve=5; printf("Curve= ANSSI\n"); strcpy(fieldname,curvename); mbits=256; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=-3; cof=1; p=(char *)"109454571331697278617670725030735128145969349647868738157201323556196022393859"; mip->IOBASE=16; r=(char *)"F1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1"; mip->IOBASE=10; curve_b=(char *)"107744541122042688792155207242782455150382764043089114141096634497567301547839"; mip->IOBASE=16; gx=(char *)"b6b3d4c356c139eb31183d4749d423958c27d2dcaf98b70164c97a2dd98f5cff"; gy=(char *)"6142e0f7c8b204911f9271f0f3ecef8c2701c307e8e4c9e183115a1554062cfb"; } if (strcmp(curvename,"HIFIVE")==0) { curve=6; printf("Curve= HIFIVE\n"); strcpy(fieldname,curvename); mbits=336; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=1; cof=8; p=pow((Big)2,336)-3; mip->IOBASE=16; r=(char *)"200000000000000000000000000000000000000000071415FA9850C0BD6B87F93BAA7B2F95973E9FA805"; mip->IOBASE=10; curve_b=(char *)"11111"; mip->IOBASE=16; gx=(char *)"C"; gy=(char *)"C0DC616B56502E18E1C161D007853D1B14B46C3811C7EF435B6DB5D5650CA0365DB12BEC68505FE8632"; } if (strcmp(curvename,"GOLDILOCKS")==0) { curve=7; printf("Curve= GOLDILOCKS\n"); strcpy(fieldname,curvename); mbits=448; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=GENERALISED_MERSENNE; curve_a=1; cof=4; p=pow((Big)2,448)-pow((Big)2,224)-1; r=(p+1-(char *)"28312320572429821613362531907042076847709625476988141958474579766324")/4; mip->IOBASE=10; curve_b=p-39081; mip->IOBASE=16; gx=(char *)"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa955555555555555555555555555555555555555555555555555555555"; gy=(char *)"ae05e9634ad7048db359d6205086c2b0036ed7a035884dd7b7e36d728ad8c4b80d6565833a2a3098bbbcb2bed1cda06bdaeafbcdea9386ed"; } if (strcmp(curvename,"NIST384")==0) { curve=8; printf("Curve= NIST384\n"); strcpy(fieldname,curvename); mbits=384; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=-3; cof=1; p=(char *)"39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319"; r=p+1-(char *)"1388124618062372383606759648309780106643088307173319169677"; curve_b=(char *)"27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575"; mip->IOBASE=16; gx=(char *)"aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7"; gy=(char *)"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f"; } if (strcmp(curvename,"C41417")==0) { curve=9; printf("Curve= C41417\n"); strcpy(fieldname,curvename); mbits=414; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=1; p=pow((Big)2,mbits)-17; cof=8; r=pow((Big)2,411)-(char *)"33364140863755142520810177694098385178984727200411208589594759"; // Group Order curve_b=(char *)"3617"; mip->IOBASE=16; gx=(char *)"1a334905141443300218c0631c326e5fcd46369f44c03ec7f57ff35498a4ab4d6d6ba111301a73faa8537c64c4fd3812f3cbc595"; gy=(char *)"22"; } if (strcmp(curvename,"NIST521")==0) { curve=10; printf("Curve= NIST521\n"); strcpy(fieldname,curvename); mbits=521; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=-3; cof=1; p=pow((Big)2,mbits)-1; mip->IOBASE=16; r=(char *)"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"; // Group Order curve_b=(char *)"51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00"; gx=(char *)"C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"; gy=(char *)"11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650"; } if (strcmp(curvename,"NUMS256W")==0) { curve=11; printf("Curve= NUMS256W\n"); strcpy(fieldname,"256PMW"); mbits=256; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=PSEUDO_MERSENNE; curve_a=-3; cof=1; p=pow((Big)2,mbits)-189; mip->IOBASE=16; r=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE43C8275EA265C6020AB20294751A825"; // Group Order curve_b=(char *)"25581"; gx=(char *)"BC9ED6B65AAADB61297A95A04F42CB0983579B0903D4C73ABC52EE1EB21AACB1"; gy=(char *)"D08FC0F13399B6A673448BF77E04E035C955C3D115310FBB80B5B9CB2184DE9F"; } if (strcmp(curvename,"NUMS256E")==0) { curve=12; printf("Curve= NUMS256E\n"); strcpy(fieldname,"256PME"); mbits=256; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=1; cof=4; p=pow((Big)2,mbits)-189; mip->IOBASE=16; r=(char *)"4000000000000000000000000000000041955AA52F59439B1A47B190EEDD4AF5"; // Group Order curve_b=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC355"; gx=(char *)"8A7514FB6AEA237DCD1E3D5F69209BD60C398A0EE3083586A0DEC0902EED13DA"; gy=(char *)"44D53E9FD9D925C7CE9665D9A64B8010715F61D810856ED32FA616E7798A89E6"; } if (strcmp(curvename,"NUMS384W")==0) { curve=13; printf("Curve= NUMS384W\n"); strcpy(fieldname,"384PM"); mbits=384; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=PSEUDO_MERSENNE; curve_a=-3; cof=1; p=pow((Big)2,mbits)-317; mip->IOBASE=16; r=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD61EAF1EEB5D6881BEDA9D3D4C37E27A604D81F67B0E61B9"; // Group Order curve_b=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77BB"; gx=(char *)"757956F0B16F181C4880CA224105F1A60225C1CDFB81F9F4F3BD291B2A6CC742522EED100F61C47BEB9CBA042098152A"; gy=(char *)"ACDEE368E19B8E38D7E33D300584CF7EB0046977F87F739CB920837D121A837EBCD6B4DBBFF4AD265C74B8EC66180716"; } if (strcmp(curvename,"NUMS384E")==0) { curve=14; printf("Curve= NUMS384E\n"); strcpy(fieldname,"384PM"); mbits=384; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=1; cof=4; p=pow((Big)2,mbits)-317; mip->IOBASE=16; r=(char *)"3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2471A1CB46BE1CF61E4555AAB35C87920B9DCC4E6A3897D"; // Group Order curve_b=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD19F"; gx=(char *)"61B111FB45A9266CC0B6A2129AE55DB5B30BF446E5BE4C005763FFA8F33163406FF292B16545941350D540E46C206BDE"; gy=(char *)"82983E67B9A6EEB08738B1A423B10DD716AD8274F1425F56830F98F7F645964B0072B0F946EC48DC9D8D03E1F0729392"; } if (strcmp(curvename,"NUMS512W")==0) { curve=15; printf("Curve= NUMS512W\n"); strcpy(fieldname,"512PM"); mbits=512; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=PSEUDO_MERSENNE; curve_a=-3; cof=1; p=pow((Big)2,mbits)-569; mip->IOBASE=16; r=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5B3CA4FB94E7831B4FC258ED97D0BDC63B568B36607CD243CE153F390433555D"; // Group Order curve_b=(char *)"1D99B"; gx=(char *)"3AC03447141D0A93DA2B7002A03D3B5298CAD83BB501F6854506E0C25306D9F95021A151076B359E93794286255615831D5D60137D6F5DE2DC8287958CABAE57"; gy=(char *)"943A54CA29AD56B3CE0EEEDC63EBB1004B97DBDEABBCBB8C8F4B260C7BD14F14A28415DA8B0EEDE9C121A840B25A5602CF2B5C1E4CFD0FE923A08760383527A6"; } if (strcmp(curvename,"NUMS512E")==0) { curve=16; printf("Curve= NUMS512E\n"); strcpy(fieldname,"512PM"); mbits=512; words=(1+((mbits-1)/bb)); curvetype=EDWARDS; modtype=PSEUDO_MERSENNE; curve_a=1; cof=4; p=pow((Big)2,mbits)-569; mip->IOBASE=16; r=(char *)"3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB4F0636D2FCF91BA9E3FD8C970B686F52A4605786DEFECFF67468CF51BEED46D"; // Group Order curve_b=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFECBEF"; gx=(char *)"DF8E316D128DB69C7A18CB7888D3C5332FD1E79F4DC4A38227A17EBE273B81474621C14EEE46730F78BDC992568904AD0FE525427CC4F015C5B9AB2999EC57FE"; gy=(char *)"6D09BFF39D49CA7198B0F577A82A256EE476F726D8259D22A92B6B95909E834120CA53F2E9963562601A06862AECC1FD0266D38A9BF1D01F326DDEC0C1E2F5E1"; } if (strcmp(curvename,"SECP256K1")==0) { // SECP256K1 curve=17; printf("Curve= SECP256K1\n"); strcpy(fieldname,"SECP256K1"); mbits=256; // bits in modulus words=(1+((mbits-1)/bb)); // words per Big curvetype=WEIERSTRASS; /*if (chunk<64)*/ modtype=NOT_SPECIAL; //modtype=PSEUDO_MERSENNE; curve_a=0; // Curve A parameter cof=1; p=pow((Big)2,mbits)-pow((Big)2,32)-977; // Modulus mip->IOBASE=16; r=(char *)"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; // group order curve_b=(char *)"7"; // curve B parameter gx=(char *)"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"; // generator point gy=(char *)"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"; } if (strcmp(curvename,"BN254")==0) { curve=18; printf("Curve= BN254\n"); strcpy(fieldname,curvename); mbits=254; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"4080000000000001"; // Fast but not GT_STRONG parameter p=36*pow(x,4)-36*pow(x,3)+24*x*x-6*x+1; // Modulus t=6*x*x+1; r=p+1-t; // Group order curve_b=2; gx=p-1; // generator point in G1 gy=1; cof=1; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_D; // twist type Xa.set((ZZn)0,(ZZn)-1); Ya.set((ZZn)1,ZZn(0)); Q.set(Xa,Ya); Q=(p-1+t)*Q; // generator point in G2 cru=(18*pow(x,3)-18*x*x+9*x-2); // cube root of unity for GLV method } if (strcmp(curvename,"BN254CX")==0) { curve=19; printf("Curve= BN254CX\n"); strcpy(fieldname,curvename); mbits=254; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"4000000003C012B1"; p=36*pow(x,4)-36*pow(x,3)+24*x*x-6*x+1; t=6*x*x+1; r=p+1-t; curve_b=2; gx=p-1; gy=1; cof=1; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_D; Xa.set((ZZn)0,(ZZn)-1); Ya.set((ZZn)1,ZZn(0)); Q.set(Xa,Ya); Q=(p-1+t)*Q; // generator point in G2 cru=(18*pow(x,3)-18*x*x+9*x-2); } if (strcmp(curvename,"BLS383")==0) { curve=20; printf("Curve= BLS383\n"); strcpy(fieldname,curvename); mbits=383; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; // x=(char *)"11000001000000040"; x=(char *)"10008000001001200"; // SIGN_OF_X is POSITIVE p=(pow(x,6)-2*pow(x,5)+2*pow(x,3)+x+1)/3; t=x+1; r=pow(x,4)-x*x+1; cof=(p+1-t)/r; // gx=-2; gy=-1; // curve_b=9; gx=1; gy=4; curve_b=15; ecurve((Big)0,curve_b,p,MR_AFFINE); // mip->TWIST=MR_SEXTIC_D; mip->TWIST=MR_SEXTIC_M; P.set(gx,gy); P*=cof; P.get(gx,gy); //cout << "gx= " << gx << endl; //cout << "gy= " << gy << endl; //cout << "y^2= " << (gy*gy)%p << endl; //cout << "x^3+b= " << (gx*gx*gx+15)%p << endl; //while (!Q.set(randn2())) ; // probably not best way to choose this Xa=1; while (!Q.set(Xa)) { Xa=Xa+(ZZn2)1; } TT=t*t-2*p; PP=p*p; FF=sqrt((4*PP-TT*TT)/3); np=PP+1-(-3*FF+TT)/2; // 2 possibilities... Q=(np/r)*Q; zcru=pow((ZZn)2,(p-1)/3); // zcru*=zcru; // right cube root of unity cru=(Big)zcru; } if (strcmp(curvename,"BLS381")==0) { curve=21; printf("Curve= BLS381\n"); strcpy(fieldname,curvename); mbits=381; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"d201000000010000"; // SIGN_OF_X is NEGATIVE p=(pow(x,6)+2*pow(x,5)-2*pow(x,3)-x+1)/3; t=-x+1; r=pow(x,4)-x*x+1; cof=(p+1-t)/r; curve_b=4; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_M; gx=1; while (!P.set(gx)) { gx=gx+1; } P*=cof; P.get(gx,gy); Xa=1; while (!Q.set(Xa)) { Xa=Xa+(ZZn2)1; } Q.get(Xa,Ya); Ya=-Ya; Q.set(Xa,Ya); TT=t*t-2*p; PP=p*p; FF=sqrt((4*PP-TT*TT)/3); np=PP+1-(-3*FF+TT)/2; // 2 possibilities... Q=(np/r)*Q; zcru=pow((ZZn)2,(p-1)/3); //zcru*=zcru; // right cube root of unity ?? if x>0 do this?? cru=(Big)zcru; } if (strcmp(curvename,"BLS461")==0) { curve=24; printf("Curve= BLS461\n"); strcpy(fieldname,curvename); mbits=461; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"1FFFFFFBFFFE00000000"; // SIGN_OF_X is NEGATIVE p=(pow(x,6)+2*pow(x,5)-2*pow(x,3)-x+1)/3; t=-x+1; r=pow(x,4)-x*x+1; cof=(p+1-t)/r; gx=-2; gy=-1; curve_b=9; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_M; P.set(gx,gy); P*=cof; P.get(gx,gy); while (!Q.set(randn2())) ; // probably not best way to choose this TT=t*t-2*p; PP=p*p; FF=sqrt((4*PP-TT*TT)/3); np=PP+1-(-3*FF+TT)/2; // 2 possibilities... Q=(np/r)*Q; zcru=pow((ZZn)2,(p-1)/3); //zcru*=zcru; // right cube root of unity cru=(Big)zcru; } if (strcmp(curvename,"FP256BN")==0) { curve=22; printf("Curve= FP256BN\n"); strcpy(fieldname,curvename); mbits=256; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"6882F5C030B0A801"; // Slow! p=36*pow(x,4)-36*pow(x,3)+24*x*x-6*x+1; t=6*x*x+1; r=p+1-t; curve_b=3; gx=1; gy=2; cof=1; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_M; Q.set((ZZn2)1); //while (!Q.set(randn2())) ; Q=(p-1+t)*Q; cru=(18*pow(x,3)-18*x*x+9*x-2); cout << pre1 << toupperit((char *)"CURVE_Cru",lang) << post1; output(chunk,words,cru,m); cout << term << endl; } if (strcmp(curvename,"FP512BN")==0) { curve=23; printf("Curve= FP512BN\n"); strcpy(fieldname,curvename); mbits=512; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; x=(char *)"6882F5C030B0F7F010B306BB5E1BD80F"; // Slow! p=36*pow(x,4)+36*pow(x,3)+24*x*x+6*x+1; t=6*x*x+1; r=p+1-t; curve_b=3; gx=1; gy=2; cof=1; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_M; Q.set((ZZn2)1); //while (!Q.set(randn2())) ; Q=(p-1+t)*Q; cru=p-(18*pow(x,3)+18*x*x+9*x+2); } if (strcmp(curvename,"BLS24")==0) { curve=25; printf("Curve= BLS24\n"); strcpy(fieldname,curvename); mbits=479; words=(1+((mbits-1)/bb)); curvetype=WEIERSTRASS; modtype=NOT_SPECIAL; curve_a=0; mip->IOBASE=16; // Note - this is GT-Strong curve x=(char *)"100020011FF80"; // SIGN_OF_X is POSITIVE //x=-x; p=(1+x+x*x-pow(x,4)+2*pow(x,5)-pow(x,6)+pow(x,8)-2*pow(x,9)+pow(x,10))/3; t=x+1; r=pow(x,8)-pow(x,4)+1; cof=(p+1-t)/r; //x=-x; gx=5; gy=12; curve_b=19; ecurve((Big)0,curve_b,p,MR_AFFINE); mip->TWIST=MR_SEXTIC_M; P.set(gx,gy); P*=cof; P.get(gx,gy); Big x0=0; forever { ZZn4 X; ZZn2 t; x0+=1; t.set((ZZn)0,(ZZn)x0); X.set(t,(ZZn2)0); if (!QQ.set(X)) continue; break; } TT=t*t*t*t-4*p*t*t+2*p*p; PP=pow(p,4); FF=sqrt((4*PP-TT*TT)/3); np=PP+1-(3*FF+TT)/2; QQ=(np/r)*QQ; //cout << "QQ= " << QQ << endl; //cout << "2*QQ= " << QQ+QQ << endl; //cout << "3*QQ= " << (QQ+QQ)+QQ << endl; zcru=pow((ZZn)2,(p-1)/3); //zcru*=zcru; // right cube root of unity - not for M-TYPE cru=(Big)zcru; }