| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| |
| use xxx::rom; |
| use xxx::big; |
| use xxx::ecp; |
| use xxx::fp2::FP2; |
| use xxx::big::BIG; |
| |
| //#[derive(Copy, Clone)] |
| pub struct ECP2 { |
| x:FP2, |
| y:FP2, |
| z:FP2, |
| // inf: bool |
| } |
| |
| #[allow(non_snake_case)] |
| impl ECP2 { |
| |
| pub fn new() -> ECP2 { |
| ECP2 { |
| x: FP2::new(), |
| y: FP2::new_int(1), |
| z: FP2::new(), |
| // inf: true |
| } |
| } |
| #[allow(non_snake_case)] |
| /* construct this from (x,y) - but set to O if not on curve */ |
| pub fn new_fp2s(ix:&FP2,iy:&FP2) -> ECP2 { |
| let mut E=ECP2::new(); |
| E.x.copy(&ix); |
| E.y.copy(&iy); |
| E.z.one(); |
| E.x.norm(); |
| |
| let mut rhs=ECP2::rhs(&E.x); |
| let mut y2=FP2::new_copy(&E.y); |
| y2.sqr(); |
| if !y2.equals(&mut rhs) { |
| E.inf(); |
| } |
| return E; |
| } |
| |
| /* construct this from x - but set to O if not on curve */ |
| pub fn new_fp2(ix:&FP2) -> ECP2 { |
| let mut E=ECP2::new(); |
| E.x.copy(&ix); |
| E.y.one(); |
| E.z.one(); |
| E.x.norm(); |
| let mut rhs=ECP2::rhs(&E.x); |
| if rhs.sqrt() { |
| E.y.copy(&rhs); |
| // E.inf=false; |
| } else {E.inf();} |
| return E; |
| } |
| |
| /* Test this=O? */ |
| pub fn is_infinity(&self) -> bool { |
| // if self.inf {return true} |
| let xx=FP2::new_copy(&self.x); |
| let zz=FP2::new_copy(&self.z); |
| return xx.iszilch() && zz.iszilch(); |
| } |
| |
| /* copy self=P */ |
| pub fn copy(&mut self,P: &ECP2) { |
| self.x.copy(&P.x); |
| self.y.copy(&P.y); |
| self.z.copy(&P.z); |
| // self.inf=P.inf; |
| } |
| |
| /* set self=O */ |
| pub fn inf(&mut self) { |
| // self.inf=true; |
| self.x.zero(); |
| self.y.one(); |
| self.z.zero(); |
| } |
| |
| /* set self=-self */ |
| pub fn neg(&mut self) { |
| // if self.is_infinity() {return} |
| self.y.norm(); self.y.neg(); self.y.norm(); |
| } |
| |
| /* Conditional move of Q to self dependant on d */ |
| pub fn cmove(&mut self,Q: &ECP2,d: isize) { |
| self.x.cmove(&Q.x,d); |
| self.y.cmove(&Q.y,d); |
| self.z.cmove(&Q.z,d); |
| /* |
| let bd:bool; |
| if d==0 {bd=false} |
| else {bd=true} |
| |
| self.inf=(self.inf!=(self.inf!=Q.inf)&&bd); */ |
| } |
| |
| /* return 1 if b==c, no branching */ |
| fn teq(b: i32,c: i32) -> isize { |
| let mut x=b^c; |
| x-=1; // if x=0, x now -1 |
| return ((x>>31)&1) as isize; |
| } |
| |
| /* Constant time select from pre-computed table */ |
| pub fn selector(&mut self,W: &[ECP2],b: i32) { |
| let mut MP=ECP2::new(); |
| let m=b>>31; |
| let mut babs=(b^m)-m; |
| |
| babs=(babs-1)/2; |
| |
| self.cmove(&W[0],ECP2::teq(babs,0)); // conditional move |
| self.cmove(&W[1],ECP2::teq(babs,1)); |
| self.cmove(&W[2],ECP2::teq(babs,2)); |
| self.cmove(&W[3],ECP2::teq(babs,3)); |
| self.cmove(&W[4],ECP2::teq(babs,4)); |
| self.cmove(&W[5],ECP2::teq(babs,5)); |
| self.cmove(&W[6],ECP2::teq(babs,6)); |
| self.cmove(&W[7],ECP2::teq(babs,7)); |
| |
| MP.copy(self); |
| MP.neg(); |
| self.cmove(&MP,(m&1) as isize); |
| } |
| |
| /* Test if P == Q */ |
| pub fn equals(&mut self,Q :&mut ECP2) -> bool { |
| // if self.is_infinity() && Q.is_infinity() {return true} |
| // if self.is_infinity() || Q.is_infinity() {return false} |
| |
| let mut a=FP2::new_copy(&self.x); |
| let mut b=FP2::new_copy(&Q.x); |
| |
| a.mul(&Q.z); |
| b.mul(&self.z); |
| if !a.equals(&mut b) {return false} |
| a.copy(&self.y); a.mul(&Q.z); |
| b.copy(&Q.y); b.mul(&self.z); |
| if !a.equals(&mut b) {return false} |
| |
| return true; |
| } |
| |
| /* set to Affine - (x,y,z) to (x,y) */ |
| pub fn affine(&mut self) { |
| if self.is_infinity() {return} |
| let mut one=FP2::new_int(1); |
| if self.z.equals(&mut one) {return} |
| self.z.inverse(); |
| |
| self.x.mul(&self.z); self.x.reduce(); |
| self.y.mul(&self.z); self.y.reduce(); |
| self.z.copy(&one); |
| } |
| |
| /* extract affine x as FP2 */ |
| pub fn getx(&self) -> FP2 { |
| let mut W=ECP2::new(); W.copy(self); |
| W.affine(); |
| return FP2::new_copy(&W.x); |
| } |
| |
| /* extract affine y as FP2 */ |
| pub fn gety(&self) -> FP2 { |
| let mut W=ECP2::new(); W.copy(self); |
| W.affine(); |
| return FP2::new_copy(&W.y); |
| } |
| |
| /* extract projective x */ |
| pub fn getpx(&self) -> FP2 { |
| return FP2::new_copy(&self.x); |
| } |
| /* extract projective y */ |
| pub fn getpy(&self) -> FP2 { |
| return FP2::new_copy(&self.y); |
| } |
| /* extract projective z */ |
| pub fn getpz(&self) -> FP2 { |
| return FP2::new_copy(&self.z); |
| } |
| |
| /* convert to byte array */ |
| pub fn tobytes(&self,b: &mut [u8]) { |
| let mut t:[u8;big::MODBYTES as usize]=[0;big::MODBYTES as usize]; |
| let mb=big::MODBYTES as usize; |
| let mut W=ECP2::new(); W.copy(self); |
| |
| W.affine(); |
| W.x.geta().tobytes(&mut t); |
| for i in 0..mb { b[i]=t[i]} |
| W.x.getb().tobytes(&mut t); |
| for i in 0..mb { b[i+mb]=t[i]} |
| |
| W.y.geta().tobytes(&mut t); |
| for i in 0..mb {b[i+2*mb]=t[i]} |
| W.y.getb().tobytes(&mut t); |
| for i in 0..mb {b[i+3*mb]=t[i]} |
| } |
| |
| /* convert from byte array to point */ |
| pub fn frombytes(b: &[u8]) -> ECP2 { |
| let mut t:[u8;big::MODBYTES as usize]=[0;big::MODBYTES as usize]; |
| let mb=big::MODBYTES as usize; |
| |
| for i in 0..mb {t[i]=b[i]} |
| let mut ra=BIG::frombytes(&t); |
| for i in 0..mb {t[i]=b[i+mb]} |
| let mut rb=BIG::frombytes(&t); |
| let rx=FP2::new_bigs(&ra,&rb); |
| |
| for i in 0..mb {t[i]=b[i+2*mb]} |
| ra.copy(&BIG::frombytes(&t)); |
| for i in 0..mb {t[i]=b[i+3*mb]} |
| rb.copy(&BIG::frombytes(&t)); |
| let ry=FP2::new_bigs(&ra,&rb); |
| |
| return ECP2::new_fp2s(&rx,&ry); |
| } |
| |
| /* convert this to hex string */ |
| pub fn tostring(&self) -> String { |
| let mut W=ECP2::new(); W.copy(self); W.affine(); |
| if W.is_infinity() {return String::from("infinity")} |
| //self.affine(); |
| return format!("({},{})",W.x.tostring(),W.y.tostring()); |
| } |
| |
| /* Calculate RHS of twisted curve equation x^3+B/i */ |
| pub fn rhs(x:&FP2) -> FP2 { |
| //x.norm(); |
| let mut r=FP2::new_copy(x); |
| r.sqr(); |
| let mut b=FP2::new_big(&BIG::new_ints(&rom::CURVE_B)); |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| b.div_ip(); |
| } |
| if ecp::SEXTIC_TWIST==ecp::M_TYPE { |
| b.norm(); |
| b.mul_ip(); |
| b.norm(); |
| } |
| |
| r.mul(x); |
| r.add(&b); |
| |
| r.reduce(); |
| return r; |
| } |
| |
| /* self+=self */ |
| pub fn dbl(&mut self) -> isize { |
| // if self.inf {return -1} |
| |
| let mut iy=FP2::new_copy(&self.y); |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| iy.mul_ip(); iy.norm(); |
| } |
| |
| let mut t0=FP2::new_copy(&self.y); //***** Change |
| t0.sqr(); |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| t0.mul_ip(); |
| } |
| let mut t1=FP2::new_copy(&iy); |
| t1.mul(&self.z); |
| let mut t2=FP2::new_copy(&self.z); |
| t2.sqr(); |
| |
| self.z.copy(&t0); |
| self.z.add(&t0); self.z.norm(); |
| self.z.dbl(); |
| self.z.dbl(); |
| self.z.norm(); |
| |
| t2.imul(3*rom::CURVE_B_I); |
| if ecp::SEXTIC_TWIST==ecp::M_TYPE { |
| t2.mul_ip(); |
| t2.norm(); |
| } |
| let mut x3=FP2::new_copy(&t2); |
| x3.mul(&self.z); |
| |
| let mut y3=FP2::new_copy(&t0); |
| |
| y3.add(&t2); y3.norm(); |
| self.z.mul(&t1); |
| t1.copy(&t2); t1.add(&t2); t2.add(&t1); t2.norm(); |
| t0.sub(&t2); t0.norm(); //y^2-9bz^2 |
| y3.mul(&t0); y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2 |
| t1.copy(&self.x); t1.mul(&iy); // |
| self.x.copy(&t0); self.x.norm(); self.x.mul(&t1); self.x.dbl(); //(y^2-9bz^2)xy2 |
| |
| self.x.norm(); |
| self.y.copy(&y3); self.y.norm(); |
| |
| return 1; |
| |
| } |
| |
| /* self+=Q - return 0 for add, 1 for double, -1 for O */ |
| pub fn add(&mut self,Q:&ECP2) -> isize { |
| /*if self.inf { |
| self.copy(Q); |
| return -1; |
| } |
| if Q.inf {return -1}*/ |
| |
| |
| let b=3*rom::CURVE_B_I; |
| let mut t0=FP2::new_copy(&self.x); |
| t0.mul(&Q.x); // x.Q.x |
| let mut t1=FP2::new_copy(&self.y); |
| t1.mul(&Q.y); // y.Q.y |
| |
| let mut t2=FP2::new_copy(&self.z); |
| t2.mul(&Q.z); |
| let mut t3=FP2::new_copy(&self.x); |
| t3.add(&self.y); t3.norm(); //t3=X1+Y1 |
| let mut t4=FP2::new_copy(&Q.x); |
| t4.add(&Q.y); t4.norm(); //t4=X2+Y2 |
| t3.mul(&t4); //t3=(X1+Y1)(X2+Y2) |
| t4.copy(&t0); t4.add(&t1); //t4=X1.X2+Y1.Y2 |
| |
| t3.sub(&t4); t3.norm(); |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| t3.mul_ip(); t3.norm(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1 |
| } |
| t4.copy(&self.y); |
| t4.add(&self.z); t4.norm(); //t4=Y1+Z1 |
| let mut x3=FP2::new_copy(&Q.y); |
| x3.add(&Q.z); x3.norm(); //x3=Y2+Z2 |
| |
| t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2) |
| x3.copy(&t1); // |
| x3.add(&t2); //X3=Y1.Y2+Z1.Z2 |
| |
| t4.sub(&x3); t4.norm(); |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| t4.mul_ip(); t4.norm(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1 |
| } |
| x3.copy(&self.x); x3.add(&self.z); x3.norm(); // x3=X1+Z1 |
| let mut y3=FP2::new_copy(&Q.x); |
| y3.add(&Q.z); y3.norm(); // y3=X2+Z2 |
| x3.mul(&y3); // x3=(X1+Z1)(X2+Z2) |
| y3.copy(&t0); |
| y3.add(&t2); // y3=X1.X2+Z1+Z2 |
| y3.rsub(&x3); y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1 |
| |
| if ecp::SEXTIC_TWIST==ecp::D_TYPE { |
| t0.mul_ip(); t0.norm(); // x.Q.x |
| t1.mul_ip(); t1.norm(); // y.Q.y |
| } |
| x3.copy(&t0); x3.add(&t0); |
| t0.add(&x3); t0.norm(); |
| t2.imul(b); |
| if ecp::SEXTIC_TWIST==ecp::M_TYPE { |
| t2.mul_ip(); t2.norm(); |
| } |
| let mut z3=FP2::new_copy(&t1); z3.add(&t2); z3.norm(); |
| t1.sub(&t2); t1.norm(); |
| y3.imul(b); |
| if ecp::SEXTIC_TWIST==ecp::M_TYPE { |
| y3.mul_ip(); |
| y3.norm(); |
| } |
| x3.copy(&y3); x3.mul(&t4); t2.copy(&t3); t2.mul(&t1); x3.rsub(&t2); |
| y3.mul(&t0); t1.mul(&z3); y3.add(&t1); |
| t0.mul(&t3); z3.mul(&t4); z3.add(&t0); |
| |
| self.x.copy(&x3); self.x.norm(); |
| self.y.copy(&y3); self.y.norm(); |
| self.z.copy(&z3); self.z.norm(); |
| |
| return 0; |
| } |
| |
| /* set this-=Q */ |
| pub fn sub(&mut self,Q :&ECP2) -> isize { |
| let mut NQ=ECP2::new(); NQ.copy(Q); |
| NQ.neg(); |
| let d=self.add(&NQ); |
| return d; |
| } |
| |
| /* set this*=q, where q is Modulus, using Frobenius */ |
| pub fn frob(&mut self,x:&FP2) { |
| // if self.inf {return} |
| let mut x2=FP2::new_copy(x); |
| x2.sqr(); |
| self.x.conj(); |
| self.y.conj(); |
| self.z.conj(); |
| self.z.reduce(); |
| self.x.mul(&x2); |
| self.y.mul(&x2); |
| self.y.mul(x); |
| } |
| |
| /* self*=e */ |
| pub fn mul(&self,e: &BIG) -> ECP2 { |
| /* fixed size windows */ |
| let mut mt=BIG::new(); |
| let mut t=BIG::new(); |
| let mut P=ECP2::new(); |
| let mut Q=ECP2::new(); |
| let mut C=ECP2::new(); |
| |
| if self.is_infinity() {return P} |
| |
| let mut W:[ECP2;8]=[ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new()]; |
| |
| const CT:usize=1+(big::NLEN*(big::BASEBITS as usize)+3)/4; |
| let mut w:[i8;CT]=[0;CT]; |
| |
| // self.affine(); |
| |
| /* precompute table */ |
| Q.copy(&self); |
| Q.dbl(); |
| |
| W[0].copy(&self); |
| |
| for i in 1..8 { |
| C.copy(&W[i-1]); |
| W[i].copy(&C); |
| W[i].add(&mut Q); |
| } |
| |
| /* make exponent odd - add 2P if even, P if odd */ |
| t.copy(&e); |
| let s=t.parity(); |
| t.inc(1); t.norm(); let ns=t.parity(); mt.copy(&t); mt.inc(1); mt.norm(); |
| t.cmove(&mt,s); |
| Q.cmove(&self,ns); |
| C.copy(&Q); |
| |
| let nb=1+(t.nbits()+3)/4; |
| |
| /* convert exponent to signed 4-bit window */ |
| for i in 0..nb { |
| w[i]=(t.lastbits(5)-16) as i8; |
| t.dec(w[i] as isize); t.norm(); |
| t.fshr(4); |
| } |
| w[nb]=(t.lastbits(5)) as i8; |
| |
| P.copy(&W[((w[nb] as usize) -1)/2]); |
| for i in (0..nb).rev() { |
| Q.selector(&W,w[i] as i32); |
| P.dbl(); |
| P.dbl(); |
| P.dbl(); |
| P.dbl(); |
| P.add(&mut Q); |
| } |
| P.sub(&mut C); |
| P.affine(); |
| return P; |
| } |
| |
| |
| /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */ |
| // Bos & Costello https://eprint.iacr.org/2013/458.pdf |
| // Faz-Hernandez & Longa & Sanchez https://eprint.iacr.org/2013/158.pdf |
| // Side channel attack secure |
| |
| pub fn mul4(Q: &mut [ECP2],u: &[BIG]) -> ECP2 { |
| let mut W=ECP2::new(); |
| let mut P=ECP2::new(); |
| |
| let mut T:[ECP2;8]=[ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new(),ECP2::new()]; |
| |
| let mut mt=BIG::new(); |
| |
| let mut t:[BIG;4]=[BIG::new_copy(&u[0]),BIG::new_copy(&u[1]),BIG::new_copy(&u[2]),BIG::new_copy(&u[3])]; |
| |
| const CT:usize=1+big::NLEN*(big::BASEBITS as usize); |
| let mut w:[i8;CT]=[0;CT]; |
| let mut s:[i8;CT]=[0;CT]; |
| |
| for i in 0..4 { |
| //Q[i].affine(); |
| t[i].norm(); |
| } |
| |
| T[0].copy(&Q[0]); W.copy(&T[0]); |
| T[1].copy(&W); T[1].add(&mut Q[1]); // Q[0]+Q[1] |
| T[2].copy(&W); T[2].add(&mut Q[2]); W.copy(&T[1]); // Q[0]+Q[2] |
| T[3].copy(&W); T[3].add(&mut Q[2]); W.copy(&T[0]); // Q[0]+Q[1]+Q[2] |
| T[4].copy(&W); T[4].add(&mut Q[3]); W.copy(&T[1]); // Q[0]+Q[3] |
| T[5].copy(&W); T[5].add(&mut Q[3]); W.copy(&T[2]); // Q[0]+Q[1]+Q[3] |
| T[6].copy(&W); T[6].add(&mut Q[3]); W.copy(&T[3]); // Q[0]+Q[2]+Q[3] |
| T[7].copy(&W); T[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3] |
| |
| // Make it odd |
| let pb=1-t[0].parity(); |
| t[0].inc(pb); |
| t[0].norm(); |
| |
| // Number of bits |
| mt.zero(); |
| for i in 0..4 { |
| mt.or(&t[i]); |
| } |
| |
| let nb=1+mt.nbits(); |
| |
| // Sign pivot |
| |
| s[nb-1]=1; |
| for i in 0..nb-1 { |
| t[0].fshr(1); |
| s[i]=(2*t[0].parity()-1) as i8; |
| //println!("s={}",s[i]); |
| } |
| |
| // Recoded exponent |
| for i in 0..nb { |
| w[i]=0; |
| let mut k=1; |
| for j in 1..4 { |
| let bt=s[i]*(t[j].parity() as i8); |
| t[j].fshr(1); |
| t[j].dec((bt>>1) as isize); |
| t[j].norm(); |
| w[i]+=bt*(k as i8); |
| k=2*k; |
| } |
| } |
| |
| // Main loop |
| P.selector(&T,(2*w[nb-1]+1) as i32); |
| for i in (0..nb-1).rev() { |
| |
| P.dbl(); |
| W.selector(&T,(2*w[i]+s[i]) as i32); |
| P.add(&mut W); |
| } |
| |
| // apply correction |
| W.copy(&P); |
| W.sub(&mut Q[0]); |
| P.cmove(&W,pb); |
| P.affine(); |
| |
| return P; |
| } |
| |
| |
| #[allow(non_snake_case)] |
| pub fn mapit(h: &[u8]) -> ECP2 { |
| let mut q=BIG::new_ints(&rom::MODULUS); |
| let mut x=BIG::frombytes(h); |
| x.rmod(&mut q); |
| let mut Q:ECP2; |
| let one=BIG::new_int(1); |
| |
| loop { |
| let X=FP2::new_bigs(&one,&x); |
| Q=ECP2::new_fp2(&X); |
| if !Q.is_infinity() {break} |
| x.inc(1); x.norm(); |
| } |
| let mut X = FP2::new_bigs(&BIG::new_ints(&rom::FRA),&BIG::new_ints(&rom::FRB)); |
| if ecp::SEXTIC_TWIST==ecp::M_TYPE { |
| X.inverse(); |
| X.norm(); |
| } |
| x = BIG::new_ints(&rom::CURVE_BNX); |
| |
| if ecp::CURVE_PAIRING_TYPE==ecp::BN { |
| |
| let mut T=Q.mul(&mut x); |
| if ecp::SIGN_OF_X==ecp::NEGATIVEX { |
| T.neg(); |
| } |
| let mut K=ECP2::new(); K.copy(&T); |
| K.dbl(); K.add(&T); |
| |
| K.frob(&X); |
| Q.frob(&X); Q.frob(&X); Q.frob(&X); |
| Q.add(&T); Q.add(&K); |
| T.frob(&X); T.frob(&X); |
| Q.add(&T); |
| } |
| if ecp::CURVE_PAIRING_TYPE==ecp::BLS { |
| |
| let mut xQ=Q.mul(&mut x); |
| let mut x2Q=xQ.mul(&mut x); |
| |
| if ecp::SIGN_OF_X==ecp::NEGATIVEX { |
| xQ.neg(); |
| } |
| x2Q.sub(&xQ); |
| x2Q.sub(&Q); |
| |
| xQ.sub(&Q); |
| xQ.frob(&X); |
| |
| Q.dbl(); |
| Q.frob(&X); |
| Q.frob(&X); |
| |
| Q.add(&x2Q); |
| Q.add(&xQ); |
| } |
| |
| Q.affine(); |
| return Q; |
| } |
| |
| pub fn generator() -> ECP2 { |
| return ECP2::new_fp2s(&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PXA),&BIG::new_ints(&rom::CURVE_PXB)),&FP2::new_bigs(&BIG::new_ints(&rom::CURVE_PYA),&BIG::new_ints(&rom::CURVE_PYB))); |
| } |
| |
| } |
| /* |
| fn main() |
| { |
| let mut r=BIG::new_ints(&rom::MODULUS); |
| |
| let pxa=BIG::new_ints(&rom::CURVE_PXA); |
| let pxb=BIG::new_ints(&rom::CURVE_PXB); |
| let pya=BIG::new_ints(&rom::CURVE_PYA); |
| let pyb=BIG::new_ints(&rom::CURVE_PYB); |
| |
| let fra=BIG::new_ints(&rom::CURVE_FRA); |
| let frb=BIG::new_ints(&rom::CURVE_FRB); |
| |
| let mut f=FP2::new_bigs(&fra,&frb); |
| |
| let px=FP2::new_bigs(&pxa,&pxb); |
| let py=FP2::new_bigs(&pya,&pyb); |
| |
| let mut P=ECP2::new_fp2s(&px,&py); |
| |
| println!("P= {}",P.tostring()); |
| |
| P=P.mul(&mut r); |
| println!("P= {}",P.tostring()); |
| |
| let mut Q=ECP2::new_fp2s(&px,&py); |
| Q.frob(&mut f); |
| println!("Q= {}",Q.tostring()); |
| } |
| */ |