KGC_TEST/KGC/miracl/source/curve/glv.cpp

130 lines
3.3 KiB
C++

// Apply the GLV algorithm to decompose k (for use by GLS elliptic curves)
// See "Faster Point Multiplication on Elliptic Curves with efficient Endomorphisms",
// by Gallant, Lambert and Vanstone".
// cl /O2 /GX glv.cpp big.cpp miracl.lib
// August 2008
#include <iostream>
#include "big.h"
using namespace std;
Miracl precision(50,0);
char *group="3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE09C5F010948D9D930E79156D8BA3CAF5";
int main()
{
int i,mkb,tmkb;
miracl *mip=&precision;
mip->IOBASE=16;
Big r=group;
Big lambda,p;
Big u,v,u1,u2,u3,v1,v2,v3,t1,t2,t3,q,s,rm,tm,rm1,tm1,rm2,tm2,V1[2],V2[2],det,k,b1,b2,t,V[2],U[2],e;
// offline calculations
cout << "r= " << r << endl;
lambda=sqrt(r-1,r); // endomorphism corresponds to sqrt(-1) mod r
cout << "lambda= " << lambda << endl;
p=pow((Big)2,127)-1;
t="3204F5AE088C39A7";
cout << "p^2+1-2*p+t*t= " << p*p+1-2*p+t*t << endl;
cout << "t+(p-1)*lambda mod r = " << (t+(p-1)*lambda)%r << endl;
cout << "(p-1) - lambda*t mod r = " << ((p-1)-lambda*t)%r << endl;
u1=1; u2=0; u3=r;
v1=0; v2=1; v3=lambda;
s=sqrt(r);
cout << "s= " << s << endl;
cout << "2^127-2= " << pow((Big)2,127)-2 << endl;
while (u3>s)
{
q=u3/v3;
t1=u1-q*v1; t2=u2-q*v2; t3=u3-q*v3;
u1=v1, u2=v2; u3=v3;
v1=t1; v2=t2; v3=t3;
}
cout << "u3= " << u3 << endl;
cout << "u2= " << u2 << endl;
cout << "u1= " << u1 << endl;
rm=u3; tm=-u2;
q=u3/v3;
t1=u1-q*v1; t2=u2-q*v2; t3=u3-q*v3;
u1=v1, u2=v2; u3=v3;
v1=t1; v2=t2; v3=t3;
rm1=u3; tm1=-u2;
q=u3/v3;
t1=u1-q*v1; t2=u2-q*v2; t3=u3-q*v3;
u1=v1, u2=v2; u3=v3;
v1=t1; v2=t2; v3=t3;
rm2=u3; tm2=-u2;
V1[0]=rm1; V1[1]=tm1;
cout << "(V1[0]+V1[1]*lambda)%r= " << (V1[0]+V1[1]*lambda)%r << endl;
if (rm*rm+tm*tm < rm2*rm2+tm2*tm2)
{
V2[0]=rm; V2[1]=tm;
}
else
{
V2[0]=rm2; V2[1]=tm2;
}
cout << "(V2[0]+V2[1]*lambda)%r= " << (V2[0]+V2[1]*lambda)%r << endl;
cout << "v1[0]= " << V1[0] << endl;
cout << "v1[1]= " << V1[1] << endl;
cout << "v2[0]= " << V2[0] << endl;
cout << "v2[1]= " << V2[1] << endl;
det=V1[0]*V2[1]-V2[0]*V1[1];
det=-det;
cout << "det= " << det << endl;
// online calculation - input V1, V2, determinant, and multiplier k which will be decomposed into k0 and k1
tmkb=0;
for (i=0;i<10;i++)
{
k=randbits(254);
t=-(V2[1]*k);
b1=t/det;
if (t%det>(det/2)) b1+=1; // don't bother with "rounding to nearest"
t=-(-V1[1]*k);
b2=t/det;
if (t%det>(det/2)) b2+=1;
cout << "b1= " << b1 << endl;
cout << "b2= " << b2 << endl;
V[0]=b1*V1[0]+b2*V2[0];
V[1]=b1*V1[1]+b2*V2[1];
U[0]=k-V[0];
U[1]=-V[1];
cout << "k0= " << (U[0]) << " bits= " << bits(U[0]) << endl;
cout << "k1= " << (U[1]) << " bits= " << bits(U[1]) << endl;
e=(U[0]+U[1]*lambda)%r;
if (e<0) e+=r;
cout << "k= " << k << endl;
cout << "(k0+k1*lam)%r= " << e << endl;
if (k!=e) break;
if (bits(U[0])>126 || bits(U[1])>126) break;
mkb=bits(U[0]);
if (bits(U[1])>mkb) mkb=bits(U[1]);
tmkb+=mkb;
// if (U[0]<0 || U[1]<0) break;
}
cout << "tmkb= " << tmkb << endl;
return 0;
}