http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/ecp2.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/ecp2.rs b/version22/rust/src/ecp2.rs deleted file mode 100644 index cee55a6..0000000 --- a/version22/rust/src/ecp2.rs +++ /dev/null @@ -1,677 +0,0 @@ -/* -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 std::fmt; -use std::str::SplitWhitespace; - -#[derive(Copy, Clone)] -pub struct ECP2 { - x:FP2, - y:FP2, - z:FP2, - inf: bool -} - - -use rom; -use rom::BIG_HEX_STRING_LEN; -//mod fp2; -use fp2::FP2; -//mod fp; -//use fp::FP; -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rand; -//mod hash256; -//mod rom; - -impl fmt::Display for ECP2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ECP2: [ {}, {}, {}, {} ]", self.inf, self.x, self.y, self.z) - } -} - -impl fmt::Debug for ECP2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ECP2: [ {}, {}, {}, {} ]", self.inf, self.x, self.y, self.z) - } -} - -impl PartialEq for ECP2 { - fn eq(&self, other: &ECP2) -> bool { - return (self.inf == other.inf) && - (self.x == other.x) && - (self.y == other.y) && - (self.z == other.z); - } -} - -#[allow(non_snake_case)] -impl ECP2 { - - pub fn new() -> ECP2 { - ECP2 { - x: FP2::new(), - y: FP2::new(), - 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(); - - let mut rhs=ECP2::rhs(&mut E.x); - let mut y2=FP2::new_copy(&E.y); - y2.sqr(); - if y2.equals(&mut rhs) { - E.inf=false; - } else {E.x.zero();E.inf=true} - 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(); - - let mut rhs=ECP2::rhs(&mut E.x); - if rhs.sqrt() { - E.y.copy(&rhs); - E.inf=false; - } else {E.x.zero();E.inf=true} - return E; - } - -/* Test this=O? */ - pub fn is_infinity(&mut self) -> bool { - return self.inf; - } - -/* 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.zero(); - self.z.zero(); - } - -/* set self=-self */ - pub fn neg(&mut self) { - if self.is_infinity() {return} - self.y.neg(); self.y.reduce(); - } - -/* 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 zs2=FP2::new_copy(&self.z); zs2.sqr(); - let mut zo2=FP2::new_copy(&Q.z); zo2.sqr(); - let mut zs3=FP2::new_copy(&zs2); zs3.mul(&mut self.z); - let mut zo3=FP2::new_copy(&zo2); zo3.mul(&mut Q.z); - zs2.mul(&mut Q.x); - zo2.mul(&mut self.x); - if !zs2.equals(&mut zo2) {return false} - zs3.mul(&mut Q.y); - zo3.mul(&mut self.y); - if !zs3.equals(&mut zo3) {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(); - - let mut z2=FP2::new_copy(&self.z); - z2.sqr(); - self.x.mul(&mut z2); self.x.reduce(); - self.y.mul(&mut z2); - self.y.mul(&mut self.z); self.y.reduce(); - self.z.copy(&one); - } - -/* extract affine x as FP2 */ - pub fn getx(&mut self) -> FP2 { - self.affine(); - return FP2::new_copy(&self.x); - } - -/* extract affine y as FP2 */ - pub fn gety(&mut self) -> FP2 { - self.affine(); - return FP2::new_copy(&self.y); - } - -/* extract projective x */ - pub fn getpx(&mut self) -> FP2 { - return FP2::new_copy(&self.x); - } -/* extract projective y */ - pub fn getpy(&mut self) -> FP2 { - return FP2::new_copy(&self.y); - } -/* extract projective z */ - pub fn getpz(&mut self) -> FP2 { - return FP2::new_copy(&self.z); - } - -/* convert to byte array */ - pub fn tobytes(&mut self,b: &mut [u8]) { - let mut t:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - let mb=rom::MODBYTES as usize; - - self.affine(); - self.x.geta().tobytes(&mut t); - for i in 0..mb { b[i]=t[i]} - self.x.getb().tobytes(&mut t); - for i in 0..mb { b[i+mb]=t[i]} - - self.y.geta().tobytes(&mut t); - for i in 0..mb {b[i+2*mb]=t[i]} - self.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;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - let mb=rom::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(&mut self) -> String { - if self.is_infinity() {return String::from("infinity")} - self.affine(); - return format!("({},{})",self.x.tostring(),self.y.tostring()); -} - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(7 * BIG_HEX_STRING_LEN); - ret.push_str(&format!("{} {} {} {}", self.inf, self.x.to_hex(), self.y.to_hex(), self.z.to_hex())); - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP2 { - let mut ret:ECP2 = ECP2::new(); - if let Some(x) = iter.next() { - ret.inf = x == "true"; - ret.x = FP2::from_hex_iter(iter); - ret.y = FP2::from_hex_iter(iter); - ret.z = FP2::from_hex_iter(iter); - } - return ret; - } - - pub fn from_hex(val: String) -> ECP2 { - let mut iter = val.split_whitespace(); - return ECP2::from_hex_iter(&mut iter); - } - -/* Calculate RHS of twisted curve equation x^3+B/i */ - pub fn rhs(x:&mut 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)); - b.div_ip(); - r.mul(x); - r.add(&b); - - r.reduce(); - return r; - } - -/* self+=self */ - pub fn dbl(&mut self) -> isize { - if self.inf {return -1} - if self.y.iszilch() { - self.inf(); - return -1 - } - - let mut w1=FP2::new_copy(&self.x); - let mut w2=FP2::new(); - let mut w3=FP2::new_copy(&self.x); - let mut w8=FP2::new_copy(&self.x); - - w1.sqr(); - w8.copy(&w1); - w8.imul(3); - - w2.copy(&self.y); w2.sqr(); - w3.copy(&self.x); w3.mul(&mut w2); - w3.imul(4); - w1.copy(&w3); w1.neg(); - w1.norm(); - - self.x.copy(&w8); self.x.sqr(); - self.x.add(&w1); - self.x.add(&w1); - self.x.norm(); - - self.z.mul(&mut self.y); - self.z.dbl(); - - w2.dbl(); - w2.sqr(); - w2.dbl(); - w3.sub(&self.x); - self.y.copy(&w8); self.y.mul(&mut w3); - w2.norm(); - self.y.sub(&w2); - - self.y.norm(); - self.z.norm(); - - return 1; - } - -/* self+=Q - return 0 for add, 1 for double, -1 for O */ - pub fn add(&mut self,Q:&mut ECP2) -> isize { - if self.inf { - self.copy(Q); - return -1; - } - if Q.inf {return -1} - - let mut aff=false; - - if Q.z.isunity() {aff=true} - - let mut a=FP2::new(); - let mut c=FP2::new(); - let mut b=FP2::new_copy(&self.z); - let mut d=FP2::new_copy(&self.z); - - if !aff { - a.copy(&Q.z); - c.copy(&Q.z); - - a.sqr(); b.sqr(); - c.mul(&mut a); d.mul(&mut b); - - a.mul(&mut self.x); - c.mul(&mut self.y); - } else { - a.copy(&self.x); - c.copy(&self.y); - - b.sqr(); - d.mul(&mut b); - } - - b.mul(&mut Q.x); b.sub(&a); - d.mul(&mut Q.y); d.sub(&c); - - if b.iszilch() { - if d.iszilch() { - self.dbl(); - return 1; - } else { - self.inf=true; - return -1; - } - } - - if !aff {self.z.mul(&mut Q.z)} - self.z.mul(&mut b); - - let mut e=FP2::new_copy(&b); e.sqr(); - b.mul(&mut e); - a.mul(&mut e); - - e.copy(&a); - e.add(&a); e.add(&b); - self.x.copy(&d); self.x.sqr(); self.x.sub(&e); - - a.sub(&self.x); - self.y.copy(&a); self.y.mul(&mut d); - c.mul(&mut b); self.y.sub(&c); - - self.x.norm(); - self.y.norm(); - self.z.norm(); - - return 0; - } - -/* set this-=Q */ - pub fn sub(&mut self,Q :&mut ECP2) -> isize { - Q.neg(); - let d=self.add(Q); - Q.neg(); - return d; - } - -/* set this*=q, where q is Modulus, using Frobenius */ - pub fn frob(&mut self,x:&mut 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(&mut x2); - self.y.mul(&mut x2); - self.y.mul(x); - } - -/* normalises m-array of ECP2 points. Requires work vector of m FP2s */ - - pub fn multiaffine(P: &mut [ECP2]) { - let mut t1=FP2::new(); - let mut t2=FP2::new(); - - let mut work:[FP2;8]=[FP2::new(),FP2::new(),FP2::new(),FP2::new(),FP2::new(),FP2::new(),FP2::new(),FP2::new()]; - let m=8; - - work[0].one(); - work[1].copy(&P[0].z); - - for i in 2..m { - t1.copy(&work[i-1]); - work[i].copy(&t1); - work[i].mul(&mut P[i-1].z) - } - - t1.copy(&work[m-1]); - t1.mul(&mut P[m-1].z); - t1.inverse(); - t2.copy(&P[m-1].z); - work[m-1].mul(&mut t1); - - let mut i=m-2; - - loop { - if i==0 { - work[0].copy(&t1); - work[0].mul(&mut t2); - break; - } - work[i].mul(&mut t2); - work[i].mul(&mut t1); - t2.mul(&mut P[i].z); - i-=1; - } -/* now work[] contains inverses of all Z coordinates */ - - for i in 0..m { - P[i].z.one(); - t1.copy(&work[i]); t1.sqr(); - P[i].x.mul(&mut t1); - t1.mul(&mut work[i]); - P[i].y.mul(&mut t1); - } - } - -/* self*=e */ - pub fn mul(&mut 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+(rom::NLEN*(rom::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); - } - -/* convert the table to affine */ - - ECP2::multiaffine(&mut W); - -/* 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 */ - pub fn mul4(Q: &mut [ECP2],u: &[BIG]) -> ECP2 { - let mut a:[i8;4]=[0;4]; - let mut T=ECP2::new(); - let mut C=ECP2::new(); - let mut P=ECP2::new(); - - let mut W:[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+rom::NLEN*(rom::BASEBITS as usize); - let mut w:[i8;CT]=[0;CT]; - - for i in 0..4 { - Q[i].affine(); - } - -/* precompute table */ - - W[0].copy(&Q[0]); W[0].sub(&mut Q[1]); - C.copy(&W[0]); W[1].copy(&C); - W[2].copy(&C); - W[3].copy(&C); - W[4].copy(&Q[0]); W[4].add(&mut Q[1]); - C.copy(&W[4]); W[5].copy(&C); - W[6].copy(&C); - W[7].copy(&C); - - T.copy(&Q[2]); T.sub(&mut Q[3]); - W[1].sub(&mut T); - W[2].add(&mut T); - W[5].sub(&mut T); - W[6].add(&mut T); - T.copy(&Q[2]); T.add(&mut Q[3]); - W[0].sub(&mut T); - W[3].add(&mut T); - W[4].sub(&mut T); - W[7].add(&mut T); - - ECP2::multiaffine(&mut W); - -/* if multiplier is even add 1 to multiplier, and add P to correction */ - mt.zero(); C.inf(); - for i in 0..4 { - if t[i].parity()==0 { - t[i].inc(1); t[i].norm(); - C.add(&mut Q[i]); - } - mt.add(&t[i]); mt.norm(); - } - - let nb=1+mt.nbits(); - -/* convert exponent to signed 1-bit window */ - for j in 0..nb { - for i in 0..4 { - a[i]=(t[i].lastbits(2)-2) as i8; - t[i].dec(a[i] as isize); t[i].norm(); - t[i].fshr(1); - } - w[j]=8*a[0]+4*a[1]+2*a[2]+a[3]; - } - w[nb]=(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2)) as i8; - - P.copy(&W[((w[nb] as usize)-1)/2]); - for i in (0..nb).rev() { - T.selector(&W,w[i] as i32); - P.dbl(); - P.add(&mut T); - } - P.sub(&mut C); /* apply correction */ - - P.affine(); - return P; - } - -} -/* -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()); -} -*/
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/ff.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/ff.rs b/version22/rust/src/ff.rs deleted file mode 100644 index d59525f..0000000 --- a/version22/rust/src/ff.rs +++ /dev/null @@ -1,944 +0,0 @@ -/* -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 -if debug {println!("sf2= {}",self.tostring())} - 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. -*/ - -//#[derive(Copy, Clone)] -pub struct FF { - v:Vec<BIG>, - length:usize -} - -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rom; -use rom; -use rom::Chunk; -//mod rand; -use rand::RAND; -//mod hash256; -//use std::process; - - -//static mut debug:bool=false; - -impl FF { - -/* Constructors */ - pub fn new_int(n:usize) -> FF { - let mut f=FF{v:Vec::new(),length:0}; - for _ in 0..n { - f.v.push(BIG::new()); - } - f.length=n; - return f; - } -/* - pub fn new_ints(x: &[&[i32];rom::NLEN],n: usize) -> FF { - let mut f=FF{v:Vec::new(),length:0}; - for i in 0..n { - f.v.push(BIG::new_ints(x[i])); - } - f.length=n; - return f; - } -*/ - pub fn zero(&mut self) { - for i in 0..self.length { - self.v[i].zero(); - } - } - - pub fn getlen(&self) -> usize { - return self.length; - } - -/* set to integer */ - pub fn set(&mut self,m:isize) { - self.zero(); - self.v[0].set(0,m as Chunk); - } - -/* copy from FF b */ - pub fn copy(&mut self,b: &FF) { - for i in 0..self.length { - self.v[i].copy(&b.v[i]); - } - } - -/* x=y<<n */ - pub fn dsucopy(&mut self,b: &FF) { - for i in 0..b.length { - self.v[b.length+i].copy(&b.v[i]); - self.v[i].zero(); - } - } - -/* x=y */ - pub fn dscopy(&mut self,b: &FF) { - for i in 0..b.length { - self.v[i].copy(&b.v[i]); - self.v[b.length+i].zero(); - } - } - -/* x=y>>n */ - pub fn sducopy(&mut self,b: &FF) { - for i in 0..self.length { - self.v[i].copy(&b.v[self.length+i]); - } - } - - pub fn one(&mut self) { - self.v[0].one(); - for i in 1..self.length { - self.v[i].zero(); - } - } - -/* test equals 0 */ - pub fn iszilch(&mut self) -> bool { - for i in 0..self.length { - if !self.v[i].iszilch() {return false} - } - return true; - } - -/* shift right by BIGBITS-bit words */ - pub fn shrw(&mut self,n: usize) { - let mut t= BIG::new(); - for i in 0..n { - t.copy(&self.v[i+n]); - self.v[i].copy(&t); - self.v[i+n].zero(); - } - } - -/* shift left by BIGBITS-bit words */ - pub fn shlw(&mut self,n: usize) { - let mut t= BIG::new(); - for i in 0..n { - t.copy(&self.v[i]); - self.v[n+i].copy(&t); - self.v[i].zero(); - } - } - -/* extract last bit */ - pub fn parity(&self) -> isize { - return self.v[0].parity(); - } - - pub fn lastbits(&mut self,m: usize) -> isize { - return self.v[0].lastbits(m); - } - -/* compare x and y - must be normalised, and of same length */ - pub fn comp(a: &FF,b: &FF) -> isize { - let mut i=a.length-1; - - loop { - let j=BIG::comp(&a.v[i],&b.v[i]); - if j!=0 {return j} - if i==0 {break;} - i-=1; - } - return 0; - } - -/* recursive add */ - pub fn radd(&mut self,vp: usize,x: &FF,xp: usize,y: &FF,yp: usize,n: usize) { - for i in 0..n { - self.v[vp+i].copy(&x.v[xp+i]); - self.v[vp+i].add(&y.v[yp+i]); - } - } - -/* recursive inc */ - pub fn rinc(&mut self,vp: usize,y: &FF,yp: usize,n: usize) { - for i in 0..n { - self.v[vp+i].add(&y.v[yp+i]); - } - } - - pub fn rsinc(&mut self,n: usize) { - let mut t=BIG::new(); - for i in 0..n { - t.copy(&self.v[i]); - self.v[n+i].add(&t); - } - } - -/* recursive sub */ - pub fn rsub(&mut self,vp: usize,x: &FF,xp: usize,y: &FF,yp: usize,n: usize) { - for i in 0..n { - self.v[vp+i].copy(&x.v[xp+i]); - self.v[vp+i].sub(&y.v[yp+i]); - } - } - -/* recursive dec */ - pub fn rdec(&mut self,vp: usize,y: &FF,yp: usize,n: usize) { - for i in 0..n { - self.v[vp+i].sub(&y.v[yp+i]); - } - } - -/* simple add */ - pub fn add(&mut self,b: &FF) { - for i in 0..self.length { - self.v[i].add(&b.v[i]); - } - } - -/* simple sub */ - pub fn sub(&mut self,b: &FF) { - for i in 0..self.length { - self.v[i].sub(&b.v[i]); - } - } - -/* reverse sub */ - pub fn revsub(&mut self,b: &FF) { - for i in 0..self.length { - self.v[i].rsub(&b.v[i]); - } - } - -/* normalise - but hold any overflow in top part unless n<0 */ - pub fn rnorm(&mut self,vp: usize,n: isize) { - let mut trunc=false; - let mut carry:Chunk; - let mut nn:usize=n as usize; - if n<0 { /* -v n signals to do truncation */ - nn=(-n) as usize; - trunc=true; - } - for i in 0..nn-1 { - carry=self.v[vp+i].norm(); - self.v[vp+i].xortop(carry<<rom::P_TBITS); - self.v[vp+i+1].w[0]+=carry; //incl(carry); - } - carry=self.v[vp+nn-1].norm(); - if trunc { - self.v[vp+nn-1].xortop(carry<<rom::P_TBITS); - } - } - - pub fn norm(&mut self) { - let n:isize=self.length as isize; - self.rnorm(0,n); - } - -/* increment/decrement by a small integer */ - pub fn inc(&mut self,m: isize) { - self.v[0].inc(m); - self.norm(); - } - - pub fn dec(&mut self,m: isize) { - self.v[0].dec(m); - self.norm(); - } - -/* shift left by one bit */ - pub fn shl(&mut self) { - let mut delay_carry:isize=0; - for i in 0..self.length-1 { - let carry=self.v[i].fshl(1); - self.v[i].inc(delay_carry); - self.v[i].xortop((carry as Chunk)<<rom::P_TBITS); - delay_carry=carry; - } - self.v[self.length-1].fshl(1); - self.v[self.length-1].inc(delay_carry); - } - -/* shift right by one bit */ - - pub fn shr(&mut self) { - let mut i=self.length-1; - while i>0 { - let carry=self.v[i].fshr(1); - self.v[i-1].xortop((carry as Chunk)<<rom::P_TBITS); - i-=1; - } - self.v[0].fshr(1); - } - -/* Convert to Hex String */ - pub fn tostring(&mut self) -> String { - self.norm(); - let mut s = String::new(); - let mut i:usize=self.length-1; - loop { - s=s+self.v[i].tostring().as_ref(); - if i==0 {break} - i-=1; - } - return s; - } - -/* Convert to Hex String - pub fn tostr(&mut self,n:usize) -> String { - let mut t=FF::new_int(n); - for i in 0..n { - t.v[i].copy(&self.v[i]); - } - t.norm(); - let mut s = String::new(); - let mut i:usize=t.length-1; - loop { - s=s+t.v[i].tostring().as_ref(); - if i==0 {break} - i-=1; - } - return s; - }*/ - -/* Convert FFs to/from byte arrays */ - pub fn tobytes(&mut self,b: &mut [u8]) { - for i in 0..self.length { - self.v[i].tobytearray(b,(self.length-i-1)*(rom::MODBYTES as usize)) - } - } - - pub fn frombytes(x: &mut FF,b: &[u8]) { - for i in 0..x.length { - x.v[i]=BIG::frombytearray(b,(x.length-i-1)*(rom::MODBYTES as usize)) - } - } - -/* in-place swapping using xor - side channel resistant - lengths must be the same */ - pub fn cswap(a: &mut FF,b: &mut FF,d: isize) { - for i in 0..a.length { - a.v[i].cswap(&mut b.v[i],d); - } - } - -/* z=x*y, t is workspace */ - fn karmul(&mut self,vp: usize,x: &FF,xp: usize,y: &FF,yp: usize,t: *mut FF,tp: usize,n: usize) { - if n==1 { - let mut d=BIG::mul(&x.v[xp],&y.v[yp]); - self.v[vp+1]=d.split(8*rom::MODBYTES); - self.v[vp].dcopy(&d); - return; - } - let nd2=n/2; - self.radd(vp,x,xp,x,xp+nd2,nd2); - self.rnorm(vp,nd2 as isize); /* Important - required for 32-bit build */ - self.radd(vp+nd2,y,yp,y,yp+nd2,nd2); - self.rnorm(vp+nd2,nd2 as isize); /* Important - required for 32-bit build */ - unsafe{ - (*t).karmul(tp,self,vp,self,vp+nd2,t,tp+n,nd2); - } - self.karmul(vp,x,xp,y,yp,t,tp+n,nd2); - self.karmul(vp+n,x,xp+nd2,y,yp+nd2,t,tp+n,nd2); - unsafe { - (*t).rdec(tp,self,vp,n); - (*t).rdec(tp,self,vp+n,n); - self.rinc(vp+nd2,&(*t),tp,n); - } - self.rnorm(vp,(2*n) as isize); - } - - fn karsqr(&mut self,vp: usize,x: &FF,xp: usize,t: *mut FF,tp: usize,n: usize) { - if n==1 { - let mut d=BIG::sqr(&x.v[xp]); - self.v[vp+1].copy(&d.split(8*rom::MODBYTES)); - self.v[vp].dcopy(&d); - return; - } - - let nd2=n/2; - self.karsqr(vp,x,xp,t,tp+n,nd2); - self.karsqr(vp+n,x,xp+nd2,t,tp+n,nd2); - unsafe { - (*t).karmul(tp,x,xp,x,xp+nd2,t,tp+n,nd2); - self.rinc(vp+nd2,&(*t),tp,n); - self.rinc(vp+nd2,&(*t),tp,n); - } - self.rnorm(vp+nd2,n as isize); - } - -/* Calculates Least Significant bottom half of x*y */ - fn karmul_lower(&mut self,vp: usize,x: &FF,xp: usize,y: &FF,yp: usize,t: *mut FF,tp: usize,n: usize) { - if n==1 { /* only calculate bottom half of product */ - self.v[vp].copy(&BIG::smul(&x.v[xp],&y.v[yp])); - return; - } - let nd2=n/2; - - self.karmul(vp,x,xp,y,yp,t,tp+n,nd2); - unsafe { - (*t).karmul_lower(tp,x,xp+nd2,y,yp,t,tp+n,nd2); - self.rinc(vp+nd2,&(*t),tp,nd2); - (*t).karmul_lower(tp,x,xp,y,yp+nd2,t,tp+n,nd2); - self.rinc(vp+nd2,&(*t),tp,nd2); - } - let sn:isize=nd2 as isize; - self.rnorm(vp+nd2,-sn); /* truncate it */ - } - -/* Calculates Most Significant upper half of x*y, given lower part */ - fn karmul_upper(&mut self,x: &FF,y: &FF,t: *mut FF,n: usize) { - let nd2=n/2; - self.radd(n,x,0,x,nd2,nd2); - self.radd(n+nd2,y,0,y,nd2,nd2); - self.rnorm(n,nd2 as isize); - self.rnorm(n+nd2,nd2 as isize); - - unsafe { - (*t).karmul(0,self,n+nd2,self,n,t,n,nd2); /* t = (a0+a1)(b0+b1) */ - - } - self.karmul(n,x,nd2,y,nd2,t,n,nd2); /* z[n]= a1*b1 */ - /* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */ - unsafe { - (*t).rdec(0,self,n,n); /* t=t-a1b1 */ - self.rsinc(nd2); /* z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1) */ - self.rdec(nd2,&(*t),0,nd2); /* z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) */ - } - - let sn:isize=n as isize; - self.rnorm(0,-sn); /* a0b0 now in z - truncate it */ - unsafe { - (*t).rdec(0,self,0,n); /* (a0+a1)(b0+b1) - a0b0 */ - self.rinc(nd2,&(*t),0,n); - } - self.rnorm(nd2,sn); - } - -/* z=x*y. Assumes x and y are of same length. */ - pub fn mul(x: &FF,y: &FF) -> FF { - let n=x.length; - let mut z=FF::new_int(2*n); - let mut t=FF::new_int(2*n); - // x.norm(); y.norm(); - z.karmul(0,&x,0,&y,0,&mut t,0,n); - return z; - } - -/* return low part of product this*y */ - pub fn lmul(&mut self,y: &FF) { - let n=self.length; - let mut t=FF::new_int(2*n); - let mut x=FF::new_int(n); x.copy(&self); - // x.norm(); y.norm(); - self.karmul_lower(0,&x,0,&y,0,&mut t,0,n); - } - -/* Set b=b mod c */ - pub fn rmod(&mut self,m: &FF) { - let mut k=1; - let n=m.length; - let mut c=FF::new_int(n); c.copy(m); - - self.norm(); - if FF::comp(&self,&c)<0 {return} - - c.shl(); - while FF::comp(&self,&c)>=0 { - c.shl(); - k+=1; - } - - while k>0 { - c.shr(); - if FF::comp(&self,&c)>=0 { - self.sub(&c); - self.norm(); - } - k-=1; - } - } - -/* z=x^2 */ - pub fn sqr(x: &FF) -> FF { - let n=x.length; - let mut z=FF::new_int(2*n); - let mut t=FF::new_int(2*n); - // x.norm(); - z.karsqr(0,&x,0,&mut t,0,n); - return z; - } - -/* return This mod modulus, ms is modulus, md is Montgomery Constant */ - pub fn reduce(&mut self,ms: &FF,md: &FF) -> FF { /* fast karatsuba Montgomery reduction */ - let n=ms.length; - let mut t=FF::new_int(2*n); - let mut r=FF::new_int(n); - let mut m=FF::new_int(n); - - r.sducopy(&self); - m.karmul_lower(0,&self,0,&md,0,&mut t,0,n); - self.karmul_upper(&ms,&m,&mut t,n); - - m.sducopy(self); - r.add(&ms); - r.sub(&m); - r.norm(); - - return r; - } - -/* Set r=this mod b */ -/* this is of length - 2*n */ -/* r,b is of length - n */ - pub fn dmod(&mut self,b: &FF) -> FF { - let n=b.length; - let mut m=FF::new_int(2*n); - let mut x=FF::new_int(2*n); - let mut r=FF::new_int(n); - - x.copy(&self); - x.norm(); - m.dsucopy(&b); let mut k=rom::BIGBITS*n; - - while FF::comp(&x,&m)>=0 { - x.sub(&m); - x.norm(); - } - - while k>0 { - m.shr(); - - if FF::comp(&x,&m)>=0 { - x.sub(&m); - x.norm(); - } - k-=1; - } - - r.copy(&x); - r.rmod(b); - return r; - } - -/* Set return=1/this mod p. Binary method - a<p on entry */ - - pub fn invmodp(&mut self,p: &FF) { - let n=p.length; - - let mut u=FF::new_int(n); - let mut v=FF::new_int(n); - let mut x1=FF::new_int(n); - let mut x2=FF::new_int(n); - let mut t=FF::new_int(n); - let mut one=FF::new_int(n); - - one.one(); - u.copy(&self); - v.copy(&p); - x1.copy(&one); - x2.zero(); - - // reduce n in here as well! - while FF::comp(&u,&one)!=0 && FF::comp(&v,&one)!=0 { - while u.parity()==0 { - u.shr(); - if x1.parity()!=0 { - x1.add(&p); - x1.norm(); - } - x1.shr(); - } - while v.parity()==0 { - v.shr(); - if x2.parity()!=0 { - x2.add(&p); - x2.norm(); - } - x2.shr(); - } - if FF::comp(&u,&v)>=0 { - u.sub(&v); - u.norm(); - if FF::comp(&x1,&x2)>=0 { - x1.sub(&x2); - } else { - t.copy(&p); - t.sub(&x2); - x1.add(&t); - } - x1.norm(); - } else { - v.sub(&u); - v.norm(); - if FF::comp(&x2,&x1)>=0 { - x2.sub(&x1); - } else { - t.copy(&p); - t.sub(&x1); - x2.add(&t); - } - x2.norm(); - } - } - if FF::comp(&u,&one)==0 { - self.copy(&x1); - } else { - self.copy(&x2); - } - } - -/* nresidue mod m */ - pub fn nres(&mut self,m: &FF) { - let n=m.length; - let mut d=FF::new_int(2*n); - d.dsucopy(&self); - self.copy(&d.dmod(m)); - } - - pub fn redc(&mut self,m: &FF,md: &FF) { - let n=m.length; - let mut d=FF::new_int(2*n); - self.rmod(m); - d.dscopy(&self); - self.copy(&d.reduce(&m,&md)); - self.rmod(m); - } - - pub fn mod2m(&mut self,m: usize) { - for i in m..self.length { - self.v[i].zero() - } - } - -/* U=1/a mod 2^m - Arazi & Qi */ - pub fn invmod2m(&self) -> FF { - let n=self.length; - - let mut b=FF::new_int(n); - let mut c=FF::new_int(n); - let mut u=FF::new_int(n); - - u.zero(); - u.v[0].copy(&self.v[0]); - u.v[0].invmod2m(); - - let mut i=1; - while i<n { - b.copy(&self); b.mod2m(i); - let mut t=FF::mul(&u,&b); t.shrw(i); b.copy(&t); - c.copy(&self); c.shrw(i); c.mod2m(i); - c.lmul(&u); c.mod2m(i); - - b.add(&c); b.norm(); - b.lmul(&u); b.mod2m(i); - - c.one(); c.shlw(i); b.revsub(&c); b.norm(); - b.shlw(i); - u.add(&b); - i<<=1; - } - u.norm(); - return u; - } - - pub fn random(&mut self,rng: &mut RAND) { - let n=self.length; - for i in 0..n { - self.v[i].copy(&BIG::random(rng)) - } - /* make sure top bit is 1 */ - while self.v[n-1].nbits()<(rom::MODBYTES as usize)*8 { - self.v[n-1].copy(&BIG::random(rng)); - } - } - -/* generate random x less than p */ - pub fn randomnum(&mut self,p: &FF,rng: &mut RAND) { - let n=self.length; - let mut d=FF::new_int(2*n); - - for i in 0..2*n { - d.v[i].copy(&BIG::random(rng)); - } - self.copy(&d.dmod(p)); - } - -/* this*=y mod p */ - pub fn modmul(&mut self,y: &FF,p: &FF,nd: &FF) { - if BIG::ff_pexceed(&self.v[self.length-1],&y.v[y.length-1]) { - self.rmod(p) - } - let mut d=FF::mul(&self,y); - self.copy(&d.reduce(p,nd)); - } - -/* this*=y mod p */ - pub fn modsqr(&mut self,p: &FF,nd: &FF) { - if BIG::ff_sexceed(&self.v[self.length-1]) { - self.rmod(p); - } - let mut d=FF::sqr(&self); - d.norm(); - self.copy(&d.reduce(p,nd)); - } - -/* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */ - pub fn skpow(&mut self,e: &FF,p: &FF) { - let n=p.length; - let mut r0=FF::new_int(n); - let mut r1=FF::new_int(n); - let nd=p.invmod2m(); - - self.rmod(p); - r0.one(); - r1.copy(&self); - r0.nres(p); - r1.nres(p); - - let mut i=8*(rom::MODBYTES as usize)*n-1; - loop { - let b=(e.v[i/(rom::BIGBITS as usize)]).bit(i%(rom::BIGBITS as usize)) as isize; - self.copy(&r0); - self.modmul(&r1,p,&nd); - - FF::cswap(&mut r0,&mut r1,b); - r0.modsqr(p,&nd); - - r1.copy(&self); - FF::cswap(&mut r0,&mut r1,b); - if i==0 {break} - i-=1; - } - self.copy(&r0); - self.redc(p,&nd); - } - -/* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */ - pub fn skpows(&mut self,e: &BIG,p: &FF) { - let n=p.length; - let mut r0=FF::new_int(n); - let mut r1=FF::new_int(n); - let nd=p.invmod2m(); - - self.rmod(p); - r0.one(); - r1.copy(&self); - r0.nres(p); - r1.nres(p); - - let mut i=8*(rom::MODBYTES as usize)-1; - loop { - let b=e.bit(i); - self.copy(&r0); - self.modmul(&r1,p,&nd); - - FF::cswap(&mut r0,&mut r1,b); - r0.modsqr(p,&nd); - - r1.copy(&self); - FF::cswap(&mut r0,&mut r1,b); - if i==0 {break} - i-=1; - } - self.copy(&r0); - self.redc(p,&nd); - } - - - - -/* raise to an integer power - right-to-left method */ - pub fn power(&mut self,e: isize,p: &FF) { - let n=p.length; - let mut w=FF::new_int(n); - let nd=p.invmod2m(); - let mut f=true; - let mut ee=e; - - w.copy(&self); - w.nres(p); - - if ee==2 { - self.copy(&w); - self.modsqr(p,&nd); - } else { - loop { - if ee%2==1 { - if f { - self.copy(&w); - } else {self.modmul(&w,p,&nd)} - f=false; - } - ee>>=1; - if ee==0 {break} - w.modsqr(p,&nd); - } - } - - self.redc(p,&nd); - } - -/* this=this^e mod p, faster but not side channel resistant */ - pub fn pow(&mut self,e: &FF,p: &FF) { - let n=p.length; - let mut w=FF::new_int(n); - let nd=p.invmod2m(); - - w.copy(&self); - self.one(); - self.nres(p); - w.nres(p); - let mut i=8*(rom::MODBYTES as usize)*n-1; - loop { - self.modsqr(p,&nd); - let b=(e.v[i/(rom::BIGBITS as usize)]).bit(i%(rom::BIGBITS as usize)) as isize; - if b==1 {self.modmul(&w,p,&nd)} - if i==0 {break} - i-=1; - } - self.redc(p,&nd); - } - -/* double exponentiation r=x^e.y^f mod p */ - pub fn pow2(&mut self,e: &BIG,y: &FF,f: &BIG,p: &FF) { - let n=p.length; - let mut xn=FF::new_int(n); - let mut yn=FF::new_int(n); - let mut xy=FF::new_int(n); - let nd=p.invmod2m(); - - xn.copy(&self); - yn.copy(y); - xn.nres(p); - yn.nres(p); - xy.copy(&xn); xy.modmul(&yn,p,&nd); - self.one(); - self.nres(p); - - let mut i=8*(rom::MODBYTES as usize)-1; - loop { - let eb=e.bit(i); - let fb=f.bit(i); - self.modsqr(p,&nd); - if eb==1 { - if fb==1 { - self.modmul(&xy,p,&nd); - } else {self.modmul(&xn,p,&nd)} - } else { - if fb==1 {self.modmul(&yn,p,&nd)} - } - if i==0 {break} - i-=1; - } - self.redc(p,&nd); - } - - pub fn igcd(x: isize,y: isize) -> isize { /* integer GCD, returns GCD of x and y */ - - if y==0 {return x} - let mut xx=x; - let mut yy=y; - loop { - let r=xx%yy; - if r==0 {break} - xx=yy;yy=r; - } - return yy; - } - -/* quick and dirty check for common factor with n */ - pub fn cfactor(&self,s: isize) -> bool { - let n=self.length; - - let mut x=FF::new_int(n); - let mut y=FF::new_int(n); - - y.set(s); - x.copy(&self); - x.norm(); - - x.sub(&y); - x.norm(); - - while !x.iszilch() && x.parity()==0 {x.shr()} - - while FF::comp(&x,&y)>0 { - x.sub(&y); - x.norm(); - while !x.iszilch() && x.parity()==0 {x.shr()} - } - - let g=x.v[0].get(0) as isize; - let r=FF::igcd(s,g); - if r>1 {return true} - return false - } - -/* Miller-Rabin test for primality. Slow. */ - pub fn prime(pp: &FF,rng: &mut RAND) -> bool { - let mut s=0; - let n=pp.length; - let mut d=FF::new_int(n); - let mut x=FF::new_int(n); - let mut unity=FF::new_int(n); - let mut nm1=FF::new_int(n); - let mut p=FF::new_int(n); p.copy(pp); - - let sf=4849845; /* 3*5*.. *19 */ - p.norm(); - - if p.cfactor(sf) {return false} - unity.one(); - nm1.copy(&p); - nm1.sub(&unity); - nm1.norm(); - d.copy(&nm1); - - while d.parity()==0 { - d.shr(); - s+=1; - } - if s==0 {return false} - for _ in 0..10 { - x.randomnum(&p,rng); - - x.pow(&d,&p); - - if FF::comp(&x,&unity)==0 || FF::comp(&x,&nm1)==0 {continue} - let mut looper=false; - for _ in 1..s { - x.power(2,&p); - if FF::comp(&x,&unity)==0 {return false} - if FF::comp(&x,&nm1)==0 {looper=true; break} - } - if looper {continue} - return false; - } - - return true; - } - -} -/* -fn main() -{ - let mut x=FF::new_int(4); - let mut y=FF::new_int(4); - - x.one(); y.one(); - let mut z=FF::mul(&mut x,&mut y); - - println!("z= {}",z.tostring()); -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/fp.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/fp.rs b/version22/rust/src/fp.rs deleted file mode 100644 index 39104bd..0000000 --- a/version22/rust/src/fp.rs +++ /dev/null @@ -1,354 +0,0 @@ -/* -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 std::fmt; -use std::str::SplitWhitespace; - -#[derive(Copy, Clone)] -pub struct FP { - x:BIG -} - -use big::BIG; -use dbig::DBIG; -use rom; -use rom::{Chunk, BIG_HEX_STRING_LEN}; - -impl fmt::Display for FP { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP: [ {} ]", self.x) - } -} - -impl fmt::Debug for FP { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP: [ {} ]", self.x) - } -} - -impl PartialEq for FP { - fn eq(&self, other: &FP) -> bool { - return self.x == other.x; - } -} - -impl FP { - -/* Constructors */ - pub fn new() -> FP { - FP { - x: BIG::new() - } - } - - pub fn new_int(a:isize) -> FP { - let mut f=FP::new(); - f.x.inc(a); - f.nres(); - return f; - } - - pub fn new_copy(y:&FP) -> FP { - let mut f=FP::new(); - f.x.copy(&(y.x)); - return f; - } - - pub fn new_big(y:&BIG) -> FP { - let mut f=FP::new(); - f.x.copy(y); - f.nres(); - return f; - } - - pub fn nres(&mut self) { - if rom::MODTYPE != rom::PSEUDO_MERSENNE && rom::MODTYPE != rom::GENERALISED_MERSENNE { - let p = BIG::new_ints(&rom::MODULUS); - let mut d=DBIG::new_scopy(&(self.x)); - d.shl(rom::NLEN*(rom::BASEBITS as usize)); - self.x.copy(&d.dmod(&p)); - } - } - -/* convert back to regular form */ - pub fn redc(&mut self) -> BIG { - if rom::MODTYPE != rom::PSEUDO_MERSENNE && rom::MODTYPE != rom::GENERALISED_MERSENNE { - let mut d=DBIG::new_scopy(&(self.x)); - return BIG::modulo(&mut d); - } else { - let r=BIG::new_copy(&(self.x)); - return r; - } - } - - /* convert to string */ - pub fn tostring(&mut self) -> String { - let s=self.redc().tostring(); - return s; - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(2 * BIG_HEX_STRING_LEN); - ret.push_str(&format!("{}", self.x.to_hex())); - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP { - FP { - x: BIG::from_hex_iter(iter) - } - } - - pub fn from_hex(val: String) -> FP { - let mut iter = val.split_whitespace(); - return FP::from_hex_iter(&mut iter); - } - -/* reduce this mod Modulus */ - pub fn reduce(&mut self) { - let p = BIG::new_ints(&rom::MODULUS); - self.x.rmod(&p) - } - -/* test this=0? */ - pub fn iszilch(&mut self) -> bool { - self.reduce(); - return self.x.iszilch(); - } - -/* copy from FP b */ - pub fn copy(&mut self,b: &FP) { - self.x.copy(&(b.x)); - } - -/* copy from BIG b */ - pub fn bcopy(&mut self,b: &BIG) { - self.x.copy(&b); - self.nres(); - } - -/* set this=0 */ - pub fn zero(&mut self) { - self.x.zero(); - } - -/* set this=1 */ - pub fn one(&mut self) { - self.x.one(); self.nres() - } - -/* normalise this */ - pub fn norm(&mut self) { - self.x.norm(); - } -/* swap FPs depending on d */ - pub fn cswap(&mut self,b: &mut FP,d: isize) { - self.x.cswap(&mut (b.x),d); - } - -/* copy FPs depending on d */ - pub fn cmove(&mut self,b: &FP,d: isize) { - self.x.cmove(&(b.x),d); - } - -/* this*=b mod Modulus */ - pub fn mul(&mut self,b: &mut FP) - { - self.norm(); - b.norm(); - if BIG::pexceed(&(self.x),&(b.x)) {self.reduce()} - - let mut d=BIG::mul(&(self.x),&(b.x)); - self.x.copy(&BIG::modulo(&mut d)) - } - - fn logb2(w: u32) -> usize { - let mut v=w; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - - v = v - ((v >> 1) & 0x55555555); - v = (v & 0x33333333) + ((v >> 2) & 0x33333333); - let r= (( ((v + (v >> 4)) & 0xF0F0F0F).wrapping_mul(0x1010101)) >> 24) as usize; - return r+1; - } - -/* this = -this mod Modulus */ - pub fn neg(&mut self) { - let mut p = BIG::new_ints(&rom::MODULUS); - - self.norm(); - - let sb=FP::logb2(BIG::excess(&(self.x)) as u32); - - // let mut ov=BIG::excess(&(self.x)); - // let mut sb=1; while ov != 0 {sb += 1;ov>>=1} - - p.fshl(sb); - self.x.rsub(&p); - - if BIG::excess(&(self.x))>=rom::FEXCESS {self.reduce()} - } - - /* this*=c mod Modulus, where c is a small int */ - pub fn imul(&mut self,c: isize) { - let mut cc=c; - self.norm(); - let mut s=false; - if cc<0 { - cc = -cc; - s=true; - } - let afx=(BIG::excess(&(self.x))+1)*((cc as Chunk)+1)+1; - if cc<rom::NEXCESS && afx<rom::FEXCESS { - self.x.imul(cc); - } else { - if afx<rom::FEXCESS { - self.x.pmul(cc); - } else { - let p = BIG::new_ints(&rom::MODULUS); - let mut d=self.x.pxmul(cc); - self.x.copy(&d.dmod(&p)); - } - } - if s {self.neg()} - self.norm(); - } - -/* self*=self mod Modulus */ - pub fn sqr(&mut self) { - self.norm(); - if BIG::sexceed(&(self.x)) {self.reduce()} - - let mut d=BIG::sqr(&(self.x)); - self.x.copy(&BIG::modulo(&mut d)) - } - -/* self+=b */ - pub fn add(&mut self,b: &FP) { - self.x.add(&(b.x)); - if BIG::excess(&(self.x))+2>=rom::FEXCESS {self.reduce()} - } - -/* self+=self */ - pub fn dbl(&mut self) { - self.x.dbl(); - if BIG::excess(&(self.x))+2>=rom::FEXCESS {self.reduce()} - } - -/* self-=b */ - pub fn sub(&mut self,b: &FP) - { - let mut n=FP::new_copy(b); - n.neg(); - self.add(&n); - } - -/* self/=2 mod Modulus */ - pub fn div2(&mut self) { - self.x.norm(); - if self.x.parity()==0 { - self.x.fshr(1); - } else { - let p = BIG::new_ints(&rom::MODULUS); - self.x.add(&p); - self.x.norm(); - self.x.fshr(1); - } - } -/* self=1/self mod Modulus */ - pub fn inverse(&mut self) { - let mut p = BIG::new_ints(&rom::MODULUS); - let mut r=self.redc(); - r.invmodp(&mut p); - self.x.copy(&r); - self.nres(); - } - -/* return TRUE if self==a */ - pub fn equals(&mut self,a: &mut FP) -> bool { - a.reduce(); - self.reduce(); - if BIG::comp(&(a.x),(&self.x))==0 {return true} - return false; - } - -/* return self^e mod Modulus */ - pub fn pow(&mut self,e: &mut BIG) -> FP { - let p = BIG::new_ints(&rom::MODULUS); - let mut r=FP::new_int(1); - e.norm(); - self.x.norm(); - let mut m=FP::new_copy(self); - loop { - let bt=e.parity(); - e.fshr(1); - if bt==1 {r.mul(&mut m)} - if e.iszilch() {break} - m.sqr(); - } - r.x.rmod(&p); - return r; - } - -/* return sqrt(this) mod Modulus */ - pub fn sqrt(&mut self) -> FP { - self.reduce(); - let mut p = BIG::new_ints(&rom::MODULUS); - if rom::MOD8==5 { - p.dec(5); p.norm(); p.shr(3); - let mut i=FP::new_copy(self); i.x.shl(1); - let mut v=i.pow(&mut p); - i.mul(&mut v); i.mul(&mut v); - i.x.dec(1); - let mut r=FP::new_copy(self); - r.mul(&mut v); r.mul(&mut i); - r.reduce(); - return r; - } - else - { - p.inc(1); p.norm(); p.shr(2); - return self.pow(&mut p); - } - } -/* return jacobi symbol (this/Modulus) */ - pub fn jacobi(&mut self) -> isize - { - let mut p = BIG::new_ints(&rom::MODULUS); - let mut w=self.redc(); - return w.jacobi(&mut p); - } - -} -/* -fn main() { - let p = BIG::new_ints(&rom::MODULUS); - let mut e = BIG::new_copy(&p); - e.dec(1); - - let mut x = FP::new_int(3); - let mut s=x.pow(&mut e); - - println!("s= {}",s.tostring()); -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/fp12.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/fp12.rs b/version22/rust/src/fp12.rs deleted file mode 100644 index 4610e67..0000000 --- a/version22/rust/src/fp12.rs +++ /dev/null @@ -1,628 +0,0 @@ -/* -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 std::fmt; -use std::str::SplitWhitespace; - -#[derive(Copy, Clone)] -pub struct FP12 { - a:FP4, - b:FP4, - c:FP4 -} - -use rom::BIG_HEX_STRING_LEN; - -//mod fp; -//use fp::FP; -//mod fp2; -use fp2::FP2; -//mod fp4; -use fp4::FP4; -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rand; -//mod hash256; -//mod rom; -use rom; - -impl PartialEq for FP12 { - fn eq(&self, other: &FP12) -> bool { - return (self.a == other.a) && - (self.b == other.b) && - (self.c == other.c); - } -} - -impl fmt::Display for FP12 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP12: [ {}, {}, {} ]", self.a, self.b, self.c) - } -} - -impl fmt::Debug for FP12 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP12: [ {}, {}, {} ]", self.a, self.b, self.c) - } -} - -impl FP12 { - - pub fn new() -> FP12 { - FP12 { - a: FP4::new(), - b: FP4::new(), - c: FP4::new() - } - } - - pub fn new_int(a: isize) -> FP12 { - let mut f=FP12::new(); - f.a.copy(&FP4::new_int(a)); - f.b.zero(); - f.c.zero(); - return f; - } - - pub fn new_copy(x: &FP12) -> FP12 { - let mut f=FP12::new(); - f.a.copy(&x.a); - f.b.copy(&x.b); - f.c.copy(&x.c); - return f; - } - - pub fn new_fp4s(d: &FP4,e: &FP4,f: &FP4) -> FP12 { - let mut g=FP12::new(); - g.a.copy(d); - g.b.copy(e); - g.c.copy(f); - return g; - } - - pub fn new_fp4(d: &FP4) -> FP12 { - let mut g=FP12::new(); - g.a.copy(d); - g.b.zero(); - g.c.zero(); - return g; - } - -/* reduce components mod Modulus */ - pub fn reduce(&mut self) { - self.a.reduce(); - self.b.reduce(); - self.c.reduce(); - } - -/* normalise components of w */ - pub fn norm(&mut self) { - self.a.norm(); - self.b.norm(); - self.c.norm(); - } - -/* test self=0 ? */ - pub fn iszilch(&mut self) -> bool { - self.reduce(); - return self.a.iszilch() && self.b.iszilch() && self.c.iszilch(); - } - -/* test self=1 ? */ - pub fn isunity(&mut self) -> bool { - let mut one=FP4::new_int(1); - return self.a.equals(&mut one) && self.b.iszilch() && self.c.iszilch(); - } - -/* test self=x */ - pub fn equals(&mut self,x:&mut FP12) -> bool { - return self.a.equals(&mut x.a) && self.b.equals(&mut x.b) && self.c.equals(&mut x.c); - } - - pub fn geta(&mut self) -> FP4 { - let f=FP4::new_copy(&self.a); - return f; - } - - pub fn getb(&mut self) -> FP4 { - let f=FP4::new_copy(&self.b); - return f; - } - - pub fn getc(&mut self) -> FP4 { - let f=FP4::new_copy(&self.c); - return f; - } - -/* copy self=x */ - pub fn copy(&mut self,x :&FP12) { - self.a.copy(&x.a); - self.b.copy(&x.b); - self.c.copy(&x.c); - } - -/* set self=1 */ - pub fn one(&mut self) { - self.a.one(); - self.b.zero(); - self.c.zero(); - } - -/* this=conj(this) */ - pub fn conj(&mut self) { - self.a.conj(); - self.b.nconj(); - self.c.conj(); - } - -/* Granger-Scott Unitary Squaring */ - pub fn usqr(&mut self) { - let mut a=FP4::new_copy(&self.a); - let mut b=FP4::new_copy(&self.c); - let mut c=FP4::new_copy(&self.b); - let mut d=FP4::new(); - - self.a.sqr(); - d.copy(&self.a); d.add(&self.a); - self.a.add(&d); - - self.a.norm(); - a.nconj(); - - a.dbl(); - self.a.add(&a); - b.sqr(); - b.times_i(); - - d.copy(&b); d.add(&b); - b.add(&d); - b.norm(); - - c.sqr(); - d.copy(&c); d.add(&c); - c.add(&d); - c.norm(); - - self.b.conj(); - self.b.dbl(); - self.c.nconj(); - - self.c.dbl(); - self.b.add(&b); - self.c.add(&c); - self.reduce(); - - } - -/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */ - pub fn sqr(&mut self) { - let mut a=FP4::new_copy(&self.a); - let mut b=FP4::new_copy(&self.b); - let mut c=FP4::new_copy(&self.c); - let mut d=FP4::new_copy(&self.a); - - a.sqr(); - b.mul(&mut self.c); - b.dbl(); - c.sqr(); - d.mul(&mut self.b); - d.dbl(); - - self.c.add(&self.a); - self.c.add(&self.b); - self.c.sqr(); - - self.a.copy(&a); - a.add(&b); - a.norm(); - a.add(&c); - a.add(&d); - a.norm(); - - a.neg(); - b.times_i(); - c.times_i(); - - self.a.add(&b); - - self.b.copy(&c); self.b.add(&d); - self.c.add(&a); - self.norm(); - } - - -/* FP12 full multiplication self=self*y */ - pub fn mul(&mut self,y: &mut FP12) { - let mut z0=FP4::new_copy(&self.a); - let mut z1=FP4::new(); - let mut z2=FP4::new_copy(&mut self.b); - let mut z3=FP4::new(); - let mut t0=FP4::new_copy(&self.a); - let mut t1=FP4::new_copy(&y.a); - - z0.mul(&mut y.a); - z2.mul(&mut y.b); - - t0.add(&self.b); - t1.add(&y.b); - - z1.copy(&t0); z1.mul(&mut t1); - t0.copy(&self.b); t0.add(&self.c); - - t1.copy(&y.b); t1.add(&y.c); - z3.copy(&t0); z3.mul(&mut t1); - - t0.copy(&z0); t0.neg(); - t1.copy(&z2); t1.neg(); - - z1.add(&t0); - z1.norm(); - self.b.copy(&z1); self.b.add(&t1); - - z3.add(&t1); - z2.add(&t0); - - t0.copy(&self.a); t0.add(&self.c); - t1.copy(&y.a); t1.add(&y.c); - t0.mul(&mut t1); - z2.add(&t0); - - t0.copy(&self.c); t0.mul(&mut y.c); - t1.copy(&t0); t1.neg(); - - z2.norm(); - z3.norm(); - self.b.norm(); - - self.c.copy(&z2); self.c.add(&t1); - z3.add(&t1); - t0.times_i(); - self.b.add(&t0); - - z3.times_i(); - self.a.copy(&z0); self.a.add(&z3); - self.norm(); - } - -/* Special case of multiplication arises from special form of ATE pairing line function */ - pub fn smul(&mut self,y: &mut FP12) { - let mut z0=FP4::new_copy(&self.a); - let mut z2=FP4::new_copy(&self.b); - let mut z3=FP4::new_copy(&self.b); - let mut t0=FP4::new(); - let mut t1=FP4::new_copy(&y.a); - - z0.mul(&mut y.a); - z2.pmul(&mut y.b.real()); - self.b.add(&self.a); - t1.padd(&y.b.real()); - - self.b.mul(&mut t1); - z3.add(&self.c); - z3.pmul(&mut y.b.real()); - - t0.copy(&z0); t0.neg(); - t1.copy(&z2); t1.neg(); - - self.b.add(&t0); - self.b.norm(); - - self.b.add(&t1); - z3.add(&t1); - z2.add(&t0); - - t0.copy(&self.a); t0.add(&self.c); - t0.mul(&mut y.a); - self.c.copy(&z2); self.c.add(&t0); - - z3.times_i(); - self.a.copy(&z0); self.a.add(&z3); - - self.norm(); - } - -/* self=1/self */ - pub fn inverse(&mut self) { - let mut f0=FP4::new_copy(&self.a); - let mut f1=FP4::new_copy(&self.b); - let mut f2=FP4::new_copy(&self.a); - let mut f3=FP4::new(); - - self.norm(); - f0.sqr(); - f1.mul(&mut self.c); - f1.times_i(); - f0.sub(&f1); - - f1.copy(&self.c); f1.sqr(); - f1.times_i(); - f2.mul(&mut self.b); - f1.sub(&f2); - - f2.copy(&self.b); f2.sqr(); - f3.copy(&self.a); f3.mul(&mut self.c); - f2.sub(&f3); - - f3.copy(&self.b); f3.mul(&mut f2); - f3.times_i(); - self.a.mul(&mut f0); - f3.add(&self.a); - self.c.mul(&mut f1); - self.c.times_i(); - - f3.add(&self.c); - f3.inverse(); - self.a.copy(&f0); self.a.mul(&mut f3); - self.b.copy(&f1); self.b.mul(&mut f3); - self.c.copy(&f2); self.c.mul(&mut f3); - } - -/* self=self^p using Frobenius */ - pub fn frob(&mut self,f: &mut FP2) { - let mut f2=FP2::new_copy(f); - let mut f3=FP2::new_copy(f); - - f2.sqr(); - f3.mul(&mut f2); - - self.a.frob(&mut f3); - self.b.frob(&mut f3); - self.c.frob(&mut f3); - - self.b.pmul(f); - self.c.pmul(&mut f2); - } - -/* trace function */ - pub fn trace(&mut self) -> FP4 { - let mut t=FP4::new(); - t.copy(&self.a); - t.imul(3); - t.reduce(); - return t; - } - -/* convert from byte array to FP12 */ - pub fn frombytes(w: &[u8]) -> FP12 { - let mut t:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - let mb=rom::MODBYTES as usize; - - for i in 0..mb {t[i]=w[i]} - let mut a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+mb]} - let mut b=BIG::frombytes(&t); - let mut c=FP2::new_bigs(&a,&b); - - for i in 0..mb {t[i]=w[i+2*mb]} - a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+3*mb]} - b=BIG::frombytes(&t); - let mut d=FP2::new_bigs(&a,&b); - - let e=FP4::new_fp2s(&c,&d); - - - for i in 0..mb {t[i]=w[i+4*mb]} - a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+5*mb]} - b=BIG::frombytes(&t); - c=FP2::new_bigs(&a,&b); - - for i in 0..mb {t[i]=w[i+6*mb]} - a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+7*mb]} - b=BIG::frombytes(&t); - d=FP2::new_bigs(&a,&b); - - let f=FP4::new_fp2s(&c,&d); - - - for i in 0..mb {t[i]=w[i+8*mb]} - a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+9*mb]} - b=BIG::frombytes(&t); - - c=FP2::new_bigs(&a,&b); - - for i in 0..mb {t[i]=w[i+10*mb]} - a=BIG::frombytes(&t); - for i in 0..mb {t[i]=w[i+11*mb]} - b=BIG::frombytes(&t); - d=FP2::new_bigs(&a,&b); - - let g=FP4::new_fp2s(&c,&d); - - return FP12::new_fp4s(&e,&f,&g); - } - -/* convert this to byte array */ - pub fn tobytes(&mut self,w: &mut [u8]) { - let mut t:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - let mb=rom::MODBYTES as usize; - - self.a.geta().geta().tobytes(&mut t); - for i in 0..mb {w[i]=t[i]} - self.a.geta().getb().tobytes(&mut t); - for i in 0..mb {w[i+mb]=t[i]} - self.a.getb().geta().tobytes(&mut t); - for i in 0..mb {w[i+2*mb]=t[i]} - self.a.getb().getb().tobytes(&mut t); - for i in 0..mb {w[i+3*mb]=t[i]} - - self.b.geta().geta().tobytes(&mut t); - for i in 0..mb {w[i+4*mb]=t[i]} - self.b.geta().getb().tobytes(&mut t); - for i in 0..mb {w[i+5*mb]=t[i]} - self.b.getb().geta().tobytes(&mut t); - for i in 0..mb {w[i+6*mb]=t[i]} - self.b.getb().getb().tobytes(&mut t); - for i in 0..mb {w[i+7*mb]=t[i]} - - self.c.geta().geta().tobytes(&mut t); - for i in 0..mb {w[i+8*mb]=t[i]} - self.c.geta().getb().tobytes(&mut t); - for i in 0..mb {w[i+9*mb]=t[i]} - self.c.getb().geta().tobytes(&mut t); - for i in 0..mb {w[i+10*mb]=t[i]} - self.c.getb().getb().tobytes(&mut t); - for i in 0..mb {w[i+11*mb]=t[i]} - } - -/* output to hex string */ - pub fn tostring(&mut self) -> String { - return format!("[{},{},{}]",self.a.tostring(),self.b.tostring(),self.c.tostring()); - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(12 * BIG_HEX_STRING_LEN); - ret.push_str(&format!("{} {} {}", self.a.to_hex(), self.b.to_hex(), self.c.to_hex())); - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP12 { - let mut ret:FP12 = FP12::new(); - ret.a = FP4::from_hex_iter(iter); - ret.b = FP4::from_hex_iter(iter); - ret.c = FP4::from_hex_iter(iter); - return ret; - } - - pub fn from_hex(val: String) -> FP12 { - let mut iter = val.split_whitespace(); - return FP12::from_hex_iter(&mut iter); - } - -/* self=self^e */ - pub fn pow(&mut self,e: &mut BIG) -> FP12 { - self.norm(); - e.norm(); - let mut w=FP12::new_copy(self); - let mut z=BIG::new_copy(&e); - let mut r=FP12::new_int(1); - loop { - let bt=z.parity(); - z.fshr(1); - if bt==1 {r.mul(&mut w)}; - if z.iszilch() {break} - w.usqr(); - } - r.reduce(); - return r; - } - -/* constant time powering by small integer of max length bts */ - pub fn pinpow(&mut self,e: i32,bts: i32) { - let mut r:[FP12;2]=[FP12::new_int(1),FP12::new_copy(self)]; - let mut t=FP12::new(); - - for i in (0..bts).rev() { - let b:usize=((e>>i)&1) as usize; - t.copy(&r[b]); - r[1-b].mul(&mut t); - r[b].usqr(); - } - self.copy(&r[0]); - } - -/* p=q0^u0.q1^u1.q2^u2.q3^u3 */ -/* Timing attack secure, but not cache attack secure */ - - pub fn pow4(q:&mut [FP12],u:&[BIG]) -> FP12 { - let mut a:[i8;4]=[0;4]; - let mut s:[FP12;2]=[FP12::new(),FP12::new()]; - let mut g:[FP12;8]=[FP12::new(),FP12::new(),FP12::new(),FP12::new(),FP12::new(),FP12::new(),FP12::new(),FP12::new()]; - - let mut c=FP12::new_int(1); - let mut p=FP12::new(); - const CT:usize=1+rom::NLEN*(rom::BASEBITS as usize); - let mut w:[i8;CT]=[0;CT]; - - 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])]; - - g[0].copy(&q[0]); s[0].copy(&q[1]); s[0].conj(); g[0].mul(&mut s[0]); - p.copy(&g[0]); - g[1].copy(&p); - g[2].copy(&p); - g[3].copy(&p); - g[4].copy(&q[0]); g[4].mul(&mut q[1]); - p.copy(&g[4]); - g[5].copy(&p); - g[6].copy(&p); - g[7].copy(&p); - - - s[1].copy(&q[2]); s[0].copy(&q[3]); s[0].conj(); p.copy(&s[0]); s[1].mul(&mut p); - p.copy(&s[1]); s[0].copy(&p); s[0].conj(); g[1].mul(&mut s[0]); - g[2].mul(&mut s[1]); - g[5].mul(&mut s[0]); - g[6].mul(&mut s[1]); - s[1].copy(&q[2]); s[1].mul(&mut q[3]); - p.copy(&s[1]); s[0].copy(&p); s[0].conj(); g[0].mul(&mut s[0]); - g[3].mul(&mut s[1]); - g[4].mul(&mut s[0]); - g[7].mul(&mut s[1]); - -/* if power is even add 1 to power, and add q to correction */ - - for i in 0..4 { - if t[i].parity()==0 { - t[i].inc(1); t[i].norm(); - c.mul(&mut q[i]); - } - mt.add(&t[i]); mt.norm(); - } - c.conj(); - let nb=1+mt.nbits(); - -/* convert exponent to signed 1-bit window */ - for j in 0..nb { - for i in 0..4 { - a[i]=(t[i].lastbits(2)-2) as i8; - t[i].dec(a[i] as isize); t[i].norm(); - t[i].fshr(1); - } - w[j]=8*a[0]+4*a[1]+2*a[2]+a[3]; - } - w[nb]=(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2)) as i8; - p.copy(&g[((w[nb] as usize)-1)/2]); - - for i in (0..nb).rev() { - let m=w[i]>>7; - let mut j=((w[i]^m)-m) as usize; /* j=abs(w[i]) */ - j=(j-1)/2; - s[0].copy(&g[j]); s[1].copy(&g[j]); s[1].conj(); - p.usqr(); - p.mul(&mut s[(m&1) as usize]); - } - p.mul(&mut c); /* apply correction */ - p.reduce(); - return p; - } - - -} -/* -fn main() -{ - let mut w=FP12::new(); -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/fp2.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/fp2.rs b/version22/rust/src/fp2.rs deleted file mode 100644 index 7ad62cc..0000000 --- a/version22/rust/src/fp2.rs +++ /dev/null @@ -1,366 +0,0 @@ -/* -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 std::fmt; -use std::str::SplitWhitespace; - -#[derive(Copy, Clone)] -pub struct FP2 { - a:FP, - b:FP, -} - -use rom::BIG_HEX_STRING_LEN; -//mod fp; -use fp::FP; -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rand; -//mod hash256; -//mod rom; -//use rom; - -impl fmt::Display for FP2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP2: [ {}, {} ]", self.a, self.b) - } -} - -impl fmt::Debug for FP2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP2: [ {}, {} ]", self.a, self.b) - } -} - -impl PartialEq for FP2 { - fn eq(&self, other: &FP2) -> bool { - return (self.a == other.a) && - (self.b == other.b); - } -} - -impl FP2 { - - pub fn new() -> FP2 { - FP2 { - a: FP::new(), - b: FP::new(), - } - } - - pub fn new_int(a: isize) -> FP2 { - let mut f=FP2::new(); - f.a.copy(&FP::new_int(a)); - f.b.zero(); - return f; - } - - pub fn new_copy(x: &FP2) -> FP2 { - let mut f=FP2::new(); - f.a.copy(&x.a); - f.b.copy(&x.b); - return f - } - - pub fn new_fps(c: &FP,d: &FP) -> FP2 { - let mut f=FP2::new(); - f.a.copy(c); - f.b.copy(d); - return f; - } - - pub fn new_bigs(c: &BIG,d: &BIG) -> FP2 { - let mut f=FP2::new(); - f.a.copy(&FP::new_big(c)); - f.b.copy(&FP::new_big(d)); - return f; - } - - pub fn new_fp(c: &FP) -> FP2 { - let mut f=FP2::new(); - f.a.copy(c); - f.b.zero(); - return f; - } - - pub fn new_big(c: &BIG) -> FP2 { - let mut f=FP2::new(); - f.a.copy(&FP::new_big(c)); - f.b.zero(); - return f; - } - -/* reduce components mod Modulus */ - pub fn reduce(&mut self) { - self.a.reduce(); - self.b.reduce(); - } - -/* normalise components of w */ - pub fn norm(&mut self) { - self.a.norm(); - self.b.norm(); - } - -/* test self=0 ? */ - pub fn iszilch(&mut self) -> bool { - self.reduce(); - return self.a.iszilch() && self.b.iszilch(); - } - - pub fn cmove(&mut self,g:&FP2,d: isize) { - self.a.cmove(&g.a,d); - self.b.cmove(&g.b,d); - } - -/* test self=1 ? */ - pub fn isunity(&mut self) -> bool { - let mut one=FP::new_int(1); - return self.a.equals(&mut one) && self.b.iszilch(); - } - -/* test self=x */ - pub fn equals(&mut self,x:&mut FP2) -> bool { - return self.a.equals(&mut x.a) && self.b.equals(&mut x.b); - } - -/* extract a */ - pub fn geta(&mut self) -> BIG { - return self.a.redc(); - } - -/* extract b */ - pub fn getb(&mut self) -> BIG { - return self.b.redc(); - } - -/* copy self=x */ - pub fn copy(&mut self,x :&FP2) { - self.a.copy(&x.a); - self.b.copy(&x.b); - } - -/* set self=0 */ - pub fn zero(&mut self) { - self.a.zero(); - self.b.zero(); - } - -/* set self=1 */ - pub fn one(&mut self) { - self.a.one(); - self.b.zero(); - } - -/* negate self mod Modulus */ - pub fn neg(&mut self) { - self.norm(); - let mut m=FP::new_copy(&self.a); - let mut t=FP::new(); - - m.add(&self.b); - m.neg(); - m.norm(); - t.copy(&m); t.add(&self.b); - self.b.copy(&m); - self.b.add(&self.a); - self.a.copy(&t); - } - -/* set to a-ib */ - pub fn conj(&mut self) { - self.b.neg(); - } - -/* self+=a */ - pub fn add(&mut self,x:&FP2) { - self.a.add(&x.a); - self.b.add(&x.b); - } - - pub fn dbl(&mut self) { - self.a.dbl(); - self.b.dbl(); - } - -/* self-=a */ - pub fn sub(&mut self,x:&FP2) { - let mut m=FP2::new_copy(x); - m.neg(); - self.add(&m); - } - -/* self*=s, where s is an FP */ - pub fn pmul(&mut self,s:&mut FP) { - self.a.mul(s); - self.b.mul(s); - } - -/* self*=i, where i is an int */ - pub fn imul(&mut self,c: isize) { - self.a.imul(c); - self.b.imul(c); - } - -/* self*=self */ - pub fn sqr(&mut self) { - self.norm(); - let mut w1=FP::new_copy(&self.a); - let mut w3=FP::new_copy(&self.a); - let mut mb=FP::new_copy(&self.b); - - w3.mul(&mut self.b); - w1.add(&self.b); - mb.neg(); - self.a.add(&mb); - self.a.mul(&mut w1); - self.b.copy(&w3); self.b.add(&w3); - - self.norm(); - } - -/* this*=y */ - pub fn mul(&mut self,y :&mut FP2) { - self.norm(); /* This is needed here as {a,b} is not normed before additions */ - - let mut w1=FP::new_copy(&self.a); - let mut w2=FP::new_copy(&self.b); - let mut w5=FP::new_copy(&self.a); - let mut mw=FP::new(); - - w1.mul(&mut y.a); // w1=a*y.a - this norms w1 and y.a, NOT a - w2.mul(&mut y.b); // w2=b*y.b - this norms w2 and y.b, NOT b - w5.add(&self.b); // w5=a+b - self.b.copy(&y.a); self.b.add(&y.b); // b=y.a+y.b - - self.b.mul(&mut w5); - mw.copy(&w1); mw.add(&w2); mw.neg(); - - self.b.add(&mw); mw.add(&w1); - self.a.copy(&w1); self.a.add(&mw); - - self.norm(); - } - -/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */ -/* returns true if this is QR */ - pub fn sqrt(&mut self) -> bool { - if self.iszilch() {return true} - let mut w1=FP::new_copy(&self.b); - let mut w2=FP::new_copy(&self.a); - w1.sqr(); w2.sqr(); w1.add(&w2); - if w1.jacobi()!=1 { self.zero(); return false } - w2.copy(&w1.sqrt()); w1.copy(&w2); - w2.copy(&self.a); w2.add(&w1); w2.div2(); - if w2.jacobi()!=1 { - w2.copy(&self.a); w2.sub(&w1); w2.div2(); - if w2.jacobi()!=1 { self.zero(); return false } - } - w1.copy(&w2.sqrt()); - self.a.copy(&w1); - w1.dbl(); - w1.inverse(); - self.b.mul(&mut w1); - return true; - } - -/* output to hex string */ - pub fn tostring(&mut self) -> String { - return format!("[{},{}]",self.a.tostring(),self.b.tostring()); - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(2 * BIG_HEX_STRING_LEN); - ret.push_str(&format!("{} {}", self.a.to_hex(), self.b.to_hex())); - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP2 { - let mut ret:FP2 = FP2::new(); - ret.a = FP::from_hex_iter(iter); - ret.b = FP::from_hex_iter(iter); - return ret; - } - - pub fn from_hex(val: String) -> FP2 { - let mut iter = val.split_whitespace(); - return FP2::from_hex_iter(&mut iter); - } - -/* self=1/self */ - pub fn inverse(&mut self) { - self.norm(); - let mut w1=FP::new_copy(&self.a); - let mut w2=FP::new_copy(&self.b); - - w1.sqr(); - w2.sqr(); - w1.add(&w2); - w1.inverse(); - self.a.mul(&mut w1); - w1.neg(); - self.b.mul(&mut w1); - } - -/* self/=2 */ - pub fn div2(&mut self) { - self.a.div2(); - self.b.div2(); - } - -/* self*=sqrt(-1) */ - pub fn times_i(&mut self) { - // a.norm(); - let z=FP::new_copy(&self.a); - self.a.copy(&self.b); self.a.neg(); - self.b.copy(&z); - } - -/* w*=(1+sqrt(-1)) */ -/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */ - pub fn mul_ip(&mut self) { - self.norm(); - let t=FP2::new_copy(self); - let z=FP::new_copy(&self.a); - self.a.copy(&self.b); - self.a.neg(); - self.b.copy(&z); - self.add(&t); - self.norm(); - } - -/* w/=(1+sqrt(-1)) */ - pub fn div_ip(&mut self) { - let mut t=FP2::new(); - self.norm(); - t.a.copy(&self.a); t.a.add(&self.b); - t.b.copy(&self.b); t.b.sub(&self.a); - self.copy(&t); - self.div2(); - } - -} -/* -fn main() -{ - let mut x=FP2::new(); -} -*/ http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/fp4.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/fp4.rs b/version22/rust/src/fp4.rs deleted file mode 100644 index ea2806d..0000000 --- a/version22/rust/src/fp4.rs +++ /dev/null @@ -1,563 +0,0 @@ -/* -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 std::fmt; -use std::str::SplitWhitespace; - -#[derive(Copy, Clone)] -pub struct FP4 { - a:FP2, - b:FP2, -} - -use rom::BIG_HEX_STRING_LEN; -//mod fp; -//use fp::FP; -//mod fp2; -use fp2::FP2; -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rand; -//mod hash256; -//mod rom; -//use rom; - -impl PartialEq for FP4 { - fn eq(&self, other: &FP4) -> bool { - return (self.a == other.a) && - (self.b == other.b); - } -} - -impl fmt::Display for FP4 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP4: [ {}, {} ]", self.a, self.b) - } -} - -impl fmt::Debug for FP4 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "FP4: [ {}, {} ]", self.a, self.b) - } -} - -impl FP4 { - - pub fn new() -> FP4 { - FP4 { - a: FP2::new(), - b: FP2::new(), - } - } - - pub fn new_int(a: isize) -> FP4 { - let mut f=FP4::new(); - f.a.copy(&FP2::new_int(a)); - f.b.zero(); - return f; - } - - pub fn new_copy(x: &FP4) -> FP4 { - let mut f=FP4::new(); - f.a.copy(&x.a); - f.b.copy(&x.b); - return f; - } - - pub fn new_fp2s(c: &FP2,d: &FP2) -> FP4 { - let mut f=FP4::new(); - f.a.copy(c); - f.b.copy(d); - return f; - } - - pub fn new_fp2(c: &FP2) -> FP4 { - let mut f=FP4::new(); - f.a.copy(c); - f.b.zero(); - return f; - } - -/* reduce components mod Modulus */ - pub fn reduce(&mut self) { - self.a.reduce(); - self.b.reduce(); - } - -/* normalise components of w */ - pub fn norm(&mut self) { - self.a.norm(); - self.b.norm(); - } - -/* test self=0 ? */ - pub fn iszilch(&mut self) -> bool { - self.reduce(); - return self.a.iszilch() && self.b.iszilch(); - } - -/* test self=1 ? */ - pub fn isunity(&mut self) -> bool { - let mut one=FP2::new_int(1); - return self.a.equals(&mut one) && self.b.iszilch(); - } - -/* test is w real? That is in a+ib test b is zero */ - pub fn isreal(&mut self) -> bool { - return self.b.iszilch(); - } -/* extract real part a */ - pub fn real(&mut self) -> FP2 { - let f=FP2::new_copy(&self.a); - return f; - } - - pub fn geta(&mut self) -> FP2 { - let f=FP2::new_copy(&self.a); - return f; - } -/* extract imaginary part b */ - pub fn getb(&mut self) -> FP2 { - let f=FP2::new_copy(&self.b); - return f; - } - -/* test self=x */ - pub fn equals(&mut self,x:&mut FP4) -> bool { - return self.a.equals(&mut x.a) && self.b.equals(&mut x.b); - } -/* copy self=x */ - pub fn copy(&mut self,x :&FP4) { - self.a.copy(&x.a); - self.b.copy(&x.b); - } - -/* set self=0 */ - pub fn zero(&mut self) { - self.a.zero(); - self.b.zero(); - } - -/* set self=1 */ - pub fn one(&mut self) { - self.a.one(); - self.b.zero(); - } - -/* negate self mod Modulus */ - pub fn neg(&mut self) { - self.norm(); - let mut m=FP2::new_copy(&self.a); - let mut t=FP2::new(); - - m.add(&self.b); - m.neg(); - m.norm(); - t.copy(&m); t.add(&self.b); - self.b.copy(&m); - self.b.add(&self.a); - self.a.copy(&t); - } - -/* set to a-ib */ - pub fn conj(&mut self) { - self.b.neg(); - self.b.norm(); - } - -/* self=-conjugate(self) */ - pub fn nconj(&mut self) { - self.a.neg(); self.a.norm(); - } - -/* self+=a */ - pub fn add(&mut self,x:&FP4) { - self.a.add(&x.a); - self.b.add(&x.b); - } - - pub fn padd(&mut self,x:&FP2) { - self.a.add(x); - } - - pub fn dbl(&mut self) { - self.a.dbl(); - self.b.dbl(); - } - -/* self-=a */ - pub fn sub(&mut self,x:&FP4) { - let mut m=FP4::new_copy(x); - m.neg(); - self.add(&m); - } - -/* self*=s, where s is an FP */ - pub fn pmul(&mut self,s:&mut FP2) { - self.a.mul(s); - self.b.mul(s); - } - -/* self*=i, where i is an int */ - pub fn imul(&mut self,c: isize) { - self.a.imul(c); - self.b.imul(c); - } - -/* self*=self */ - pub fn sqr(&mut self) { - self.norm(); - - let mut t1=FP2::new_copy(&self.a); - let mut t2=FP2::new_copy(&self.b); - let mut t3=FP2::new_copy(&self.a); - - - t3.mul(&mut self.b); - t1.add(&self.b); - t2.mul_ip(); - - t2.add(&mut self.a); - self.a.copy(&t1); - - self.a.mul(&mut t2); - - t2.copy(&t3); - t2.mul_ip(); - t2.add(&mut t3); - t2.neg(); - self.a.add(&t2); - - t3.dbl(); - self.b.copy(&t3); - - self.norm(); - } - -/* self*=y */ - pub fn mul(&mut self,y :&mut FP4) { - self.norm(); - - let mut t1=FP2::new_copy(&self.a); - let mut t2=FP2::new_copy(&self.b); - let mut t3=FP2::new(); - let mut t4=FP2::new_copy(&self.b); - - t1.mul(&mut y.a); - t2.mul(&mut y.b); - t3.copy(&y.b); - t3.add(&y.a); - t4.add(&self.a); - - t4.mul(&mut t3); - t4.sub(&t1); - t4.norm(); - - self.b.copy(&t4); - self.b.sub(&t2); - t2.mul_ip(); - self.a.copy(&t2); - self.a.add(&t1); - - self.norm(); - } - -/* output to hex string */ - pub fn tostring(&mut self) -> String { - return format!("[{},{}]",self.a.tostring(),self.b.tostring()); - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(4 * BIG_HEX_STRING_LEN); - ret.push_str(&format!("{} {}", self.a.to_hex(), self.b.to_hex())); - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP4 { - let mut ret:FP4 = FP4::new(); - ret.a = FP2::from_hex_iter(iter); - ret.b = FP2::from_hex_iter(iter); - return ret; - } - - pub fn from_hex(val: String) -> FP4 { - let mut iter = val.split_whitespace(); - return FP4::from_hex_iter(&mut iter); - } - -/* self=1/self */ - pub fn inverse(&mut self) { - self.norm(); - - let mut t1=FP2::new_copy(&self.a); - let mut t2=FP2::new_copy(&self.b); - - t1.sqr(); - t2.sqr(); - t2.mul_ip(); - t1.sub(&t2); - t1.inverse(); - self.a.mul(&mut t1); - t1.neg(); - self.b.mul(&mut t1); - } - -/* self*=i where i = sqrt(-1+sqrt(-1)) */ - pub fn times_i(&mut self) { - self.norm(); - let mut s=FP2::new_copy(&self.b); - let mut t=FP2::new_copy(&self.b); - s.times_i(); - t.add(&s); - t.norm(); - self.b.copy(&self.a); - self.a.copy(&t); - } - -/* self=self^p using Frobenius */ - pub fn frob(&mut self,f: &mut FP2) { - self.a.conj(); - self.b.conj(); - self.b.mul(f); - } - -/* self=self^e */ - pub fn pow(&mut self,e: &mut BIG) -> FP4 { - self.norm(); - e.norm(); - let mut w=FP4::new_copy(self); - let mut z=BIG::new_copy(&e); - let mut r=FP4::new_int(1); - loop { - let bt=z.parity(); - z.fshr(1); - if bt==1 {r.mul(&mut w)}; - if z.iszilch() {break} - w.sqr(); - } - r.reduce(); - return r; - } - -/* XTR xtr_a function */ - pub fn xtr_a(&mut self,w:&FP4,y:&FP4,z:&FP4) { - let mut r=FP4::new_copy(w); - let mut t=FP4::new_copy(w); - r.sub(y); - r.pmul(&mut self.a); - t.add(y); - t.pmul(&mut self.b); - t.times_i(); - - self.copy(&r); - self.add(&t); - self.add(z); - - self.norm(); - } - -/* XTR xtr_d function */ - pub fn xtr_d(&mut self) { - let mut w=FP4::new_copy(self); - self.sqr(); w.conj(); - w.dbl(); - self.sub(&w); - self.reduce(); - } - -/* r=x^n using XTR method on traces of FP12s */ - pub fn xtr_pow(&mut self,n: &mut BIG) -> FP4 { - let mut a=FP4::new_int(3); - let mut b=FP4::new_copy(self); - let mut c=FP4::new_copy(&b); - c.xtr_d(); - let mut t=FP4::new(); - let mut r=FP4::new(); - - n.norm(); - let par=n.parity(); - let mut v=BIG::new_copy(n); v.fshr(1); - if par==0 {v.dec(1); v.norm(); } - - let nb=v.nbits(); - for i in (0..nb).rev() { - if v.bit(i)!=1 { - t.copy(&b); - self.conj(); - c.conj(); - b.xtr_a(&a,self,&c); - self.conj(); - c.copy(&t); - c.xtr_d(); - a.xtr_d(); - } else { - t.copy(&a); t.conj(); - a.copy(&b); - a.xtr_d(); - b.xtr_a(&c,self,&t); - c.xtr_d(); - } - } - if par==0 { - r.copy(&c) - } else {r.copy(&b)} - r.reduce(); - return r; - } - -/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */ - pub fn xtr_pow2(&mut self,ck: &FP4,ckml: &FP4,ckm2l: &FP4,a: &mut BIG,b: &mut BIG) -> FP4 { - a.norm(); b.norm(); - let mut e=BIG::new_copy(a); - let mut d=BIG::new_copy(b); - let mut w=BIG::new(); - - let mut cu=FP4::new_copy(ck); // can probably be passed in w/o copying - let mut cv=FP4::new_copy(self); - let mut cumv=FP4::new_copy(ckml); - let mut cum2v=FP4::new_copy(ckm2l); - let mut r=FP4::new(); - let mut t=FP4::new(); - - let mut f2:usize=0; - while d.parity()==0 && e.parity()==0 { - d.fshr(1); - e.fshr(1); - f2+=1; - } - - while BIG::comp(&d,&e)!=0 { - if BIG::comp(&d,&e)>0 { - w.copy(&e); w.imul(4); w.norm(); - if BIG::comp(&d,&w)<=0 { - w.copy(&d); d.copy(&e); - e.rsub(&w); e.norm(); - - t.copy(&cv); - t.xtr_a(&cu,&cumv,&cum2v); - cum2v.copy(&cumv); - cum2v.conj(); - cumv.copy(&cv); - cv.copy(&cu); - cu.copy(&t); - } else { - if d.parity()==0 { - d.fshr(1); - r.copy(&cum2v); r.conj(); - t.copy(&cumv); - t.xtr_a(&cu,&cv,&r); - cum2v.copy(&cumv); - cum2v.xtr_d(); - cumv.copy(&t); - cu.xtr_d(); - } else { - if e.parity()==1 { - d.sub(&e); d.norm(); - d.fshr(1); - t.copy(&cv); - t.xtr_a(&cu,&cumv,&cum2v); - cu.xtr_d(); - cum2v.copy(&cv); - cum2v.xtr_d(); - cum2v.conj(); - cv.copy(&t); - } else { - w.copy(&d); - d.copy(&e); d.fshr(1); - e.copy(&w); - t.copy(&cumv); - t.xtr_d(); - cumv.copy(&cum2v); cumv.conj(); - cum2v.copy(&t); cum2v.conj(); - t.copy(&cv); - t.xtr_d(); - cv.copy(&cu); - cu.copy(&t); - } - } - } - } - if BIG::comp(&d,&e)<0 { - w.copy(&d); w.imul(4); w.norm(); - if BIG::comp(&e,&w)<=0 { - e.sub(&d); e.norm(); - t.copy(&cv); - t.xtr_a(&cu,&cumv,&cum2v); - cum2v.copy(&cumv); - cumv.copy(&cu); - cu.copy(&t); - } else { - if e.parity()==0 { - w.copy(&d); - d.copy(&e); d.fshr(1); - e.copy(&w); - t.copy(&cumv); - t.xtr_d(); - cumv.copy(&cum2v); cumv.conj(); - cum2v.copy(&t); cum2v.conj(); - t.copy(&cv); - t.xtr_d(); - cv.copy(&cu); - cu.copy(&t); - } else { - if d.parity()==1 { - w.copy(&e); - e.copy(&d); - w.sub(&d); w.norm(); - d.copy(&w); d.fshr(1); - t.copy(&cv); - t.xtr_a(&cu,&cumv,&cum2v); - cumv.conj(); - cum2v.copy(&cu); - cum2v.xtr_d(); - cum2v.conj(); - cu.copy(&cv); - cu.xtr_d(); - cv.copy(&t); - } else { - d.fshr(1); - r.copy(&cum2v); r.conj(); - t.copy(&cumv); - t.xtr_a(&cu,&cv,&r); - cum2v.copy(&cumv); - cum2v.xtr_d(); - cumv.copy(&t); - cu.xtr_d(); - } - } - } - } - } - r.copy(&cv); - r.xtr_a(&cu,&cumv,&cum2v); - for _ in 0..f2 {r.xtr_d()} - r=r.xtr_pow(&mut d); - return r; - } - - -} -/* -fn main() -{ - let mut w=FP4::new(); -} -*/
