147 lines
3.1 KiB
C++
147 lines
3.1 KiB
C++
//
|
|
// cl /O2 /GX bls12.cpp zzn2.cpp zzn.cpp ecn2.cpp ecn.cpp big.cpp miracl.lib
|
|
// Program to generate Barreto-Lynn-Scott k=12 rho=1.5 curves for use by ake12blsa.cpp
|
|
//
|
|
|
|
#include <iostream>
|
|
#include "big.h"
|
|
#include "ecn.h"
|
|
#include "ecn2.h"
|
|
|
|
using namespace std;
|
|
|
|
Miracl precision=100;
|
|
|
|
int main()
|
|
{
|
|
int ns,twist,best_ham=1000;
|
|
int sign;
|
|
BOOL got_one;
|
|
Big cof,r,m1,m2,n,p,t,s,x,y,b,w,best_s;
|
|
Big PP,TT,FF;
|
|
miracl*mip=&precision;
|
|
ECn P;
|
|
ECn2 Q;
|
|
ZZn2 xi;
|
|
|
|
mip->IOBASE=16;
|
|
|
|
s=(char *)"C000000000000000";
|
|
|
|
ns=1;
|
|
forever
|
|
{
|
|
s+=1;
|
|
for (sign=1;sign<=2;sign++)
|
|
{
|
|
if (sign==1) x=s;
|
|
else x=-s;
|
|
|
|
if (x<0 || ham(x)>9) continue; // filter out difficult or poor solutions
|
|
|
|
p=pow(x,6)-2*pow(x,5)+2*pow(x,3)+x+1;
|
|
|
|
|
|
if (p%3!=0) continue; // check congruence conditions
|
|
p/=3;
|
|
|
|
if (p%8==1) continue;
|
|
if (p%8==7 && (p%5==1 || p%5==4)) continue;
|
|
|
|
t=x+1;
|
|
|
|
n=p+1-t;
|
|
r=pow(x,4)-x*x+1;
|
|
|
|
if (!prime(r)) continue;
|
|
|
|
if (!prime(p)) continue;
|
|
modulo(p);
|
|
|
|
if (p%8==5) xi.set(0,1);
|
|
if (p%8==3) xi.set(1,1);
|
|
if (p%8==7) xi.set(2,1);
|
|
if (pow(xi,(p*p-1)/2)==1) continue;
|
|
if (pow(xi,(p*p-1)/3)==1) continue; // make sure that x^6+c is irreducible
|
|
|
|
cof=n/r;
|
|
|
|
// find number of points on sextic twist..
|
|
|
|
TT=t*t-2*p;
|
|
PP=p*p;
|
|
|
|
FF=sqrt((4*PP-TT*TT)/3);
|
|
|
|
m1=PP+1-(-3*FF+TT)/2; // 2 possibilities...
|
|
|
|
// m2=PP+1-(3*FF+TT)/2; // wrong one
|
|
|
|
b=0;
|
|
forever
|
|
{
|
|
b+=1;
|
|
ecurve(0,b,p,MR_AFFINE);
|
|
while (!P.set(rand(p))) ;
|
|
P*=cof;
|
|
if ((r*P).iszero()) break; // right curve
|
|
}
|
|
got_one=FALSE;
|
|
|
|
mip->TWIST=MR_SEXTIC_M;
|
|
while (!Q.set(randn2())) ;
|
|
|
|
Q*=(m1/r);
|
|
|
|
if ((r*Q).iszero()) got_one=TRUE;
|
|
else
|
|
{
|
|
mip->TWIST=MR_SEXTIC_D;
|
|
while (!Q.set(randn2())) ;
|
|
|
|
Q*=(m1/r);
|
|
|
|
if ((r*Q).iszero()) got_one=TRUE;
|
|
}
|
|
if (!got_one) {cout << "Bad twist" << endl; exit(0);} // Huh?
|
|
|
|
if (mip->TWIST==MR_SEXTIC_M) continue; // not interested just now
|
|
|
|
cout << "solution " << ns << endl;
|
|
cout << "irreducible polynomial = X^6 + " << xi << endl;
|
|
cout << "p=" << p << endl;
|
|
cout << "p mod 72 = " << p%72 << endl;
|
|
cout << "x mod 72 = " << x%72 << endl;
|
|
|
|
cout << "x= " << x << endl;
|
|
cout << "bits(p)= " << bits(p) << endl;
|
|
cout << "r=" << r << endl;
|
|
cout << "t=" << t << endl;
|
|
cout << "m1= " << m1 << endl;
|
|
cout << "cof= " << m1/r << endl;
|
|
|
|
cout << "bits(t)= " << bits(t) << endl;
|
|
cout << "ham(t-1) = " << ham(t-1) << " (small is better for Ate pairing)" << endl;
|
|
cout << "bits(r)= " << bits(r) << endl;
|
|
|
|
cout << "p%8= " << p%8 << endl;
|
|
mip->IOBASE=10;
|
|
cout << "E(Fp): y^2=x^3+" << b << endl;
|
|
mip->IOBASE=16;
|
|
if (mip->TWIST==MR_SEXTIC_M) cout << "Twist type M" << endl;
|
|
if (mip->TWIST==MR_SEXTIC_D) cout << "Twist type D" << endl;
|
|
|
|
Q*=r;
|
|
cout << "check - if right twist should be O - r*Q= " << Q << endl;
|
|
ns++;
|
|
if (ham(x)<best_ham) {best_ham=ham(x);best_s=s;}
|
|
cout << "So far minimum hamming weight of x= " << best_ham << endl;
|
|
cout << "for seed= " << best_s << endl;
|
|
|
|
cout << endl;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|