use crate::bls12443::big::BIG;
use crate::bls12443::ecp;
use crate::bls12443::ecp::ECP;
use crate::bls12443::ecp2::ECP2;
use crate::bls12443::fp::FP;
use crate::bls12443::fp12;
use crate::bls12443::fp12::FP12;
use crate::bls12443::fp2::FP2;
use crate::bls12443::fp4::FP4;
use crate::bls12443::rom;
#[allow(unused_imports)]
use crate::bls12443::dbig::DBIG;
#[allow(non_snake_case)]
fn dbl(A: &mut ECP2, aa: &mut FP2, bb: &mut FP2, cc: &mut FP2) {
cc.copy(&A.getpx()); let mut yy = FP2::new_copy(&A.getpy()); bb.copy(&A.getpz());
aa.copy(&yy); aa.mul(&bb); cc.sqr(); yy.sqr(); bb.sqr();
aa.dbl();
aa.neg(); aa.norm();
aa.mul_ip();
aa.norm();
let sb = 3 * rom::CURVE_B_I;
bb.imul(sb);
cc.imul(3);
if ecp::SEXTIC_TWIST == ecp::D_TYPE {
yy.mul_ip();
yy.norm();
cc.mul_ip();
cc.norm();
}
if ecp::SEXTIC_TWIST == ecp::M_TYPE {
bb.mul_ip();
bb.norm();
}
bb.sub(&yy);
bb.norm();
A.dbl();
}
#[allow(non_snake_case)]
fn add(A: &mut ECP2, B: &ECP2, aa: &mut FP2, bb: &mut FP2, cc: &mut FP2) {
aa.copy(&A.getpx()); cc.copy(&A.getpy()); let mut t1 = FP2::new_copy(&A.getpz()); bb.copy(&A.getpz());
t1.mul(&B.getpy()); bb.mul(&B.getpx());
aa.sub(&bb);
aa.norm(); cc.sub(&t1);
cc.norm();
t1.copy(&aa); if ecp::SEXTIC_TWIST == ecp::M_TYPE {
aa.mul_ip();
aa.norm();
}
t1.mul(&B.getpy());
bb.copy(&cc); bb.mul(&B.getpx()); bb.sub(&t1);
bb.norm();
cc.neg();
cc.norm();
A.add(B);
}
#[allow(non_snake_case)]
fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
let mut a = FP4::new();
let mut b = FP4::new();
let mut c = FP4::new();
let mut aa = FP2::new();
let mut bb = FP2::new();
let mut cc = FP2::new();
dbl(A,&mut aa,&mut bb,&mut cc);
cc.pmul(qx);
aa.pmul(qy);
a.copy(&FP4::new_fp2s(&aa, &bb)); if ecp::SEXTIC_TWIST == ecp::D_TYPE {
b.copy(&FP4::new_fp2(&cc)); }
if ecp::SEXTIC_TWIST == ecp::M_TYPE {
c.copy(&FP4::new_fp2(&cc));
c.times_i();
}
let mut res= FP12::new_fp4s(&a, &b, &c);
res.settype(fp12::SPARSER);
res
}
#[allow(non_snake_case)]
fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
let mut a = FP4::new();
let mut b = FP4::new();
let mut c = FP4::new();
let mut aa = FP2::new();
let mut bb = FP2::new();
let mut cc = FP2::new();
add(A,B,&mut aa,&mut bb,&mut cc);
cc.pmul(qx);
aa.pmul(qy);
a.copy(&FP4::new_fp2s(&aa, &bb)); if ecp::SEXTIC_TWIST == ecp::D_TYPE {
b.copy(&FP4::new_fp2(&cc)); }
if ecp::SEXTIC_TWIST == ecp::M_TYPE {
c.copy(&FP4::new_fp2(&cc));
c.times_i();
}
let mut res= FP12::new_fp4s(&a, &b, &c);
res.settype(fp12::SPARSER);
res
}
#[allow(non_snake_case)]
fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
n.copy(&BIG::new_ints(&rom::CURVE_BNX));
if ecp::CURVE_PAIRING_TYPE==ecp::BN {
n.pmul(6);
if ecp::SIGN_OF_X==ecp::POSITIVEX {
n.inc(2);
} else {
n.dec(2);
}
}
n.norm();
n3.copy(&n);
n3.pmul(3);
n3.norm();
n3.nbits()
}
pub fn initmp() -> [FP12; ecp::ATE_BITS] {
[FP12::new_int(1); ecp::ATE_BITS]
}
pub fn miller(r:&mut [FP12]) -> FP12 {
let mut res=FP12::new_int(1);
for i in (1..ecp::ATE_BITS).rev() {
res.sqr();
res.ssmul(&r[i]);
r[i].zero();
}
if ecp::SIGN_OF_X==ecp::NEGATIVEX {
res.conj();
}
res.ssmul(&r[0]);
r[0].zero();
res
}
fn pack(aa: &FP2,bb: &FP2,cc: &FP2) -> FP4 {
let mut i=FP2::new_copy(cc);
i.inverse(None);
let mut a=FP2::new_copy(aa);
let mut b=FP2::new_copy(bb);
a.mul(&i);
b.mul(&i);
FP4::new_fp2s(&a,&b)
}
fn unpack(t: &FP4, qx: &FP, qy: &FP) -> FP12 {
let b:FP4;
let mut c:FP4;
let w=FP2::new_fp(qx);
let mut aa=t.geta();
let bb=t.getb();
aa.pmul(qy);
let a=FP4::new_fp2s(&aa,&bb);
if ecp::SEXTIC_TWIST==ecp::D_TYPE {
b=FP4::new_fp2(&w);
c=FP4::new();
} else {
b=FP4::new();
c=FP4::new_fp2(&w); c.times_i();
}
let mut v=FP12::new_fp4s(&a,&b,&c);
v.settype(fp12::SPARSEST);
v
}
#[allow(non_snake_case)]
pub fn precomp(T: &mut [FP4],GV: &ECP2) {
let mut n = BIG::new();
let mut n3 = BIG::new();
let nb=lbits(&mut n3,&mut n);
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut aa = FP2::new();
let mut bb = FP2::new();
let mut cc = FP2::new();
let mut P=ECP2::new(); P.copy(GV);
if (ecp::CURVE_PAIRING_TYPE==ecp::BN) && (ecp::SEXTIC_TWIST==ecp::M_TYPE) {
f.inverse(None);
f.norm();
}
let mut A = ECP2::new();
A.copy(&P);
let mut NP = ECP2::new();
NP.copy(&P);
NP.neg();
let mut j=0;
for i in (1..nb-1).rev() {
dbl(&mut A,&mut aa,&mut bb,&mut cc);
T[j].copy(&pack(&aa,&bb,&cc)); j+=1;
let bt=n3.bit(i)-n.bit(i);
if bt==1 {
add(&mut A,&P,&mut aa,&mut bb,&mut cc);
T[j].copy(&pack(&aa,&bb,&cc)); j+=1;
}
if bt==-1 {
add(&mut A,&NP,&mut aa,&mut bb,&mut cc);
T[j].copy(&pack(&aa,&bb,&cc)); j+=1;
}
}
if ecp::CURVE_PAIRING_TYPE==ecp::BN {
if ecp::SIGN_OF_X==ecp::NEGATIVEX {
A.neg();
}
let mut K = ECP2::new();
K.copy(&P);
K.frob(&f);
add(&mut A,&K,&mut aa,&mut bb,&mut cc);
T[j].copy(&pack(&aa,&bb,&cc)); j+=1;
K.frob(&f);
K.neg();
add(&mut A,&K,&mut aa,&mut bb,&mut cc);
T[j].copy(&pack(&aa,&bb,&cc));
}
}
#[allow(non_snake_case)]
pub fn another_pc(r:&mut [FP12],T: &[FP4],QV: &ECP) {
let mut n = BIG::new();
let mut n3 = BIG::new();
if QV.is_infinity() {
return;
}
let nb=lbits(&mut n3,&mut n);
let mut Q = ECP::new();
Q.copy(QV);
Q.affine();
let qx = FP::new_copy(&Q.getpx());
let qy = FP::new_copy(&Q.getpy());
let mut j=0;
for i in (1..nb-1).rev() {
let mut lv=unpack(&T[j],&qx,&qy); j+=1;
let bt=n3.bit(i)-n.bit(i);
if bt==1 {
let lv2=unpack(&T[j],&qx,&qy); j+=1;
lv.smul(&lv2);
}
if bt==-1 {
let lv2=unpack(&T[j],&qx,&qy); j+=1;
lv.smul(&lv2);
}
r[i].ssmul(&lv);
}
if ecp::CURVE_PAIRING_TYPE==ecp::BN {
let mut lv=unpack(&T[j],&qx,&qy); j+=1;
let lv2=unpack(&T[j],&qx,&qy);
lv.smul(&lv2);
r[0].ssmul(&lv);
}
}
#[allow(non_snake_case)]
pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut n = BIG::new();
let mut n3 = BIG::new();
let mut K = ECP2::new();
if Q1.is_infinity() {
return;
}
let mut P = ECP2::new();
P.copy(P1);
P.affine();
let mut Q = ECP::new();
Q.copy(Q1);
Q.affine();
if (ecp::CURVE_PAIRING_TYPE==ecp::BN) && (ecp::SEXTIC_TWIST==ecp::M_TYPE) {
f.inverse(None);
f.norm();
}
let qx = FP::new_copy(&Q.getpx());
let qy = FP::new_copy(&Q.getpy());
let mut A = ECP2::new();
A.copy(&P);
let mut NP = ECP2::new();
NP.copy(&P);
NP.neg();
let nb=lbits(&mut n3,&mut n);
for i in (1..nb-1).rev() {
let mut lv=linedbl(&mut A,&qx,&qy);
let bt=n3.bit(i)-n.bit(i);
if bt==1 {
let lv2=lineadd(&mut A,&P,&qx,&qy);
lv.smul(&lv2);
}
if bt==-1 {
let lv2=lineadd(&mut A,&NP,&qx,&qy);
lv.smul(&lv2);
}
r[i].ssmul(&lv);
}
if ecp::CURVE_PAIRING_TYPE==ecp::BN {
if ecp::SIGN_OF_X==ecp::NEGATIVEX {
A.neg();
}
K.copy(&P);
K.frob(&f);
let mut lv=lineadd(&mut A,&K,&qx,&qy);
K.frob(&f);
K.neg();
let lv2=lineadd(&mut A,&K,&qx,&qy);
lv.smul(&lv2);
r[0].ssmul(&lv);
}
}
#[allow(non_snake_case)]
pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut n = BIG::new();
let mut n3 = BIG::new();
let mut K = ECP2::new();
if Q1.is_infinity() {
return FP12::new_int(1);
}
if (ecp::CURVE_PAIRING_TYPE == ecp::BN) && (ecp::SEXTIC_TWIST == ecp::M_TYPE) {
f.inverse(None);
f.norm();
}
let mut P = ECP2::new();
P.copy(P1);
P.affine();
let mut Q = ECP::new();
Q.copy(Q1);
Q.affine();
let qx = FP::new_copy(&Q.getpx());
let qy = FP::new_copy(&Q.getpy());
let mut A = ECP2::new();
let mut r = FP12::new_int(1);
A.copy(&P);
let mut NP = ECP2::new();
NP.copy(&P);
NP.neg();
let nb=lbits(&mut n3,&mut n);
for i in (1..nb - 1).rev() {
r.sqr();
let mut lv = linedbl(&mut A, &qx, &qy);
let bt = n3.bit(i) - n.bit(i);
if bt == 1 {
let lv2 = lineadd(&mut A, &P, &qx, &qy);
lv.smul(&lv2);
}
if bt == -1 {
let lv2 = lineadd(&mut A, &NP, &qx, &qy);
lv.smul(&lv2);
}
r.ssmul(&lv);
}
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
r.conj();
}
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
A.neg();
}
K.copy(&P);
K.frob(&f);
let mut lv = lineadd(&mut A, &K, &qx, &qy);
K.frob(&f);
K.neg();
let lv2 = lineadd(&mut A, &K, &qx, &qy);
lv.smul(&lv2);
r.ssmul(&lv);
}
r
}
#[allow(non_snake_case)]
pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut n = BIG::new();
let mut n3 = BIG::new();
let mut K = ECP2::new();
if Q1.is_infinity() {
return ate(R1,S1);
}
if S1.is_infinity() {
return ate(P1,Q1);
}
if (ecp::CURVE_PAIRING_TYPE == ecp::BN) && (ecp::SEXTIC_TWIST == ecp::M_TYPE) {
f.inverse(None);
f.norm();
}
let mut P = ECP2::new();
P.copy(P1);
P.affine();
let mut Q = ECP::new();
Q.copy(Q1);
Q.affine();
let mut R = ECP2::new();
R.copy(R1);
R.affine();
let mut S = ECP::new();
S.copy(S1);
S.affine();
let qx = FP::new_copy(&Q.getpx());
let qy = FP::new_copy(&Q.getpy());
let sx = FP::new_copy(&S.getpx());
let sy = FP::new_copy(&S.getpy());
let mut A = ECP2::new();
let mut B = ECP2::new();
let mut r = FP12::new_int(1);
A.copy(&P);
B.copy(&R);
let mut NP = ECP2::new();
NP.copy(&P);
NP.neg();
let mut NR = ECP2::new();
NR.copy(&R);
NR.neg();
let nb=lbits(&mut n3,&mut n);
for i in (1..nb - 1).rev() {
r.sqr();
let mut lv = linedbl(&mut A, &qx, &qy);
let lv2 = linedbl(&mut B, &sx, &sy);
lv.smul(&lv2);
r.ssmul(&lv);
let bt = n3.bit(i) - n.bit(i);
if bt == 1 {
lv = lineadd(&mut A, &P, &qx, &qy);
let lv2 = lineadd(&mut B, &R, &sx, &sy);
lv.smul(&lv2);
r.ssmul(&lv);
}
if bt == -1 {
lv = lineadd(&mut A, &NP, &qx, &qy);
let lv2 = lineadd(&mut B, &NR, &sx, &sy);
lv.smul(&lv2);
r.ssmul(&lv);
}
}
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
r.conj();
}
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
A.neg();
B.neg();
}
K.copy(&P);
K.frob(&f);
let mut lv = lineadd(&mut A, &K, &qx, &qy);
K.frob(&f);
K.neg();
let mut lv2 = lineadd(&mut A, &K, &qx, &qy);
lv.smul(&lv2);
r.ssmul(&lv);
K.copy(&R);
K.frob(&f);
lv = lineadd(&mut B, &K, &sx, &sy);
K.frob(&f);
K.neg();
lv2 = lineadd(&mut B, &K, &sx, &sy);
lv.smul(&lv2);
r.ssmul(&lv);
}
r
}
pub fn fexp(m: &FP12) -> FP12 {
let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let x = BIG::new_ints(&rom::CURVE_BNX);
let mut r = FP12::new_copy(m);
let mut lv = FP12::new_copy(&r);
lv.inverse();
r.conj();
r.mul(&lv);
lv.copy(&r);
r.frob(&f);
r.frob(&f);
r.mul(&lv);
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
lv.copy(&r);
lv.frob(&f);
let mut x0 = FP12::new_copy(&lv);
x0.frob(&f);
lv.mul(&r);
x0.mul(&lv);
x0.frob(&f);
let mut x1 = FP12::new_copy(&r);
x1.conj();
let mut x4 = r.pow(&x);
if ecp::SIGN_OF_X == ecp::POSITIVEX {
x4.conj();
}
let mut x3 = FP12::new_copy(&x4);
x3.frob(&f);
let mut x2 = x4.pow(&x);
if ecp::SIGN_OF_X == ecp::POSITIVEX {
x2.conj();
}
let mut x5 = FP12::new_copy(&x2);
x5.conj();
lv = x2.pow(&x);
if ecp::SIGN_OF_X == ecp::POSITIVEX {
lv.conj();
}
x2.frob(&f);
r.copy(&x2);
r.conj();
x4.mul(&r);
x2.frob(&f);
r.copy(&lv);
r.frob(&f);
lv.mul(&r);
lv.usqr();
lv.mul(&x4);
lv.mul(&x5);
r.copy(&x3);
r.mul(&x5);
r.mul(&lv);
lv.mul(&x2);
r.usqr();
r.mul(&lv);
r.usqr();
lv.copy(&r);
lv.mul(&x1);
r.mul(&x0);
lv.usqr();
r.mul(&lv);
r.reduce();
} else {
let mut y1 = FP12::new_copy(&r);
y1.usqr();
y1.mul(&r);
let mut y0 = FP12::new_copy(&r.pow(&x));
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
y0.conj();
}
let mut t0 = FP12::new_copy(&r); t0.conj();
r.copy(&y0);
r.mul(&t0);
y0.copy(&r.pow(&x));
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
y0.conj();
}
t0.copy(&r); t0.conj();
r.copy(&y0);
r.mul(&t0);
y0.copy(&r.pow(&x));
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
y0.conj();
}
t0.copy(&r);
t0.frob(&f);
r.copy(&y0);
r.mul(&t0);
y0.copy(&r.pow(&x));
y0.copy(&y0.pow(&x));
t0.copy(&r);
t0.frob(&f); t0.frob(&f);
y0.mul(&t0);
t0.copy(&r); t0.conj();
r.copy(&y0);
r.mul(&t0);
r.mul(&y1);
r.reduce();
}
r
}
#[allow(non_snake_case)]
fn glv(ee: &BIG) -> [BIG; 2] {
let mut u: [BIG; 2] = [BIG::new(), BIG::new()];
let q = BIG::new_ints(&rom::CURVE_ORDER);
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
} else {
let x = BIG::new_ints(&rom::CURVE_BNX);
let x2 = BIG::smul(&x, &x);
let bd=q.nbits()-x2.nbits();
u[0].copy(&ee);
u[0].ctmod(&x2,bd);
u[1].copy(&ee);
u[1].ctdiv(&x2,bd);
u[1].rsub(&q);
}
u
}
#[allow(non_snake_case)]
pub fn gs(ee: &BIG) -> [BIG; 4] {
let mut u: [BIG; 4] = [BIG::new(), BIG::new(), BIG::new(), BIG::new()];
let q = BIG::new_ints(&rom::CURVE_ORDER);
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
} else {
let x = BIG::new_ints(&rom::CURVE_BNX);
let bd=q.nbits()-x.nbits();
let mut w = BIG::new_copy(&ee);
for i in 0..3 {
u[i].copy(&w);
u[i].ctmod(&x,bd);
w.ctdiv(&x,bd);
}
u[3].copy(&w);
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
let mut t = BIG::new();
t.copy(&BIG::modneg(&u[1], &q));
u[1].copy(&t);
t.copy(&BIG::modneg(&u[3], &q));
u[3].copy(&t);
}
}
u
}
#[allow(non_snake_case)]
pub fn g1mul(P: &ECP, e: &BIG) -> ECP {
let mut R = ECP::new();
let q = BIG::new_ints(&rom::CURVE_ORDER);
let mut ee= BIG::new_copy(e);
ee.rmod(&q);
if rom::USE_GLV {
R.copy(P);
let mut Q = ECP::new();
Q.copy(P);
Q.affine();
let mut cru = FP::new_big(&BIG::new_ints(&rom::CRU));
let mut u = glv(&ee);
Q.mulx(&mut cru);
let mut np = u[0].nbits();
let mut t: BIG = BIG::modneg(&u[0], &q);
let mut nn = t.nbits();
if nn < np {
u[0].copy(&t);
R.neg();
}
np = u[1].nbits();
t = BIG::modneg(&u[1], &q);
nn = t.nbits();
if nn < np {
u[1].copy(&t);
Q.neg();
}
u[0].norm();
u[1].norm();
R = R.mul2(&u[0], &Q, &u[1]);
} else {
R = P.clmul(&ee,&q);
}
R
}
#[allow(non_snake_case)]
pub fn g2mul(P: &ECP2, e: &BIG) -> ECP2 {
let mut R = ECP2::new();
let q = BIG::new_ints(&rom::CURVE_ORDER);
let mut ee= BIG::new_copy(e);
ee.rmod(&q);
if rom::USE_GS_G2 {
let mut Q: [ECP2; 4] = [ECP2::new(), ECP2::new(), ECP2::new(), ECP2::new()];
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut u = gs(&ee);
let mut T = ECP2::new();
if ecp::SEXTIC_TWIST == ecp::M_TYPE {
f.inverse(None);
f.norm();
}
let mut t = BIG::new();
Q[0].copy(&P);
for i in 1..4 {
T.copy(&Q[i - 1]);
Q[i].copy(&T);
Q[i].frob(&f);
}
for i in 0..4 {
let np = u[i].nbits();
t.copy(&BIG::modneg(&u[i], &q));
let nn = t.nbits();
if nn < np {
u[i].copy(&t);
Q[i].neg();
}
u[i].norm();
}
R.copy(&ECP2::mul4(&Q, &u));
} else {
R.copy(&P.mul(&ee));
}
R
}
pub fn gtpow(d: &FP12, e: &BIG) -> FP12 {
let mut r = FP12::new();
let q = BIG::new_ints(&rom::CURVE_ORDER);
let mut ee= BIG::new_copy(e);
ee.rmod(&q);
if rom::USE_GS_GT {
let mut g: [FP12; 4] = [FP12::new(), FP12::new(), FP12::new(), FP12::new()];
let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let mut t = BIG::new();
let mut u = gs(&ee);
let mut w = FP12::new();
g[0].copy(&d);
for i in 1..4 {
w.copy(&g[i - 1]);
g[i].copy(&w);
g[i].frob(&f);
}
for i in 0..4 {
let np = u[i].nbits();
t.copy(&BIG::modneg(&u[i], &q));
let nn = t.nbits();
if nn < np {
u[i].copy(&t);
g[i].conj();
}
u[i].norm();
}
r.copy(&FP12::pow4(&g, &u));
} else {
r.copy(&d.pow(&ee));
}
r
}
#[allow(non_snake_case)]
pub fn g1member(P: &ECP) -> bool {
if P.is_infinity() {
return false;
}
if ecp::CURVE_PAIRING_TYPE != ecp::BN {
let x = BIG::new_ints(&rom::CURVE_BNX);
let mut cru = FP::new_big(&BIG::new_ints(&rom::CRU));
let mut W=ECP::new(); W.copy(P); W.mulx(&mut cru);
let mut T=P.mul(&x);
if P.equals(&T) {return false;}
T=T.mul(&x); T.neg();
if !W.equals(&T) {
return false;
}
}
true
}
#[allow(non_snake_case)]
pub fn g2member(P: &ECP2) -> bool {
let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
if ecp::SEXTIC_TWIST == ecp::M_TYPE {
f.inverse(None);
f.norm();
}
let x = BIG::new_ints(&rom::CURVE_BNX);
let mut W=ECP2::new(); W.copy(P); W.frob(&f);
let mut T=P.mul(&x);
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
T=T.mul(&x);
let six=BIG::new_int(6);
T=T.mul(&six);
} else {
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
T.neg();
}
}
if !W.equals(&T) {
return false;
}
true
}
pub fn gtcyclotomic(m: &FP12) -> bool {
if m.isunity() {
return false;
}
let mut r = FP12::new_copy(&m);
r.conj();
r.mul(&m);
if !r.isunity() {
return false;
}
let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
r.copy(&m); r.frob(&f); r.frob(&f);
let mut w = FP12::new_copy(&r); w.frob(&f); w.frob(&f);
w.mul(&m);
if !w.equals(&r) {
return false;
}
return true;
}
pub fn gtmember(m: &FP12) -> bool {
if !gtcyclotomic(m) {
return false;
}
let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
let x = BIG::new_ints(&rom::CURVE_BNX);
let mut r=FP12::new_copy(m); r.frob(&f);
let mut t=m.pow(&x);
if ecp::CURVE_PAIRING_TYPE == ecp::BN {
t=t.pow(&x);
let six=BIG::new_int(6);
t=t.pow(&six);
} else {
if ecp::SIGN_OF_X == ecp::NEGATIVEX {
t.conj();
}
}
if !r.equals(&t) {
return false;
}
true
}