http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/big.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/big.rs b/version22/rust/src/big.rs deleted file mode 100644 index 5e3fb1d..0000000 --- a/version22/rust/src/big.rs +++ /dev/null @@ -1,1227 +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::cmp::Ordering; -use std::str::SplitWhitespace; - -use rom; -use rom::{Chunk, NLEN}; - -#[cfg(target_pointer_width = "32")] -use rom::DChunk; - -#[derive(Copy, Clone)] -pub struct BIG { - pub w: [Chunk; rom::NLEN] -} - -//mod dbig; - -use dbig::DBIG; -use rand::RAND; - -impl fmt::Display for BIG { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut big = self.clone(); - write!(f, "BIG: [ {} ]", big.tostring()) - } -} - -impl fmt::Debug for BIG { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut big = self.clone(); - write!(f, "BIG: [ {} ]", big.tostring()) - } -} - -impl PartialEq for BIG { - fn eq(&self, other: &BIG) -> bool { - return self.w == other.w; - } -} - -impl Ord for BIG { - fn cmp(&self, other: &BIG) -> Ordering { - let r = BIG::comp(self, other); - if r > 0 { - return Ordering::Greater; - } - if r < 0 { - return Ordering::Less; - } - return Ordering::Equal; - } -} - -impl Eq for BIG { } - -impl PartialOrd for BIG { - fn partial_cmp(&self, other: &BIG) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl BIG { - - pub fn new() -> BIG { - BIG { - w: [0; rom::NLEN] - } - } - - pub fn new_int(x:isize) -> BIG { - let mut s= BIG::new(); - s.w[0]=x as Chunk; - return s; - } - - pub fn new_ints(a:&[Chunk]) -> BIG { - let mut s= BIG::new(); - for i in 0..rom::NLEN {s.w[i]=a[i]} - return s; - } - - pub fn new_copy(y:&BIG) -> BIG { - let mut s= BIG::new(); - for i in 0..rom::NLEN {s.w[i]=y.w[i]} - return s; - } - - pub fn new_big(y:&BIG) -> BIG { - let mut s= BIG::new(); - for i in 0..rom::NLEN {s.w[i]=y.w[i]} - return s; - } - - pub fn new_dcopy(y:&DBIG) -> BIG { - let mut s= BIG::new(); - for i in 0..rom::NLEN {s.w[i]=y.w[i]} - return s; - } - - pub fn get(&self,i:usize) -> Chunk { - return self.w[i]; - } - - pub fn set(&mut self,i:usize,x:Chunk) { - self.w[i]=x; - } - - pub fn xortop(&mut self,x:Chunk) { - self.w[rom::NLEN-1]^=x; - } - - pub fn ortop(&mut self,x:Chunk) { - self.w[rom::NLEN-1]|=x; - } - -/* test for zero */ - pub fn iszilch(&self) -> bool { - for i in 0 ..rom::NLEN { - if self.w[i]!=0 {return false} - } - return true; - } - -/* set to zero */ - pub fn zero(&mut self) { - for i in 0 ..rom::NLEN { - self.w[i]=0 - } - } - -/* Test for equal to one */ - pub fn isunity(&self) -> bool { - for i in 0 ..rom::NLEN { - if self.w[i]!=0 {return false} - } - if self.w[0]!=1 {return false} - return true; - } - -/* set to one */ - pub fn one(&mut self) { - self.w[0]=1; - for i in 1 ..rom::NLEN { - self.w[i]=0; - } - } - -/* Copy from another BIG */ - pub fn copy(&mut self,x: &BIG) { - for i in 0 ..rom::NLEN { - self.w[i]=x.w[i] - } - } - - pub fn dcopy(&mut self,x: &DBIG) - { - for i in 0 ..rom::NLEN {self.w[i] = x.w[i]} - } - -/* calculate Field Excess */ - pub fn excess(a:&BIG) -> Chunk { - return (a.w[rom::NLEN-1]&rom::OMASK)>>(rom::MODBITS%rom::BASEBITS) - } - - pub fn ff_excess(a:&BIG) -> Chunk { - return (a.w[rom::NLEN-1]&rom::P_OMASK)>>(rom::P_MB) - } - -#[cfg(target_pointer_width = "32")] - pub fn pexceed(a: &BIG,b: &BIG) -> bool { - let ea=BIG::excess(a); - let eb=BIG::excess(b); - if ((ea+1) as DChunk)*((eb+1) as DChunk) > rom::FEXCESS as DChunk {return true} - return false - } - -#[cfg(target_pointer_width = "32")] - pub fn sexceed(a: &BIG) -> bool { - let ea=BIG::excess(a); - if ((ea+1) as DChunk)*((ea+1) as DChunk) > rom::FEXCESS as DChunk {return true} - return false - } - -#[cfg(target_pointer_width = "32")] - pub fn ff_pexceed(a: &BIG,b: &BIG) -> bool { - let ea=BIG::ff_excess(a); - let eb=BIG::ff_excess(b); - if ((ea+1) as DChunk)*((eb+1) as DChunk) > rom::P_FEXCESS as DChunk {return true} - return false; - } - -#[cfg(target_pointer_width = "32")] - pub fn ff_sexceed(a: &BIG) -> bool { - let ea=BIG::ff_excess(a); - if ((ea+1) as DChunk)*((ea+1) as DChunk) > rom::P_FEXCESS as DChunk {return true} - return false; - } - -/* Get top and bottom half of =x*y+c+r */ -#[cfg(target_pointer_width = "32")] - pub fn muladd(a: Chunk,b: Chunk,c: Chunk,r: Chunk) -> (Chunk,Chunk) { - let prod:DChunk = (a as DChunk)*(b as DChunk)+(c as DChunk)+(r as DChunk); - let bot=(prod&(rom::BMASK as DChunk)) as Chunk; - let top=(prod>>rom::BASEBITS) as Chunk; - return (top,bot); - } - -#[cfg(target_pointer_width = "64")] - pub fn pexceed(a: &BIG,b: &BIG) -> bool { - let ea=BIG::excess(a); - let eb=BIG::excess(b); - if (ea+1) > rom::FEXCESS/(eb+1) {return true} - return false - } - -#[cfg(target_pointer_width = "64")] - pub fn sexceed(a: &BIG) -> bool { - let ea=BIG::excess(a); - if (ea+1) > rom::FEXCESS/(ea+1) {return true} - return false - } - -#[cfg(target_pointer_width = "64")] - pub fn ff_pexceed(a: &BIG,b: &BIG) -> bool { - let ea=BIG::ff_excess(a); - let eb=BIG::ff_excess(b); - if (ea+1) > rom::P_FEXCESS/(eb+1) {return true} - return false; - } - -#[cfg(target_pointer_width = "64")] - pub fn ff_sexceed(a: &BIG) -> bool { - let ea=BIG::ff_excess(a); - if (ea+1) > rom::P_FEXCESS/(ea+1) {return true} - return false; - } - -#[cfg(target_pointer_width = "64")] - pub fn muladd(a: Chunk,b: Chunk,c: Chunk,r: Chunk) -> (Chunk,Chunk) { - let x0=a&rom::HMASK; - let x1=a>>rom::HBITS; - let y0=b&rom::HMASK; - let y1=b>>rom::HBITS; - let mut bot=x0*y0; - let mut top=x1*y1; - let mid=x0*y1+x1*y0; - let u0=mid&rom::HMASK; - let u1=mid>>rom::HBITS; - bot+= u0 <<rom::HBITS; - bot+=c; bot+=r; - top+=u1; - let carry=bot>>rom::BASEBITS; - bot&=rom::BMASK; - top+=carry; - return (top,bot); - } - -/* -alise BIG - force all digits < 2^rom::BASEBITS */ - pub fn norm(&mut self) -> Chunk - { - let mut carry=0 as Chunk; - for i in 0 ..rom::NLEN-1 { - let d=self.w[i]+carry; - self.w[i]=d&rom::BMASK; - carry=d>>rom::BASEBITS; - } - self.w[rom::NLEN-1]+=carry; - return (self.w[rom::NLEN-1]>>((8*rom::MODBYTES)%rom::BASEBITS)) as Chunk; - } - -/* Conditional swap of two bigs depending on d using XOR - no branches */ - pub fn cswap(&mut self,b: &mut BIG,d: isize) { - let mut c= d as Chunk; - c=!(c-1); - for i in 0 ..rom::NLEN { - let t=c&(self.w[i]^b.w[i]); - self.w[i]^=t; - b.w[i]^=t; - } - } - - pub fn cmove(&mut self,g:&BIG,d: isize) { - let b= -d as Chunk; - for i in 0 ..rom::NLEN { - self.w[i]^=(self.w[i]^g.w[i])&b; - } - } - -/* Shift right by less than a word */ - pub fn fshr(&mut self, k: usize) -> isize { - let n = k; - let w=self.w[0]&((1<<n)-1); /* shifted out part */ - for i in 0 ..rom::NLEN-1 { - self.w[i]=(self.w[i]>>k)|((self.w[i+1]<<(rom::BASEBITS-n))&rom::BMASK); - } - self.w[rom::NLEN-1]=self.w[rom::NLEN-1]>>k; - return w as isize; - } - - /* general shift right */ - pub fn shr(&mut self,k:usize) { - let n=k%rom::BASEBITS; - let m=k/rom::BASEBITS; - for i in 0 ..rom::NLEN-m-1 { - self.w[i]=(self.w[m+i]>>n)|((self.w[m+i+1]<<(rom::BASEBITS-n))&rom::BMASK) - } - self.w[rom::NLEN-m-1]=self.w[rom::NLEN-1]>>n; - for i in rom::NLEN-m ..rom::NLEN - {self.w[i]=0} - } - -/* Shift right by less than a word */ - pub fn fshl(&mut self,k:usize) -> isize { - let n=k; - self.w[rom::NLEN-1]=((self.w[rom::NLEN-1]<<n))|(self.w[rom::NLEN-2]>>(rom::BASEBITS-n)); - for i in (1 ..rom::NLEN-1).rev() { - self.w[i]=((self.w[i]<<k)&rom::BMASK)|(self.w[i-1]>>(rom::BASEBITS-n)); - } - self.w[0]=(self.w[0]<<n)&rom::BMASK; - return (self.w[rom::NLEN-1]>>((8*rom::MODBYTES)%rom::BASEBITS)) as isize /* return excess - only used in ff.c */ - } - -/* general shift left */ - pub fn shl(&mut self,k: usize) { - let n=k%rom::BASEBITS; - let m=k/rom::BASEBITS; - - self.w[rom::NLEN-1]=self.w[rom::NLEN-1-m]<<n; - if rom::NLEN>=m+2 {self.w[rom::NLEN-1]|=self.w[rom::NLEN-m-2]>>(rom::BASEBITS-n)} - for i in (m+1 ..rom::NLEN-1).rev() { - self.w[i]=((self.w[i-m]<<n)&rom::BMASK)|(self.w[i-m-1]>>(rom::BASEBITS-n)); - } - self.w[m]=(self.w[0]<<n)&rom::BMASK; - for i in 0 ..m {self.w[i]=0} - } - -/* return number of bits */ - pub fn nbits(&mut self) -> usize { - let mut k=rom::NLEN-1; - self.norm(); - while (k as isize)>=0 && self.w[k]==0 {k=k.wrapping_sub(1)} - if (k as isize) <0 {return 0} - let mut bts=rom::BASEBITS*k; - let mut c=self.w[k]; - while c!=0 {c/=2; bts+=1;} - return bts; - } - -/* Convert to Hex String */ - pub fn tostring(&mut self) -> String { - let mut s = String::new(); - let mut len=self.nbits(); - - if len%4==0 { - len/=4; - } else { - len/=4; - len+=1; - } - let mb=(rom::MODBYTES*2) as usize; - if len<mb {len=mb} - - for i in (0 ..len).rev() { - let mut b=BIG::new_copy(&self); - b.shr(i*4); - s=s + &format!("{:X}", b.w[0]&15); - } - return s; - } - - pub fn add(&mut self,r:&BIG) { - for i in 0 ..rom::NLEN { - self.w[i]+=r.w[i] - } - } - - pub fn dbl(&mut self) { - for i in 0 ..rom::NLEN { - self.w[i]+=self.w[i] - } - } - -/* return this+x */ - pub fn plus(&self,x: &BIG) -> BIG { - let mut s=BIG::new(); - for i in 0 ..rom::NLEN { - s.w[i]=self.w[i]+x.w[i]; - } - return s; - } - - pub fn inc(&mut self,x:isize) { - self.norm(); - self.w[0]+=x as Chunk; - } - -// pub fn incl(&mut self,x:Chunk) { -// self.norm(); -// self.w[0]+=x; -// } - -/* return self-x */ - pub fn minus(&self,x:& BIG) -> BIG { - let mut d=BIG::new(); - for i in 0 ..rom::NLEN { - d.w[i]=self.w[i]-x.w[i]; - } - return d; - } - -/* self-=x */ - pub fn sub(&mut self,x:&BIG) { - for i in 0 ..rom::NLEN { - self.w[i]-=x.w[i]; - } - } - -/* reverse subtract this=x-this */ - pub fn rsub(&mut self,x:&BIG) { - for i in 0 ..rom::NLEN { - self.w[i]=x.w[i]-self.w[i] - } - } - -/* self-=x, where x is int */ - pub fn dec(&mut self,x:isize) { - self.norm(); - self.w[0]-= x as Chunk; - } - -/* self*=x, where x is small int<NEXCESS */ - pub fn imul(&mut self,c: isize) { - for i in 0 ..rom::NLEN { - self.w[i]*=c as Chunk; - } - } - -/* convert this BIG to byte array */ - pub fn tobytearray(&mut self,b: &mut [u8],n:usize) { - self.norm(); - let mut c=BIG::new_copy(self); - - for i in (0 ..(rom::MODBYTES as usize)).rev() { - b[i+n]=(c.w[0]&0xff) as u8; - c.fshr(8); - } - } - -/* convert from byte array to BIG */ - pub fn frombytearray(b: &[u8],n:usize) -> BIG { - let mut m=BIG::new(); - for i in 0 ..(rom::MODBYTES as usize) { - m.fshl(8); m.w[0]+=(b[i+n]&0xff) as Chunk; - } - return m; - } - - pub fn tobytes(&mut self,b: &mut [u8]) { - self.tobytearray(b,0) - } - - pub fn frombytes(b: &[u8]) -> BIG { - return BIG::frombytearray(b,0) - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(NLEN * 16 + NLEN - 1); - - for i in 0..NLEN { - if i == NLEN-1 { - ret.push_str(&format!("{:X}", self.w[i])); - } else { - ret.push_str(&format!("{:X} ", self.w[i])); - } - } - return ret; - } - - pub fn from_hex_iter(iter: &mut SplitWhitespace) -> BIG { - let mut ret:BIG = BIG::new(); - for i in 0..NLEN { - let v = iter.next(); - match v { - Some(x) => { - ret.w[i] = u64::from_str_radix(x, 16).unwrap() as Chunk; - }, - None => { - break; - } - } - } - return ret; - } - - pub fn from_hex(val: String) -> BIG { - let mut iter = val.split_whitespace(); - return BIG::from_hex_iter(&mut iter); - } - -/* self*=x, where x is >NEXCESS */ - pub fn pmul(&mut self,c: isize) -> Chunk { - let mut carry=0 as Chunk; - self.norm(); - for i in 0 ..rom::NLEN { - let ak=self.w[i]; - let tuple=BIG::muladd(ak,c as Chunk,carry,0 as Chunk); - carry=tuple.0; self.w[i]=tuple.1; - } - return carry; - } - -/* self*=c and catch overflow in DBIG */ - pub fn pxmul(&mut self,c: isize) -> DBIG - { - let mut m=DBIG::new(); - let mut carry=0 as Chunk; - for j in 0 ..rom::NLEN { - let tuple=BIG::muladd(self.w[j],c as Chunk,carry,m.w[j]); - carry=tuple.0; m.w[j]=tuple.1; - } - m.w[rom::NLEN]=carry; - return m; - } - -/* divide by 3 */ - pub fn div3(&mut self) -> Chunk - { - let mut carry=0 as Chunk; - self.norm(); - let base=1<<rom::BASEBITS; - for i in (0 ..rom::NLEN).rev() { - let ak=carry*base+self.w[i]; - self.w[i]=ak/3; - carry=ak%3; - } - return carry; - } - -/* return a*b where result fits in a BIG */ - pub fn smul(a: &BIG,b: &BIG) -> BIG { - let mut c=BIG::new(); - for i in 0 ..rom::NLEN { - let mut carry=0 as Chunk; - for j in 0 ..rom::NLEN { - if i+j<rom::NLEN { - let tuple=BIG::muladd(a.w[i],b.w[j],carry,c.w[i+j]); - carry=tuple.0; c.w[i+j]=tuple.1; - } - } - } - return c; - } - -/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ - pub fn comp(a: &BIG,b: &BIG) -> isize { - for i in (0 ..rom::NLEN).rev() { - if a.w[i]==b.w[i] {continue} - if a.w[i]>b.w[i] {return 1} - else {return -1} - } - return 0; - } - -/* set x = x mod 2^m */ - pub fn mod2m(&mut self,m: usize) - { - let wd=m/rom::BASEBITS; - let bt=m%rom::BASEBITS; - let msk=(1<<bt)-1; - self.w[wd]&=msk; - for i in wd+1 ..rom::NLEN {self.w[i]=0} - } - -/* Arazi and Qi inversion mod 256 */ - pub fn invmod256(a: isize) -> isize { - let mut t1:isize=0; - let mut c=(a>>1)&1; - t1+=c; - t1&=1; - t1=2-t1; - t1<<=1; - let mut u=t1+1; - - // i=2 - let mut b=a&3; - t1=u*b; t1>>=2; - c=(a>>2)&3; - let mut t2=(u*c)&3; - t1+=t2; - t1*=u; t1&=3; - t1=4-t1; - t1<<=2; - u+=t1; - - // i=4 - b=a&15; - t1=u*b; t1>>=4; - c=(a>>4)&15; - t2=(u*c)&15; - t1+=t2; - t1*=u; t1&=15; - t1=16-t1; - t1<<=4; - u+=t1; - - return u; - } - -/* return parity */ - pub fn parity(&self) -> isize { - return (self.w[0]%2) as isize; - } - -/* return n-th bit */ - pub fn bit(&self,n: usize) -> isize { - if (self.w[n/(rom::BASEBITS as usize)]&(1<<(n%rom::BASEBITS)))>0 {return 1;} - else {return 0;} - } - -/* return n last bits */ - pub fn lastbits(&mut self,n: usize) -> isize - { - let msk = ((1<<n)-1) as Chunk; - self.norm(); - return (self.w[0]&msk) as isize; - } - -/* a=1/a mod 2^256. This is very fast! */ - pub fn invmod2m(&mut self) { - let mut u=BIG::new(); - let mut b=BIG::new(); - let mut c=BIG::new(); - - u.inc(BIG::invmod256(self.lastbits(8))); - - let mut i=8; - while i<rom::BIGBITS { - b.copy(self); - b.mod2m(i); - let mut t1=BIG::smul(&u,&b); - t1.shr(i); - c.copy(self); - c.shr(i); - c.mod2m(i); - - let mut t2=BIG::smul(&u,&c); - t2.mod2m(i); - t1.add(&t2); - b=BIG::smul(&t1,&u); - t1.copy(&b); - t1.mod2m(i); - - t2.one(); t2.shl(i); t1.rsub(&t2); t1.norm(); - t1.shl(i); - u.add(&t1); - i<<=1; - } - u.mod2m(rom::BIGBITS); - self.copy(&u); - self.norm(); - } - -/* reduce self mod m */ - pub fn rmod(&mut self,n: &BIG) { - let mut k=0; - let mut m=BIG::new_copy(n); - let mut r=BIG::new(); - self.norm(); - if BIG::comp(self,&m)<0 {return} - loop { - m.fshl(1); - k += 1; - if BIG::comp(self,&m)<0 {break} - } - - while k>0 { - m.fshr(1); - - r.copy(self); - r.sub(&m); - r.norm(); - self.cmove(&r,(1-((r.w[rom::NLEN-1]>>(rom::CHUNK-1))&1)) as isize); -/* - if BIG::comp(self,&m)>=0 { - self.sub(&m); - self.norm(); - } */ - k -= 1; - } - } - -/* divide self by m */ - pub fn div(&mut self,n: &BIG) { - let mut k=0; - self.norm(); - let mut e=BIG::new_int(1); - let mut b=BIG::new_copy(self); - let mut m=BIG::new_copy(n); - let mut r=BIG::new(); - self.zero(); - - while BIG::comp(&b,&m)>=0 { - e.fshl(1); - m.fshl(1); - k += 1; - } - - while k>0 { - m.fshr(1); - e.fshr(1); - - r.copy(&b); - r.sub(&m); - r.norm(); - let d=(1-((r.w[rom::NLEN-1]>>(rom::CHUNK-1))&1)) as isize; - b.cmove(&r,d); - r.copy(self); - r.add(&e); - r.norm(); - self.cmove(&r,d); -/* - if BIG::comp(&b,&m)>=0 { - self.add(&e); - self.norm(); - b.sub(&m); - b.norm(); - } */ - k -= 1; - } - } - -/* get 8*MODBYTES size random number */ - pub fn random(rng: &mut RAND) -> BIG { - let mut m=BIG::new(); - let mut j=0; - let mut r:u8=0; -/* generate random BIG */ - for _ in 0..8*(rom::MODBYTES as usize) { - if j==0 { - r=rng.getbyte() - } else {r>>=1} - - let b= (r as Chunk)&1; - m.shl(1); m.w[0]+=b;// m.inc(b) - j+=1; j&=7; - } - return m; - } - -/* Create random BIG in portable way, one bit at a time */ - pub fn randomnum(q: &BIG,rng: &mut RAND) -> BIG { - let mut d=DBIG::new(); - let mut j=0; - let mut r:u8=0; - for _ in 0..2*(rom::MODBITS as usize) { - if j==0 { - r=rng.getbyte(); - } else {r>>=1} - - let b= (r as Chunk)&1; - d.shl(1); d.w[0]+=b; // m.inc(b); - j+=1; j&=7; - } - let m=d.dmod(q); - return m; - } - - - /* Jacobi Symbol (this/p). Returns 0, 1 or -1 */ - pub fn jacobi(&mut self,p: &BIG) -> isize { - let mut m:usize=0; - let mut t=BIG::new(); - let mut x=BIG::new(); - let mut n=BIG::new(); - let zilch=BIG::new(); - let one=BIG::new_int(1); - if p.parity()==0 || BIG::comp(self,&zilch)==0 || BIG::comp(p,&one)<=0 {return 0} - self.norm(); - - x.copy(self); - n.copy(p); - x.rmod(p); - - while BIG::comp(&n,&one)>0 { - if BIG::comp(&x,&zilch)==0 {return 0} - let n8=n.lastbits(3) as usize; - let mut k=0; - while x.parity()==0 { - k += 1; - x.shr(1); - } - if k%2==1 {m+=(n8*n8-1)/8} - m+=(n8-1)*((x.lastbits(2) as usize)-1)/4; - t.copy(&n); - t.rmod(&x); - n.copy(&x); - x.copy(&t); - m%=2; - - } - if m==0 {return 1} - else {return -1} - } - -/* self=1/self mod p. Binary method */ - pub fn invmodp(&mut self,p: &BIG) { - self.rmod(p); - let mut u=BIG::new_copy(self); - let mut v=BIG::new_copy(p); - let mut x1=BIG::new_int(1); - let mut x2=BIG::new(); - let mut t=BIG::new(); - let one=BIG::new_int(1); - - while (BIG::comp(&u,&one) != 0 ) && (BIG::comp(&v,&one) != 0 ) { - while u.parity()==0 { - u.shr(1); - if x1.parity() != 0 { - x1.add(p); - x1.norm(); - } - x1.shr(1); - } - while v.parity()==0 { - v.shr(1); - if x2.parity() != 0 { - x2.add(p); - x2.norm(); - } - x2.shr(1); - } - if BIG::comp(&u,&v)>=0 { - u.sub(&v); - u.norm(); - if BIG::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 BIG::comp(&x2,&x1)>=0 {x2.sub(&x1)} - else - { - t.copy(p); - t.sub(&x1); - x2.add(&t); - } - x2.norm(); - } - } - if BIG::comp(&u,&one)==0 {self.copy(&x1)} - else {self.copy(&x2)} - } - - /* return a*b as DBIG */ -#[cfg(target_pointer_width = "32")] - pub fn mul(a: &BIG,b: &BIG) -> DBIG { - let mut c=DBIG::new(); - let rm=rom::BMASK as DChunk; - let rb=rom::BASEBITS; - // a.norm(); - // b.norm(); - - let mut d: [DChunk; rom::DNLEN] = [0; rom::DNLEN]; - for i in 0 ..rom::NLEN { - d[i]=(a.w[i] as DChunk)*(b.w[i] as DChunk); - } - let mut s=d[0]; - let mut t=s; c.w[0]=(t&rm) as Chunk; - let mut co=t>>rb; - for k in 1 ..rom::NLEN { - s+=d[k]; t=co+s; - for i in 1+k/2..k+1 - {t+=((a.w[i]-a.w[k-i]) as DChunk)*((b.w[k-i]-b.w[i]) as DChunk)} - c.w[k]=(t&rm) as Chunk; co=t>>rb; - } - for k in rom::NLEN ..2*rom::NLEN-1 { - s-=d[k-rom::NLEN]; t=co+s; - let mut i=1+k/2; - while i<rom::NLEN { - t+=((a.w[i]-a.w[k-i]) as DChunk)*((b.w[k-i]-b.w[i]) as DChunk); - i+=1; - } - - c.w[k]=(t&rm) as Chunk; co=t>>rb; - } - c.w[2*rom::NLEN-1]=co as Chunk; - return c; - } - -/* return a^2 as DBIG */ -#[cfg(target_pointer_width = "32")] - pub fn sqr(a: &BIG) -> DBIG { - let mut c=DBIG::new(); - let rm=rom::BMASK as DChunk; - let rb=rom::BASEBITS; - // a.norm(); - - let mut t=(a.w[0] as DChunk)*(a.w[0] as DChunk); - c.w[0]=(t&rm) as Chunk; let mut co=t>>rb; - t=(a.w[1] as DChunk)*(a.w[0] as DChunk); t+=t; t+=co; - c.w[1]=(t&rm) as Chunk; co=t>>rb; - - let last=rom::NLEN-(rom::NLEN%2); - let mut j=2; - while j<last { - t=(a.w[j] as DChunk)*(a.w[0] as DChunk); for i in 1 ..(j+1)/2 {t+=(a.w[j-i] as DChunk)*(a.w[i] as DChunk)} ; t+=t; t+=co; t+=(a.w[j/2] as DChunk)*(a.w[j/2] as DChunk); - c.w[j]=(t&rm) as Chunk; co=t>>rb; - t=(a.w[j+1] as DChunk)*(a.w[0] as DChunk); for i in 1 ..(j+2)/2 {t+=(a.w[j+1-i] as DChunk)*(a.w[i] as DChunk)} ; t+=t; t+=co; - c.w[j+1]=(t&rm) as Chunk; co=t>>rb; - j+=2; - } - j=last; - if rom::NLEN%2==1 { - t=(a.w[j] as DChunk)*(a.w[0] as DChunk); for i in 1 ..(j+1)/2 {t+=(a.w[j-i] as DChunk)*(a.w[i] as DChunk)} ; t+=t; t+=co; t+=(a.w[j/2] as DChunk)*(a.w[j/2] as DChunk); - c.w[j]=(t&rm) as Chunk; co=t>>rb; j += 1; - t=(a.w[rom::NLEN-1] as DChunk)*(a.w[j-rom::NLEN+1] as DChunk); for i in j-rom::NLEN+2 ..(j+1)/2 {t+=(a.w[j-i] as DChunk)*(a.w[i] as DChunk)}; t+=t; t+=co; - c.w[j]=(t&rm) as Chunk; co=t>>rb; j += 1; - } - while j<rom::DNLEN-2 { - t=(a.w[rom::NLEN-1] as DChunk)*(a.w[j-rom::NLEN+1] as DChunk); for i in j-rom::NLEN+2 ..(j+1)/2 {t+=(a.w[j-i] as DChunk)*(a.w[i] as DChunk)} ; t+=t; t+=co; t+=(a.w[j/2] as DChunk)*(a.w[j/2] as DChunk); - c.w[j]=(t&rm) as Chunk; co=t>>rb; - t=(a.w[rom::NLEN-1] as DChunk)*(a.w[j-rom::NLEN+2] as DChunk); for i in j-rom::NLEN+3 ..(j+2)/2 {t+=(a.w[j+1-i] as DChunk)*(a.w[i] as DChunk)} ; t+=t; t+=co; - c.w[j+1]=(t&rm) as Chunk; co=t>>rb; - j+=2; - } - t=(a.w[rom::NLEN-1] as DChunk)*(a.w[rom::NLEN-1] as DChunk)+co; - c.w[rom::DNLEN-2]=(t&rm) as Chunk; co=t>>rb; - c.w[rom::DNLEN-1]=co as Chunk; - - return c; - } - - -#[cfg(target_pointer_width = "32")] - fn monty(d: &mut DBIG) -> BIG { - let mut b=BIG::new(); - let md=BIG::new_ints(&rom::MODULUS); - let rm=rom::BMASK as DChunk; - let rb=rom::BASEBITS; - - let mut dd: [DChunk; rom::NLEN] = [0; rom::NLEN]; - let mut v: [Chunk; rom::NLEN] = [0; rom::NLEN]; - - b.zero(); - - let mut t=d.w[0] as DChunk; v[0]=(((t&rm) as Chunk).wrapping_mul(rom::MCONST))&rom::BMASK; t+=(v[0] as DChunk)*(md.w[0] as DChunk); let mut c=(d.w[1] as DChunk)+(t>>rb); let mut s:DChunk=0; - for k in 1 ..rom::NLEN { - t=c+s+(v[0] as DChunk)*(md.w[k] as DChunk); - let mut i=1+k/2; - while i<k { - t+=((v[k-i]-v[i]) as DChunk)*((md.w[i]-md.w[k-i]) as DChunk); - i+=1; - } - v[k]=(((t&rm) as Chunk).wrapping_mul(rom::MCONST))&rom::BMASK; t+=(v[k] as DChunk)*(md.w[0] as DChunk); c=(d.w[k+1] as DChunk)+(t>>rb); - dd[k]=(v[k] as DChunk)*(md.w[k] as DChunk); s+=dd[k]; - } - - for k in rom::NLEN ..2*rom::NLEN-1 - { - t=c+s; - let mut i=1+k/2; - while i<rom::NLEN { - t+=((v[k-i]-v[i]) as DChunk)*((md.w[i]-md.w[k-i]) as DChunk); - i+=1; - } - b.w[k-rom::NLEN]=(t&rm) as Chunk; c=(d.w[k+1] as DChunk)+(t>>rb); s-=dd[k-rom::NLEN+1]; - } - b.w[rom::NLEN-1]=(c&rm) as Chunk; - b.norm(); - return b; - } - - - -/* return a*b as DBIG */ -#[cfg(target_pointer_width = "64")] - pub fn mul(a: &BIG,b: &BIG) -> DBIG { - let mut c=DBIG::new(); - let mut carry; - - for i in 0 ..rom::NLEN { - carry=0; - for j in 0 ..rom::NLEN { - let tuple=BIG::muladd(a.w[i],b.w[j],carry,c.w[i+j]); - carry=tuple.0; c.w[i+j]=tuple.1; - } - c.w[rom::NLEN+i]=carry; - } - return c; - } - -/* return a^2 as DBIG */ -#[cfg(target_pointer_width = "64")] - pub fn sqr(a: &BIG) -> DBIG { - let mut c=DBIG::new(); - let mut carry; - - for i in 0 ..rom::NLEN { - carry=0; - for j in i+1 ..rom::NLEN { - let tuple=BIG::muladd(2*a.w[i],a.w[j],carry,c.w[i+j]); - carry=tuple.0; c.w[i+j]=tuple.1; - //carry,c.w[i+j]=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]) - //carry=c.muladd(2*a.w[i],a.w[j],carry,i+j) - } - c.w[rom::NLEN+i]=carry; - } - - for i in 0 ..rom::NLEN { - let tuple=BIG::muladd(a.w[i],a.w[i],0,c.w[2*i]); - c.w[2*i]=tuple.1; - c.w[2*i+1]+=tuple.0; - //c.w[2*i+1]+=c.muladd(a.w[i],a.w[i],0,2*i) - } - c.norm(); - return c; - } - -#[cfg(target_pointer_width = "64")] - fn monty(d: &mut DBIG) -> BIG { - let mut b=BIG::new(); - let md=BIG::new_ints(&rom::MODULUS); - let mut carry; - let mut m; - for i in 0 ..rom::NLEN { - if rom::MCONST==-1 { - m=(-d.w[i])&rom::BMASK; - } else { - if rom::MCONST==1 { - m=d.w[i]; - } else { - m=(rom::MCONST.wrapping_mul(d.w[i]))&rom::BMASK; - } - } - - carry=0; - for j in 0 ..rom::NLEN { - let tuple=BIG::muladd(m,md.w[j],carry,d.w[i+j]); - carry=tuple.0; d.w[i+j]=tuple.1; - } - d.w[rom::NLEN+i]+=carry; - } - - for i in 0 ..rom::NLEN { - b.w[i]=d.w[rom::NLEN+i]; - } - b.norm(); - return b; - } - - -/* reduce a DBIG to a BIG using the appropriate form of the modulus */ -/* dd */ - pub fn modulo(d: &mut DBIG) -> BIG { - - if rom::MODTYPE==rom::PSEUDO_MERSENNE { - let mut b=BIG::new(); - let mut t=d.split(rom::MODBITS); - b.dcopy(&d); - let v=t.pmul(rom::MCONST as isize); - let tw=t.w[rom::NLEN-1]; - t.w[rom::NLEN-1] &= rom::TMASK; - t.w[0]+=rom::MCONST*((tw>>rom::TBITS)+(v<<(rom::BASEBITS-rom::TBITS))); - - b.add(&t); - b.norm(); - return b; - } - - if rom::MODTYPE==rom::MONTGOMERY_FRIENDLY - { - let mut b=BIG::new(); - for i in 0 ..rom::NLEN { - let x=d.w[i]; - - let tuple=BIG::muladd(x,rom::MCONST-1,x,d.w[rom::NLEN+i-1]); - d.w[rom::NLEN+i]+=tuple.0; d.w[rom::NLEN+i-1]=tuple.1; - } - - b.zero(); - - for i in 0 ..rom::NLEN { - b.w[i]=d.w[rom::NLEN+i]; - } - b.norm(); - return b; - } - - if rom::MODTYPE==rom::GENERALISED_MERSENNE - { // GoldiLocks Only - let mut b=BIG::new(); - let t=d.split(rom::MODBITS); - let rm2=(rom::MODBITS/2) as usize; - b.dcopy(&d); - b.add(&t); - let mut dd=DBIG::new_scopy(&t); - dd.shl(rm2); - - let mut tt=dd.split(rom::MODBITS); - let lo=BIG::new_dcopy(&dd); - b.add(&tt); - b.add(&lo); - b.norm(); - tt.shl(rm2); - b.add(&tt); - - let carry=b.w[rom::NLEN-1]>>rom::TBITS; - b.w[rom::NLEN-1]&=rom::TMASK; - b.w[0]+=carry; - - b.w[(224/rom::BASEBITS) as usize]+=carry<<(224%rom::BASEBITS); - b.norm(); - return b; - } - - if rom::MODTYPE==rom::NOT_SPECIAL { - return BIG::monty(d); - } - return BIG::new(); - } - - /* return a*b mod m */ - pub fn modmul(a: &mut BIG,b: &mut BIG,m: &BIG) -> BIG { - a.rmod(m); - b.rmod(m); - let mut d=BIG::mul(a,b); - return d.dmod(m); - } - - /* return a^2 mod m */ - pub fn modsqr(a: &mut BIG,m: &BIG) -> BIG { - a.rmod(m); - let mut d=BIG::sqr(a); - return d.dmod(m); - } - - /* return -a mod m */ - pub fn modneg(a: &mut BIG,m: &BIG) -> BIG { - a.rmod(m); - return m.minus(a); - } - - /* return this^e mod m */ - pub fn powmod(&mut self,e: &mut BIG,m: &BIG) -> BIG { - self.norm(); - e.norm(); - let mut a=BIG::new_int(1); - let mut z=BIG::new_copy(e); - let mut s=BIG::new_copy(self); - loop { - let bt=z.parity(); - z.fshr(1); - if bt==1 {a=BIG::modmul(&mut a,&mut s,m)} - if z.iszilch() {break} - s=BIG::modsqr(&mut s,m); - } - return a; - } - -} - -/* -fn main() { - let fd: [i32; rom::NLEN as usize] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; - let mut x= BIG::new(); - x.inc(3); - println!("{}", x.w[0]); - let mut y= BIG::new_int(7); - println!("{}", y.w[0]); - y=BIG::new_copy(&x); - println!("{}", y.w[0]); - x.add(&y); - x.add(&y); - println!("{}", x.w[0]); - let mut z= BIG::new_ints(&fd); - println!("{}", z.w[0]); - z.shr(3); - z.norm(); - println!("{:X}", z.w[0]); - - println!("{}",z.tostring()); - - let mut a = BIG::new_int(3); - let mut m = BIG::new_ints(&MODULUS); - - println!("rom::MODULUS= {}",m.tostring()); - - let mut e = BIG::new_copy(&m); - e.dec(1); e.norm(); - println!("Exponent= {}",e.tostring()); -// for i in 0..20 -// { - a=a.powmod(&mut e,&mut m); -// a.inc(2); -// } - println!("Result= {}",a.tostring()); - -} -*/
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/dbig.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/dbig.rs b/version22/rust/src/dbig.rs deleted file mode 100644 index 167cfaf..0000000 --- a/version22/rust/src/dbig.rs +++ /dev/null @@ -1,249 +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 rom; - -use rom::Chunk; - -//#[derive(Copy, Clone)] -pub struct DBIG { - pub w: [Chunk; rom::DNLEN] -} - -//mod big; -use big::BIG; - -impl DBIG { - pub fn new() -> DBIG { - DBIG { - w: [0; rom::DNLEN as usize] - } - } - - pub fn new_copy(y:&DBIG) -> DBIG { - let mut s= DBIG::new(); - for i in 0..rom::NLEN {s.w[i]=y.w[i]} - return s; - } - - pub fn new_scopy(x:&BIG) -> DBIG { - let mut b= DBIG::new(); - for i in 0 ..rom::NLEN { - b.w[i]=x.w[i]; - } - b.w[rom::NLEN-1]=x.get(rom::NLEN-1)&rom::BMASK; /* top word normalized */ - b.w[rom::NLEN]=x.get(rom::NLEN-1)>>rom::BASEBITS; - - for i in rom::NLEN+1 ..rom::DNLEN {b.w[i]=0} - return b; - } - -/* split DBIG at position n, return higher half, keep lower half */ - pub fn split(&mut self,n: usize) -> BIG - { - let mut t=BIG::new(); - let m=n%rom::BASEBITS; - let mut carry=self.w[rom::DNLEN-1]<<(rom::BASEBITS-m); - - for i in (rom::NLEN-1..rom::DNLEN-1).rev() { - let nw=(self.w[i]>>m)|carry; - carry= (self.w[i]<<(rom::BASEBITS-m))&rom::BMASK; - t.set(i-rom::NLEN+1,nw); - } - self.w[rom::NLEN-1]&=((1 as Chunk)<<m)-1; - return t; - } - -/* general shift left */ - pub fn shl(&mut self,k: usize) - { - let n=k%rom::BASEBITS; - let m=k/rom::BASEBITS; - self.w[rom::DNLEN-1]=((self.w[rom::DNLEN-1-m]<<n))|(self.w[rom::DNLEN-m-2]>>(rom::BASEBITS-n)); - for i in (m+1..rom::DNLEN-1).rev() { - self.w[i]=((self.w[i-m]<<n)&rom::BMASK)|(self.w[i-m-1]>>(rom::BASEBITS-n)); - } - - self.w[m]=(self.w[0]<<n)&rom::BMASK; - for i in 0 ..m {self.w[i]=0} - } - -/* general shift right */ - pub fn shr(&mut self,k: usize) { - let n=k%rom::BASEBITS; - let m=k/rom::BASEBITS; - for i in 0 ..rom::DNLEN-m-1 { - self.w[i]=(self.w[m+i]>>n)|((self.w[m+i+1]<<(rom::BASEBITS-n))&rom::BMASK); - } - self.w[rom::DNLEN-m-1]=self.w[rom::DNLEN-1]>>n; - for i in rom::DNLEN - m ..rom::DNLEN {self.w[i]=0} - } - -/* Copy from another DBIG */ - pub fn copy(&mut self,x: &DBIG) { - for i in 0 ..rom::DNLEN { - self.w[i]=x.w[i] - } - } - - pub fn cmove(&mut self,g:&DBIG,d: isize) { - let b=-d as Chunk; - for i in 0 ..rom::DNLEN { - self.w[i]^=(self.w[i]^g.w[i])&b; - } - } - -/* self-=x */ - pub fn sub(&mut self,x:&DBIG) { - for i in 0 ..rom::DNLEN { - self.w[i]-=x.w[i]; - } - } - -/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */ - pub fn comp(a: &DBIG,b: &DBIG) -> isize { - for i in (0 ..rom::DNLEN).rev() { - if a.w[i]==b.w[i] {continue} - if a.w[i]>b.w[i] {return 1} - else {return -1} - } - return 0; - } - -/* normalise BIG - force all digits < 2^rom::BASEBITS */ - pub fn norm(&mut self) { - let mut carry=0 as Chunk; - for i in 0 ..rom::DNLEN-1 { - let d=self.w[i]+carry; - self.w[i]=d&rom::BMASK; - carry=d>>rom::BASEBITS; - } - self.w[rom::DNLEN-1]+=carry - } - -/* reduces self DBIG mod a BIG, and returns the BIG */ - pub fn dmod(&mut self,c: &BIG) -> BIG { - let mut k=0; - self.norm(); - let mut m=DBIG::new_scopy(c); - let mut dr=DBIG::new(); - - if DBIG::comp(self,&m)<0 { - let r=BIG::new_dcopy(self); - return r; - } - - loop { - m.shl(1); - k += 1; - if DBIG::comp(self,&m)<0 {break;} - } - - while k>0 { - m.shr(1); - - dr.copy(self); - dr.sub(&m); - dr.norm(); - self.cmove(&dr,(1-((dr.w[rom::DNLEN-1]>>(rom::CHUNK-1))&1)) as isize); -/* - if DBIG::comp(self,&m)>=0 { - self.sub(&m); - self.norm(); - } */ - k -= 1; - } - let r=BIG::new_dcopy(self); - return r; - } - -/* return this/c */ - pub fn div(&mut self,c: &BIG) -> BIG { - let mut k=0; - let mut m=DBIG::new_scopy(c); - let mut a=BIG::new(); - let mut e=BIG::new_int(1); - let mut dr=DBIG::new(); - let mut r=BIG::new(); - self.norm(); - - while DBIG::comp(self,&m)>=0 { - e.fshl(1); - m.shl(1); - k+=1; - } - - while k>0 { - m.shr(1); - e.shr(1); - - dr.copy(self); - dr.sub(&m); - dr.norm(); - let d=(1-((dr.w[rom::DNLEN-1]>>(rom::CHUNK-1))&1)) as isize; - self.cmove(&dr,d); - r.copy(&a); - r.add(&e); - r.norm(); - a.cmove(&r,d); -/* - if DBIG::comp(self,&m)>0 { - a.add(&e); - a.norm(); - self.sub(&m); - self.norm(); - } */ - k-=1; - } - return a; - } - -/* return number of bits */ - pub fn nbits(&mut self) -> usize { - let mut k=rom::DNLEN-1; - self.norm(); - while (k as isize)>=0 && self.w[k]==0 {k=k-1} - if (k as isize) <0 {return 0} - let mut bts=(rom::BASEBITS as usize)*k; - let mut c=self.w[k]; - while c!=0 {c/=2; bts+=1;} - return bts; - } - -/* Convert to Hex String */ - pub fn to_string(&mut self) -> String { - let mut s = String::new(); - let mut len=self.nbits(); - - if len%4==0 { - len/=4; - } else { - len/=4; - len+=1; - } - - for i in (0 ..len).rev() { - let mut b=DBIG::new_copy(&self); - b.shr(i*4); - s=s + &format!("{:X}", b.w[0]&15); - } - return s; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/ecdh.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/ecdh.rs b/version22/rust/src/ecdh.rs deleted file mode 100644 index 1511140..0000000 --- a/version22/rust/src/ecdh.rs +++ /dev/null @@ -1,585 +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 ecp::ECP; -use big::BIG; -use rand::RAND; -use hash256::HASH256; -use hash384::HASH384; -use hash512::HASH512; -use aes; -use aes::AES; -use rom; - - -pub const INVALID_PUBLIC_KEY:isize=-2; -pub const ERROR: isize=-3; -pub const INVALID: isize=-4; -pub const EFS: usize=rom::MODBYTES as usize; -pub const EGS: usize=rom::MODBYTES as usize; -pub const EAS: usize=16; -pub const EBS: usize=16; -pub const SHA256: usize=32; -pub const SHA384: usize=48; -pub const SHA512: usize=64; - -pub const HASH_TYPE: usize=SHA512; - -#[allow(non_snake_case)] - -fn inttobytes(n: usize,b:&mut [u8]) { - let mut i=b.len(); - let mut m=n; - while m>0 && i>0 { - i-=1; - b[i]=(m&0xff) as u8; - m/=256; - } -} - -fn hashit(sha: usize, a: &[u8],n: usize,b: Option<&[u8]>,pad: usize,w: &mut [u8]) { - let mut r:[u8;64]=[0;64]; - if sha==SHA256 { - let mut h=HASH256::new(); - h.process_array(a); - if n>0 {h.process_num(n as i32)} - if let Some(x) = b { - h.process_array(x); - } - let hs=h.hash(); - for i in 0..sha {r[i]=hs[i];} - } - if sha==SHA384 { - let mut h=HASH384::new(); - h.process_array(a); - if n>0 {h.process_num(n as i32)} - if let Some(x) = b { - h.process_array(x); - } - let hs=h.hash(); - for i in 0..sha {r[i]=hs[i];} - } - if sha==SHA512 { - let mut h=HASH512::new(); - h.process_array(a); - if n>0 {h.process_num(n as i32)} - if let Some(x) = b { - h.process_array(x); - } - let hs=h.hash(); - for i in 0..sha {r[i]=hs[i];} - } - - if pad==0 { - for i in 0..sha {w[i]=r[i]} - } else { - - if pad<=sha { - for i in 0..pad {w[i]=r[i]} - } else { - for i in 0..sha {w[i]=r[i]} - for i in sha..pad {w[i]=0} - } - } -} - -/* Key Derivation Functions */ -/* Input octet Z */ -/* Output key of length olen */ -pub fn kdf1(sha: usize,z: &[u8],olen: usize,k: &mut [u8]) { -/* NOTE: the parameter olen is the length of the output K in bytes */ - let hlen=sha; - let mut lk=0; - - let mut cthreshold=olen/hlen; if olen%hlen!=0 {cthreshold+=1} - - for counter in 0..cthreshold { - let mut b:[u8;64]=[0;64]; - hashit(sha,z,counter,None,0,&mut b); - if lk+hlen>olen { - for i in 0..(olen%hlen) {k[lk]=b[i]; lk+=1} - } else { - for i in 0..hlen {k[lk]=b[i]; lk+=1} - } - } -} - -pub fn kdf2(sha: usize,z: &[u8],p: Option<&[u8]>,olen: usize,k: &mut [u8]) { -/* NOTE: the parameter olen is the length of the output K in bytes */ - let hlen=sha; - let mut lk=0; - - let mut cthreshold=olen/hlen; if olen%hlen!=0 {cthreshold+=1} - - for counter in 1..cthreshold+1 { - let mut b:[u8;64]=[0;64]; - hashit(sha,z,counter,p,0,&mut b); - if lk+hlen>olen { - for i in 0..(olen%hlen) {k[lk]=b[i]; lk+=1} - } else { - for i in 0..hlen {k[lk]=b[i]; lk+=1} - } - } -} - -/* Password based Key Derivation Function */ -/* Input password p, salt s, and repeat count */ -/* Output key of length olen */ -pub fn pbkdf2(sha: usize,pass: &[u8],salt: &[u8],rep: usize,olen: usize,k: &mut [u8]) { - let mut d=olen/sha; if olen%sha!=0 {d+=1} - let mut f:[u8;64]=[0;64]; - let mut u:[u8;64]=[0;64]; - let mut ku:[u8;64]=[0;64]; - let mut s:[u8;36]=[0;36]; // Maximum salt of 32 bytes + 4 - let mut n:[u8;4]=[0;4]; - - let sl=salt.len(); - let mut kp=0; - for i in 0..d { - for j in 0..sl {s[j]=salt[j]} - inttobytes(i+1,&mut n); - for j in 0..4 {s[sl+j]=n[j]} - - hmac(sha,&s[0..sl+4],pass,sha,&mut f); - - for j in 0..sha {u[j]=f[j]} - for _ in 1..rep { - hmac(sha,&mut u,pass,sha,&mut ku); - for k in 0..sha {u[k]=ku[k]; f[k]^=u[k]} - } - for j in 0..EFS {if kp<olen {k[kp]=f[j]} kp+=1} - } -} - -/* Calculate HMAC of m using key k. HMAC is tag of length olen (which is length of tag) */ -pub fn hmac(sha: usize,m: &[u8],k: &[u8],olen: usize,tag: &mut [u8]) -> bool { - /* Input is from an octet m * - * olen is requested output length in bytes. k is the key * - * The output is the calculated tag */ - let mut b:[u8;64]=[0;64]; /* Not good */ - let mut k0:[u8;128]=[0;128]; -// let olen=tag.len(); /* length of HMAC */ - - if olen<4 /*|| olen>sha */ {return false} - - let mut lb=64; - if sha>32 {lb=128} - - for i in 0..lb {k0[i]=0} - - if k.len() > lb { - hashit(sha,k,0,None,0,&mut b); - for i in 0..sha {k0[i]=b[i]} - } else { - for i in 0..k.len() {k0[i]=k[i]} - } - - for i in 0..lb {k0[i]^=0x36} - hashit(sha,&mut k0[0..lb],0,Some(m),0,&mut b); - - for i in 0..lb {k0[i]^=0x6a} - hashit(sha,&mut k0[0..lb],0,Some(&b[0..sha]),olen,tag); - - return true; -} - -/* AES encryption/decryption. Encrypt byte array m using key k and returns ciphertext c */ -pub fn cbc_iv0_encrypt(k: &[u8],m: &[u8]) -> Vec<u8> { /* AES CBC encryption, with Null IV and key K */ - /* Input is from an octet string m, output is to an octet string c */ - /* Input is padded as necessary to make up a full final block */ - let mut a=AES::new(); - let mut fin=false; - let mut c:Vec<u8>=Vec::new(); - - let mut buff:[u8;16]=[0;16]; - - a.init(aes::CBC,k.len(),k,None); - - let mut ipt=0; -// let mut opt=0; - let mut i; - loop { - i=0; - while i<16 { - if ipt<m.len() { - buff[i]=m[ipt]; i+=1; ipt+=1; - } else {fin=true; break;} - } - if fin {break} - a.encrypt(&mut buff); - for j in 0..16 { - c.push(buff[j]); - //c[opt]=buff[j]; opt+=1; - } - } - -/* last block, filled up to i-th index */ - - let padlen=16-i; - for j in i..16 {buff[j]=padlen as u8} - - a.encrypt(&mut buff); - - for j in 0..16 { - c.push(buff[j]); - //c[opt]=buff[j]; opt+=1; - } - a.end(); - return c; -} - -/* returns plaintext if all consistent, else returns null string */ -pub fn cbc_iv0_decrypt(k: &[u8],c: &[u8]) -> Option<Vec<u8>> { /* padding is removed */ - let mut a=AES::new(); - let mut fin=false; - let mut m:Vec<u8>=Vec::new(); - - let mut buff:[u8;16]=[0;16]; - - a.init(aes::CBC,k.len(),k,None); - - let mut ipt=0; - //let mut opt=0; - let mut i; - - if c.len()==0 {return None} - let mut ch=c[ipt]; ipt+=1; - - loop { - i=0; - while i<16 { - buff[i]=ch; - if ipt>=c.len() { - fin=true; break; - } else {ch=c[ipt]; ipt+=1 } - i+=1; - } - a.decrypt(&mut buff); - if fin {break} - for j in 0..16 { - m.push(buff[j]); - //m[opt]=buff[j]; opt+=1; - } - } - - a.end(); - let mut bad=false; - let padlen=buff[15] as usize; - if i!=15 || padlen<1 || padlen>16 {bad=true} - if padlen>=2 && padlen<=16 { - for j in 16-padlen..16 { - if buff[j]!=padlen as u8 {bad=true} - } - } - - if !bad { - for _ in 0..16-padlen { - m.push(buff[i]); - //m[opt]=buff[j]; opt+=1; - } - } - - if bad {return None} - return Some(m); -} - -/* Calculate a public/private EC GF(p) key pair w,s where W=s.G mod EC(p), - * where s is the secret key and W is the public key - * and G is fixed generator. - * If RNG is NULL then the private key is provided externally in s - * otherwise it is generated randomly internally */ - #[allow(non_snake_case)] -pub fn key_pair_generate(rng: Option<&mut RAND>,s: &mut [u8],w: &mut [u8]) -> isize { - let res=0; - let mut sc:BIG; - let mut G:ECP; - - let gx=BIG::new_ints(&rom::CURVE_GX); - - if rom::CURVETYPE!=rom::MONTGOMERY { - let gy=BIG::new_ints(&rom::CURVE_GY); - G=ECP::new_bigs(&gx,&gy); - } else { - G=ECP::new_big(&gx); - } - - let r=BIG::new_ints(&rom::CURVE_ORDER); - - if let Some(mut x)=rng { - sc=BIG::randomnum(&r,&mut x); - } else { - sc=BIG::frombytes(&s); - sc.rmod(&r); - } - - if rom::AES_S>0 { - sc.mod2m(2*rom::AES_S) - } - sc.tobytes(s); - - let mut WP=G.mul(&mut sc); - - WP.tobytes(w); - - return res; -} - -/* validate public key. Set full=true for fuller check */ -#[allow(non_snake_case)] -pub fn public_key_validate(full: bool,w: &[u8]) -> isize { - let mut WP=ECP::frombytes(w); - let mut res=0; - - let mut r=BIG::new_ints(&rom::CURVE_ORDER); - - if WP.is_infinity() {res=INVALID_PUBLIC_KEY} - if res==0 && full { - WP=WP.mul(&mut r); - if !WP.is_infinity() {res=INVALID_PUBLIC_KEY} - } - return res; -} - -/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */ -#[allow(non_snake_case)] -pub fn ecpsvdp_dh(s: &[u8],wd: &[u8],z: &mut [u8]) -> isize { - let mut res=0; - let mut t:[u8;EFS]=[0;EFS]; - - let mut sc=BIG::frombytes(&s); - - let mut W=ECP::frombytes(&wd); - if W.is_infinity() {res=ERROR} - - if res==0 { - let r=BIG::new_ints(&rom::CURVE_ORDER); - sc.rmod(&r); - W=W.mul(&mut sc); - if W.is_infinity() { - res=ERROR; - } else { - W.getx().tobytes(&mut t); - for i in 0..EFS {z[i]=t[i]} - } - } - return res; -} - -/* IEEE ECDSA Signature, C and D are signature on F using private key S */ -#[allow(non_snake_case)] -pub fn ecpsp_dsa(sha: usize,rng: &mut RAND,s: &[u8],f: &[u8],c: &mut [u8],d: &mut [u8]) -> isize { - let mut t:[u8;EFS]=[0;EFS]; - let mut b:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - - hashit(sha,f,0,None,rom::MODBYTES as usize,&mut b); - - let gx=BIG::new_ints(&rom::CURVE_GX); - let gy=BIG::new_ints(&rom::CURVE_GY); - - let G=ECP::new_bigs(&gx,&gy); - let r=BIG::new_ints(&rom::CURVE_ORDER); - - let mut sc=BIG::frombytes(s); /* s or &s? */ - let fb=BIG::frombytes(&b); - - let mut cb=BIG::new(); - let mut db=BIG::new(); - let mut tb=BIG::new(); - let mut V=ECP::new(); - - while db.iszilch() { - let mut u=BIG::randomnum(&r,rng); - let mut w=BIG::randomnum(&r,rng); - if rom::AES_S>0 { - u.mod2m(2*rom::AES_S); - } - V.copy(&G); - V=V.mul(&mut u); - let vx=V.getx(); - cb.copy(&vx); - cb.rmod(&r); - if cb.iszilch() {continue} - - tb.copy(&BIG::modmul(&mut u,&mut w,&r)); - u.copy(&tb); - - u.invmodp(&r); - db.copy(&BIG::modmul(&mut sc,&mut cb,&r)); - db.add(&fb); - - tb.copy(&BIG::modmul(&mut db,&mut w,&r)); - db.copy(&tb); - - tb.copy(&BIG::modmul(&mut u,&mut db,&r)); - db.copy(&tb); - } - - cb.tobytes(&mut t); - for i in 0..EFS {c[i]=t[i]} - db.tobytes(&mut t); - for i in 0..EFS {d[i]=t[i]} - return 0; -} - -/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */ -#[allow(non_snake_case)] -pub fn ecpvp_dsa(sha: usize,w: &[u8],f: &[u8],c: &[u8],d: &[u8]) -> isize { - let mut res=0; - - let mut b:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - - hashit(sha,f,0,None,rom::MODBYTES as usize,&mut b); - - let gx=BIG::new_ints(&rom::CURVE_GX); - let gy=BIG::new_ints(&rom::CURVE_GY); - - let mut G=ECP::new_bigs(&gx,&gy); - let r=BIG::new_ints(&rom::CURVE_ORDER); - - let mut cb=BIG::frombytes(c); /* c or &c ? */ - let mut db=BIG::frombytes(d); /* d or &d ? */ - let mut fb=BIG::frombytes(&b); - let mut tb=BIG::new(); - - if cb.iszilch() || BIG::comp(&cb,&r)>=0 || db.iszilch() || BIG::comp(&db,&r)>=0 { - res=INVALID; - } - - if res==0 { - db.invmodp(&r); - tb.copy(&BIG::modmul(&mut fb,&mut db,&r)); - fb.copy(&tb); - let h2=BIG::modmul(&mut cb,&mut db,&r); - - let mut WP=ECP::frombytes(&w); - if WP.is_infinity() { - res=ERROR; - } else { - let mut P=ECP::new(); - P.copy(&WP); - - P=P.mul2(&h2,&mut G,&fb); - - if P.is_infinity() { - res=INVALID; - } else { - db=P.getx(); - db.rmod(&r); - - if BIG::comp(&db,&cb)!=0 {res=INVALID} - } - } - } - - return res; -} - -/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */ -#[allow(non_snake_case)] -pub fn ecies_encrypt(sha: usize,p1: &[u8],p2: &[u8],rng: &mut RAND,w: &[u8],m: &[u8],v: &mut [u8],t: &mut [u8]) -> Option<Vec<u8>> { - let mut z:[u8;EFS]=[0;EFS]; - let mut k1:[u8;EAS]=[0;EAS]; - let mut k2:[u8;EAS]=[0;EAS]; - let mut u:[u8;EGS]=[0;EGS]; - let mut vz:[u8;3*EFS+1]=[0;3*EFS+1]; - let mut k:[u8;EFS]=[0;EFS]; - - if key_pair_generate(Some(rng),&mut u,v)!=0 {return None} - if ecpsvdp_dh(&u,&w,&mut z)!=0 {return None} - - for i in 0..2*EFS+1 {vz[i]=v[i]} - for i in 0..EFS {vz[2*EFS+1+i]=z[i]} - - - kdf2(sha,&vz,Some(p1),EFS,&mut k); - - for i in 0..EAS {k1[i]=k[i]; k2[i]=k[EAS+i]} - - let mut c=cbc_iv0_encrypt(&k1,m); - - let mut l2:[u8;8]=[0;8]; - let p2l=p2.len(); - - inttobytes(p2l,&mut l2); - - for i in 0..p2l { - c.push(p2[i]); - } - for i in 0..8 { - c.push(l2[i]); - } - - hmac(sha,&c,&k2,t.len(),t); - - for _ in 0..p2l+8 {c.pop();} - - return Some(c); -} - -/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */ -#[allow(non_snake_case)] -pub fn ecies_decrypt(sha: usize,p1: &[u8],p2: &[u8],v: &[u8],c: &mut Vec<u8>,t: &[u8],u: &[u8]) -> Option<Vec<u8>> { - let mut z:[u8;EFS]=[0;EFS]; - let mut k1:[u8;EAS]=[0;EAS]; - let mut k2:[u8;EAS]=[0;EAS]; - let mut vz:[u8;3*EFS+1]=[0;3*EFS+1]; - let mut k:[u8;EFS]=[0;EFS]; - - let mut tag:[u8;32]=[0;32]; /* 32 is max length of tag */ - - for i in 0..t.len() {tag[i]=t[i]} - - if ecpsvdp_dh(&u,&v,&mut z)!=0 {return None} - - for i in 0..2*EFS+1 {vz[i]=v[i]} - for i in 0..EFS {vz[2*EFS+1+i]=z[i]} - - kdf2(sha,&vz,Some(p1),EFS,&mut k); - - for i in 0..EAS {k1[i]=k[i]; k2[i]=k[EAS+i]} - - let m=cbc_iv0_decrypt(&k1,&c); - - if m==None {return None} - - let mut l2:[u8;8]=[0;8]; - let p2l=p2.len(); - - inttobytes(p2l,&mut l2); - - for i in 0..p2l { - c.push(p2[i]); - } - for i in 0..8 { - c.push(l2[i]); - } - - hmac(sha,&c,&k2,t.len(),&mut tag); - - for _ in 0..p2l+8 {c.pop();} - - let mut same=true; - for i in 0..t.len() { - if t[i]!=tag[i] {same=false} - } - if !same {return None} - - return m; -} - http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/1add7560/version22/rust/src/ecp.rs ---------------------------------------------------------------------- diff --git a/version22/rust/src/ecp.rs b/version22/rust/src/ecp.rs deleted file mode 100644 index 69b6c57..0000000 --- a/version22/rust/src/ecp.rs +++ /dev/null @@ -1,955 +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 ECP { - x:FP, - y:FP, - z:FP, - inf: bool -} - - -//use rom; -//mod fp; -use fp::FP; -//mod big; -use big::BIG; -//mod dbig; -//use dbig::DBIG; -//mod rand; -//mod hash256; -//mod rom; -use rom; -use rom::BIG_HEX_STRING_LEN; - -impl fmt::Display for ECP { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ECP: [ {}, {}, {}, {} ]", self.inf, self.x, self.y, self.z) - } -} - -impl fmt::Debug for ECP { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "ECP: [ {}, {}, {}, {} ]", self.inf, self.x, self.y, self.z) - } -} - -impl PartialEq for ECP { - fn eq(&self, other: &ECP) -> bool { - return (self.inf == other.inf) && - (self.x == other.x) && - (self.y == other.y) && - (self.z == other.z); - } -} - -#[allow(non_snake_case)] -impl ECP { - - pub fn new() -> ECP { - ECP { - x: FP::new(), - y: FP::new(), - z: FP::new(), - inf: true - } - } - -/* set (x,y) from two BIGs */ - pub fn new_bigs(ix: &BIG,iy: &BIG) -> ECP { - let mut E=ECP::new(); - E.x.bcopy(ix); - E.y.bcopy(iy); - E.z.one(); - let mut rhs=ECP::rhs(&mut E.x); - if rom::CURVETYPE==rom::MONTGOMERY { - if rhs.jacobi()==1 { - E.inf=false; - } else {E.inf()} - } else { - let mut y2=FP::new_copy(&E.y); - y2.sqr(); - if y2.equals(&mut rhs) { - E.inf=false - } else {E.inf()} - } - return E; - } - -/* set (x,y) from BIG and a bit */ - pub fn new_bigint(ix: &BIG,s: isize) -> ECP { - let mut E=ECP::new(); - E.x.bcopy(ix); - E.z.one(); - - let mut rhs=ECP::rhs(&mut E.x); - - if rhs.jacobi()==1 { - let mut ny=rhs.sqrt(); - if ny.redc().parity()!=s {ny.neg()} - E.y.copy(&ny); - E.inf=false; - } else {E.inf()} - return E; - } - -#[allow(non_snake_case)] -/* set from x - calculate y from curve equation */ - pub fn new_big(ix: &BIG) -> ECP { - let mut E=ECP::new(); - E.x.bcopy(ix); - E.z.one(); - let mut rhs=ECP::rhs(&mut E.x); - if rhs.jacobi()==1 { - if rom::CURVETYPE!=rom::MONTGOMERY {E.y.copy(&rhs.sqrt())} - E.inf=false; - } else {E.inf=true} - return E; - } - -/* set this=O */ - pub fn inf(&mut self) { - self.inf=true; - self.x.zero(); - self.y.one(); - self.z.one(); - } - -/* Calculate RHS of curve equation */ - fn rhs(x: &mut FP) -> FP { - x.norm(); - let mut r=FP::new_copy(x); - r.sqr(); - - if rom::CURVETYPE==rom::WEIERSTRASS { // x^3+Ax+B - let b=FP::new_big(&BIG::new_ints(&rom::CURVE_B)); - r.mul(x); - if rom::CURVE_A==-3 { - let mut cx=FP::new_copy(x); - cx.imul(3); - cx.neg(); cx.norm(); - r.add(&cx); - } - r.add(&b); - } - if rom::CURVETYPE==rom::EDWARDS { // (Ax^2-1)/(Bx^2-1) - let mut b=FP::new_big(&BIG::new_ints(&rom::CURVE_B)); - let one=FP::new_int(1); - b.mul(&mut r); - b.sub(&one); - if rom::CURVE_A==-1 {r.neg()} - r.sub(&one); - b.inverse(); - r.mul(&mut b); - } - if rom::CURVETYPE==rom::MONTGOMERY { // x^3+Ax^2+x - let mut x3=FP::new(); - x3.copy(&r); - x3.mul(x); - r.imul(rom::CURVE_A); - r.add(&x3); - r.add(&x); - } - r.reduce(); - return r; - } - -/* test for O point-at-infinity */ - pub fn is_infinity(&mut self) -> bool { - if rom::CURVETYPE==rom::EDWARDS { - self.x.reduce(); self.y.reduce(); self.z.reduce(); - return self.x.iszilch() && self.y.equals(&mut self.z); - } else {return self.inf} - } - -/* Conditional swap of P and Q dependant on d */ - pub fn cswap(&mut self,Q: &mut ECP,d: isize) { - self.x.cswap(&mut Q.x,d); - if rom::CURVETYPE!=rom::MONTGOMERY {self.y.cswap(&mut Q.y,d)} - self.z.cswap(&mut Q.z,d); - if rom::CURVETYPE!=rom::EDWARDS { - let mut bd=true; - if d==0 {bd=false} - bd=bd&&(self.inf!=Q.inf); - self.inf=bd!=self.inf; - Q.inf=bd!=Q.inf; - } - } - -/* Conditional move of Q to P dependant on d */ - pub fn cmove(&mut self,Q: &ECP,d: isize) { - self.x.cmove(&Q.x,d); - if rom::CURVETYPE!=rom::MONTGOMERY {self.y.cmove(&Q.y,d)} - self.z.cmove(&Q.z,d); - if rom::CURVETYPE!=rom::EDWARDS { - let mut bd=true; - if d==0 {bd=false} - 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; - } - -/* this=P */ - pub fn copy(&mut self,P: & ECP) { - self.x.copy(&P.x); - if rom::CURVETYPE!=rom::MONTGOMERY {self.y.copy(&P.y)} - self.z.copy(&P.z); - self.inf=P.inf; -} - -/* this=-this */ - pub fn neg(&mut self) { - if self.is_infinity() {return} - if rom::CURVETYPE==rom::WEIERSTRASS { - self.y.neg(); self.y.norm(); - } - if rom::CURVETYPE==rom::EDWARDS { - self.x.neg(); self.x.norm(); - } - return; - } -/* multiply x coordinate */ - pub fn mulx(&mut self,c: &mut FP) { - self.x.mul(c); - } - -/* Constant time select from pre-computed table */ - fn selector(&mut self, W: &[ECP],b: i32) { // unsure about &[& syntax. An array of pointers I hope.. - let mut MP=ECP::new(); - let m=b>>31; - let mut babs=(b^m)-m; - - babs=(babs-1)/2; - - self.cmove(&W[0],ECP::teq(babs,0)); // conditional move - self.cmove(&W[1],ECP::teq(babs,1)); - self.cmove(&W[2],ECP::teq(babs,2)); - self.cmove(&W[3],ECP::teq(babs,3)); - self.cmove(&W[4],ECP::teq(babs,4)); - self.cmove(&W[5],ECP::teq(babs,5)); - self.cmove(&W[6],ECP::teq(babs,6)); - self.cmove(&W[7],ECP::teq(babs,7)); - - MP.copy(self); - MP.neg(); - self.cmove(&MP,(m&1) as isize); - } - -/* Test P == Q */ - pub fn equals(&mut self,Q: &mut ECP) -> bool { - if self.is_infinity() && Q.is_infinity() {return true} - if self.is_infinity() || Q.is_infinity() {return false} - if rom::CURVETYPE==rom::WEIERSTRASS { - let mut zs2=FP::new_copy(&self.z); zs2.sqr(); - let mut zo2=FP::new_copy(&Q.z); zo2.sqr(); - let mut zs3=FP::new_copy(&zs2); zs3.mul(&mut self.z); - let mut zo3=FP::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} - } else { - let mut a=FP::new(); - let mut b=FP::new(); - a.copy(&self.x); a.mul(&mut Q.z); a.reduce(); - b.copy(&Q.x); b.mul(&mut self.z); b.reduce(); - if !a.equals(&mut b) {return false} - if rom::CURVETYPE==rom::EDWARDS { - a.copy(&self.y); a.mul(&mut Q.z); a.reduce(); - b.copy(&Q.y); b.mul(&mut self.z); b.reduce(); - if !a.equals(&mut b) {return false} - } - } - return true; - } - -/* set to affine - from (x,y,z) to (x,y) */ - pub fn affine(&mut self) { - if self.is_infinity() {return} - let mut one=FP::new_int(1); - if self.z.equals(&mut one) {return} - self.z.inverse(); - if rom::CURVETYPE==rom::WEIERSTRASS { - let mut z2=FP::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(); - } - if rom::CURVETYPE==rom::EDWARDS { - self.x.mul(&mut self.z); self.x.reduce(); - self.y.mul(&mut self.z); self.y.reduce(); - } - if rom::CURVETYPE==rom::MONTGOMERY { - self.x.mul(&mut self.z); self.x.reduce(); - } - self.z.one(); - } - -/* extract x as a BIG */ - pub fn getx(&mut self) -> BIG { - self.affine(); - return self.x.redc(); - } - -/* extract y as a BIG */ - pub fn gety(&mut self) -> BIG { - self.affine(); - return self.y.redc(); - } - -/* get sign of Y */ - pub fn gets(&mut self) -> isize { - self.affine(); - let y=self.gety(); - return y.parity(); - } - -/* extract x as an FP */ - pub fn getpx(&self) -> FP { - let w=FP::new_copy(&self.x); - return w; - } -/* extract y as an FP */ - pub fn getpy(&self) -> FP { - let w=FP::new_copy(&self.y); - return w; - } - -/* extract z as an FP */ - pub fn getpz(&self) -> FP { - let w=FP::new_copy(&self.z); - return w; - } - -/* convert to byte array */ - pub fn tobytes(&mut self,b: &mut [u8]) { - let mb=rom::MODBYTES as usize; - let mut t:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - if rom::CURVETYPE!=rom::MONTGOMERY { - b[0]=0x04; - } else {b[0]=0x02} - - self.affine(); - self.x.redc().tobytes(&mut t); - for i in 0..mb {b[i+1]=t[i]} - if rom::CURVETYPE!=rom::MONTGOMERY { - self.y.redc().tobytes(&mut t); - for i in 0..mb {b[i+mb+1]=t[i]} - } - } - -/* convert from byte array to point */ - pub fn frombytes(b: &[u8]) -> ECP { - let mut t:[u8;rom::MODBYTES as usize]=[0;rom::MODBYTES as usize]; - let mb=rom::MODBYTES as usize; - let p=BIG::new_ints(&rom::MODULUS); - - for i in 0..mb {t[i]=b[i+1]} - let px=BIG::frombytes(&t); - if BIG::comp(&px,&p)>=0 {return ECP::new()} - - if b[0]==0x04 { - for i in 0..mb {t[i]=b[i+mb+1]} - let py=BIG::frombytes(&t); - if BIG::comp(&py,&p)>=0 {return ECP::new()} - return ECP::new_bigs(&px,&py); - } else {return ECP::new_big(&px)} - } - - pub fn to_hex(&self) -> String { - let mut ret: String = String::with_capacity(4 * 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) -> ECP { - let mut ret:ECP = ECP::new(); - if let Some(x) = iter.next() { - ret.inf = x == "true"; - ret.x = FP::from_hex_iter(iter); - ret.y = FP::from_hex_iter(iter); - ret.z = FP::from_hex_iter(iter); - } - return ret; - } - - pub fn from_hex(val: String) -> ECP { - let mut iter = val.split_whitespace(); - return ECP::from_hex_iter(&mut iter); - } - -/* convert to hex string */ - pub fn tostring(&mut self) -> String { - if self.is_infinity() {return String::from("infinity")} - self.affine(); - if rom::CURVETYPE==rom::MONTGOMERY { - return format!("({})",self.x.redc().tostring()); - } else {return format!("({},{})",self.x.redc().tostring(),self.y.redc().tostring())} ; - } - -/* this*=2 */ - pub fn dbl(&mut self) { - if rom::CURVETYPE==rom::WEIERSTRASS { - if self.inf {return} - if self.y.iszilch() { - self.inf(); - return; - } - - let mut w1=FP::new_copy(&self.x); - let mut w6=FP::new_copy(&self.z); - let mut w2=FP::new(); - let mut w3=FP::new_copy(&self.x); - let mut w8=FP::new_copy(&self.x); - - if rom::CURVE_A==-3 { - w6.sqr(); - w1.copy(&w6); - w1.neg(); - w3.add(&w1); - - w8.add(&w6); - - w3.mul(&mut w8); - w8.copy(&w3); - w8.imul(3); - } else { - 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(); - } - if rom::CURVETYPE==rom::EDWARDS { - let mut c=FP::new_copy(&self.x); - let mut d=FP::new_copy(&self.y); - let mut h=FP::new_copy(&self.z); - let mut j=FP::new(); - - self.x.mul(&mut self.y); self.x.dbl(); - c.sqr(); - d.sqr(); - if rom::CURVE_A == -1 {c.neg()} - self.y.copy(&c); self.y.add(&d); - self.y.norm(); - h.sqr(); h.dbl(); - self.z.copy(&self.y); - j.copy(&self.y); j.sub(&h); - self.x.mul(&mut j); - c.sub(&d); - self.y.mul(&mut c); - self.z.mul(&mut j); - - self.x.norm(); - self.y.norm(); - self.z.norm(); - } - if rom::CURVETYPE==rom::MONTGOMERY { - let mut a=FP::new_copy(&self.x); - let mut b=FP::new_copy(&self.x); - let mut aa=FP::new(); - let mut bb=FP::new(); - let mut c=FP::new(); - - if self.inf {return} - - a.add(&self.z); - aa.copy(&a); aa.sqr(); - b.sub(&self.z); - bb.copy(&b); bb.sqr(); - c.copy(&aa); c.sub(&bb); - - self.x.copy(&aa); self.x.mul(&mut bb); - - a.copy(&c); a.imul((rom::CURVE_A+2)/4); - - bb.add(&a); - self.z.copy(&bb); self.z.mul(&mut c); - self.x.norm(); - self.z.norm(); - } - return; - } - - /* self+=Q */ - pub fn add(&mut self,Q:&mut ECP) - { - if rom::CURVETYPE==rom::WEIERSTRASS { - if self.inf { - self.copy(&Q); - return; - } - if Q.inf {return} - - let mut aff=false; - - let mut one=FP::new_int(1); - if Q.z.equals(&mut one) {aff=true} - - let mut a=FP::new(); - let mut c=FP::new(); - let mut b=FP::new_copy(&self.z); - let mut d=FP::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; - } - else - { - self.inf=true; - return; - } - } - - if !aff {self.z.mul(&mut Q.z)} - self.z.mul(&mut b); - - let mut e=FP::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(); - } - if rom::CURVETYPE==rom::EDWARDS { - let mut bb=FP::new_big(&BIG::new_ints(&rom::CURVE_B)); - let mut a=FP::new_copy(&self.z); - let mut b=FP::new(); - let mut c=FP::new_copy(&self.x); - let mut d=FP::new_copy(&self.y); - let mut e=FP::new(); - let mut f=FP::new(); - let mut g=FP::new(); - - a.mul(&mut Q.z); - b.copy(&a); b.sqr(); - c.mul(&mut Q.x); - d.mul(&mut Q.y); - - e.copy(&c); e.mul(&mut d); e.mul(&mut bb); - f.copy(&b); f.sub(&e); - g.copy(&b); g.add(&e); - - if rom::CURVE_A==1 { - e.copy(&d); e.sub(&c); - } - c.add(&d); - - b.copy(&self.x); b.add(&self.y); - d.copy(&Q.x); d.add(&Q.y); - b.mul(&mut d); - b.sub(&c); - b.mul(&mut f); - self.x.copy(&a); self.x.mul(&mut b); - - if rom::CURVE_A==1 { - c.copy(&e); c.mul(&mut g); - } - if rom::CURVE_A == -1 { - c.mul(&mut g); - } - self.y.copy(&a); self.y.mul(&mut c); - self.z.copy(&f); self.z.mul(&mut g); - self.x.norm(); self.y.norm(); self.z.norm(); - } - return; - } - -/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */ - pub fn dadd(&mut self,Q: &ECP,W: &ECP) { - let mut a=FP::new_copy(&self.x); - let mut b=FP::new_copy(&self.x); - let mut c=FP::new_copy(&Q.x); - let mut d=FP::new_copy(&Q.x); - let mut da=FP::new(); - let mut cb=FP::new(); - - a.add(&self.z); - b.sub(&self.z); - - c.add(&Q.z); - d.sub(&Q.z); - - da.copy(&d); da.mul(&mut a); - cb.copy(&c); cb.mul(&mut b); - - a.copy(&da); a.add(&cb); a.sqr(); - b.copy(&da); b.sub(&cb); b.sqr(); - - self.x.copy(&a); - self.z.copy(&W.x); self.z.mul(&mut b); - - if self.z.iszilch() { - self.inf(); - } else {self.inf=false;} - - self.x.norm(); - } - -/* self-=Q */ - pub fn sub(&mut self,Q:&mut ECP) { - Q.neg(); - self.add(Q); - Q.neg(); - } - - fn multiaffine(P: &mut [ECP]) { - let mut t1=FP::new(); - let mut t2=FP::new(); - - let mut work:[FP;8]=[FP::new(),FP::new(),FP::new(),FP::new(),FP::new(),FP::new(),FP::new(),FP::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); - } - } - -/* constant time multiply by small integer of length bts - use ladder */ - pub fn pinmul(&mut self,e: i32,bts: i32) -> ECP { - if rom::CURVETYPE==rom::MONTGOMERY { - return self.mul(&mut BIG::new_int(e as isize)); - } else { - let mut P=ECP::new(); - let mut R0=ECP::new(); - let mut R1=ECP::new(); R1.copy(&self); - - for i in (0..bts).rev() { - let b=((e>>i)&1) as isize; - P.copy(&R1); - P.add(&mut R0); - R0.cswap(&mut R1,b); - R1.copy(&P); - R0.dbl(); - R0.cswap(&mut R1,b); - } - P.copy(&R0); - P.affine(); - return P; - } - } - -/* return e.self */ - - pub fn mul(&mut self,e:&mut BIG) -> ECP { - if e.iszilch() || self.is_infinity() {return ECP::new()} - let mut P=ECP::new(); - if rom::CURVETYPE==rom::MONTGOMERY { -/* use Ladder */ - let mut D=ECP::new(); - let mut R0=ECP::new(); R0.copy(&self); - let mut R1=ECP::new(); R1.copy(&self); - R1.dbl(); - D.copy(&self); D.affine(); - let nb=e.nbits(); - - for i in (0..nb-1).rev() { - let b=e.bit(i); - P.copy(&R1); - P.dadd(&mut R0,&D); - R0.cswap(&mut R1,b); - R1.copy(&P); - R0.dbl(); - R0.cswap(&mut R1,b); - } - P.copy(&R0) - } else { -// fixed size windows - let mut mt=BIG::new(); - let mut t=BIG::new(); - let mut Q=ECP::new(); - let mut C=ECP::new(); - - let mut W:[ECP;8]=[ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new()]; - - const CT:usize=1+(rom::NLEN*(rom::BASEBITS as usize)+3)/4; - let mut w:[i8;CT]=[0;CT]; - - self.affine(); - - 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 - if rom::CURVETYPE==rom::WEIERSTRASS { - ECP::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); /* apply correction */ - } - P.affine(); - return P; - } - -/* Return e.this+f.Q */ - - pub fn mul2(&mut self,e: &BIG,Q: &mut ECP,f: &BIG) -> ECP { - let mut te=BIG::new(); - let mut tf=BIG::new(); - let mut mt=BIG::new(); - let mut S=ECP::new(); - let mut T=ECP::new(); - let mut C=ECP::new(); - - let mut W:[ECP;8]=[ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new(),ECP::new()]; - - const CT:usize=1+(rom::NLEN*(rom::BASEBITS as usize)+1)/2; - let mut w: [i8;CT]=[0;CT]; - - self.affine(); - Q.affine(); - - te.copy(e); - tf.copy(f); - -// precompute table - - W[1].copy(&self); W[1].sub(Q); - W[2].copy(&self); W[2].add(Q); - S.copy(&Q); S.dbl(); - C.copy(&W[1]); W[0].copy(&C); W[0].sub(&mut S); // copy to C is stupid Rust thing.. - C.copy(&W[2]); W[3].copy(&C); W[3].add(&mut S); - T.copy(&self); T.dbl(); - C.copy(&W[1]); W[5].copy(&C); W[5].add(&mut T); - C.copy(&W[2]); W[6].copy(&C); W[6].add(&mut T); - C.copy(&W[5]); W[4].copy(&C); W[4].sub(&mut S); - C.copy(&W[6]); W[7].copy(&C); W[7].add(&mut S); - -// convert the table to affine - if rom::CURVETYPE==rom::WEIERSTRASS { - ECP::multiaffine(&mut W); - } - -// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction - - let mut s=te.parity(); - te.inc(1); te.norm(); let mut ns=te.parity(); mt.copy(&te); mt.inc(1); mt.norm(); - te.cmove(&mt,s); - T.cmove(&self,ns); - C.copy(&T); - - s=tf.parity(); - tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(&tf); mt.inc(1); mt.norm(); - tf.cmove(&mt,s); - S.cmove(&Q,ns); - C.add(&mut S); - - mt.copy(&te); mt.add(&tf); mt.norm(); - let nb=1+(mt.nbits()+1)/2; - -// convert exponent to signed 2-bit window - for i in 0..nb { - let a=te.lastbits(3)-4; - te.dec(a); te.norm(); - te.fshr(2); - let b=tf.lastbits(3)-4; - tf.dec(b); tf.norm(); - tf.fshr(2); - w[i]=(4*a+b) as i8; - } - w[nb]=(4*te.lastbits(3)+tf.lastbits(3)) as i8; - S.copy(&W[((w[nb] as usize)-1)/2]); - - for i in (0..nb).rev() { - T.selector(&W,w[i] as i32); - S.dbl(); - S.dbl(); - S.add(&mut T); - } - S.sub(&mut C); /* apply correction */ - S.affine(); - return S; - } - - -} -/* -fn main() -{ - let mut E=ECP::new(); - - let mut W:[&ECP;8]=[&ECP::new(),&ECP::new(),&ECP::new(),&ECP::new(),&ECP::new(),&ECP::new(),&ECP::new(),&ECP::new()]; - - let mut gx=BIG::new_ints(&rom::CURVE_GX); - let mut gy=BIG::new(); - let mut P=ECP::new(); - - if rom::CURVETYPE!=rom::MONTGOMERY {gy.copy(&BIG::new_ints(&rom::CURVE_GY))} - let mut r=BIG::new_ints(&rom::CURVE_ORDER); - - //r.dec(7); - - println!("gx= {}",gx.tostring()); - - if rom::CURVETYPE!=rom::MONTGOMERY { - println!("gy= {}",gy.tostring()); - } - - if rom::CURVETYPE!=rom::MONTGOMERY { - P.copy(&ECP::new_bigs(&gx,&gy))} - else {P.copy(&ECP::new_big(&gx))} - - println!("P= {}",P.tostring()); - - let mut R=P.mul(&mut r); - //for i in 0..10000 (R=P.mul(r)); - - println!("R= {}",R.tostring()); - -} -*/
