You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by km...@apache.org on 2020/05/05 06:38:46 UTC

[incubator-milagro-crypto-rust] branch develop updated (c492975 -> d8f3bb9)

This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git.


    from c492975  Merge pull request #23 from sigp/ecp-to-string
     new cc1b6e8  Update to hash to curve version 7
     new 1fd5b33  Add equality checks
     new 9a2581f  Merge branch 'standard-update' into hash-to-curve-07
     new d8f3bb9  Merge pull request #21 from sigp/hash-to-curve-07

The 44 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/bls381.rs                                      | 132 ++-------------------
 src/ecp.rs                                         |   2 +
 src/ecp2.rs                                        |   2 +
 src/fp.rs                                          |  23 ++--
 src/fp12.rs                                        |   2 +
 src/fp2.rs                                         |  19 ++-
 src/fp4.rs                                         |   2 +
 src/hash256.rs                                     |  10 +-
 src/hash384.rs                                     |  10 +-
 src/hash512.rs                                     |  10 +-
 src/hash_to_curve.rs                               |  87 ++++++++------
 src/roms/rom_bls381g1_32.rs                        |   4 +-
 src/roms/rom_bls381g1_64.rs                        |   6 +-
 src/roms/rom_bls381g2_32.rs                        |   6 +-
 src/roms/rom_bls381g2_64.rs                        |   6 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 src/test_utils/test_vector_structs.rs              |   1 -
 24 files changed, 331 insertions(+), 431 deletions(-)


[incubator-milagro-crypto-rust] 13/44: Remove binaries

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit f72e294615d2bdda7e22795e8b16b013f433f87b
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Dec 13 16:03:52 2019 +1100

    Remove binaries
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 BenchtestALL | Bin 5723448 -> 0 bytes
 TestALL      | Bin 6209648 -> 0 bytes
 TestBLS      | Bin 4990944 -> 0 bytes
 3 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/BenchtestALL b/BenchtestALL
deleted file mode 100755
index 0323393..0000000
Binary files a/BenchtestALL and /dev/null differ
diff --git a/TestALL b/TestALL
deleted file mode 100755
index 36a1426..0000000
Binary files a/TestALL and /dev/null differ
diff --git a/TestBLS b/TestBLS
deleted file mode 100755
index b248889..0000000
Binary files a/TestBLS and /dev/null differ


[incubator-milagro-crypto-rust] 07/44: Fix bn256CX and other minor issues

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit fcc4c3a08c89de23ec83c6009b934f5bb6c87931
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Thu Aug 8 15:05:29 2019 +1000

    Fix bn256CX and other minor issues
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 Cargo.toml | 12 ++++++------
 src/ff.rs  | 14 +++++++-------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index b3a8fa8..6596861 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,19 +15,19 @@ path = "src/lib.rs"
 
 [features]
 default = ["bn254"]
-bn254 = []
-bn254cx = []
-ansii = []
+anssi = []
 bls24 = []
 bls48 = []
 bls381 = []
 bls383 = []
 bls461 = []
+bn254 = []
+bn254CX = []
 brainpool = []
 c25519 = []
 c41417 = []
 ed25519 = []
-fp256Bn = []
+fp256BN = []
 fp512BN = []
 goldilocks = []
 hifive = []
@@ -40,7 +40,7 @@ nums384e = []
 nums384w = []
 nums512e = []
 nums512w = []
-secp256k1 = []
 rsa2048 = []
 rsa3072 = []
-rsa4096 = []
\ No newline at end of file
+rsa4096 = []
+secp256k1 = []
diff --git a/src/ff.rs b/src/ff.rs
index 54e7a32..90e7fdf 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -26,12 +26,12 @@ use rand::RAND;
 use super::super::arch::DChunk;
 
 /* Finite field support - for RSA, DH etc. */
-/* RSA/DH modulus length as multiple of BigBITS */
+/* RSA/DH modulus length as multiple of BIGBITS */
 
 pub use super::rom::FFLEN;
 //use std::str::SplitWhitespace;
 
-pub const FF_BITS: usize = (big::BigBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
+pub const FF_BITS: usize = (big::BIGBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
 pub const HFLEN: usize = (FFLEN / 2); /* Useful for half-size RSA private key operations */
 
 pub const P_MBITS: usize = (big::MODBYTES as usize) * 8;
@@ -142,7 +142,7 @@ impl FF {
         return true;
     }
 
-    /* shift right by BigBITS-bit words */
+    /* shift right by BIGBITS-bit words */
     pub fn shrw(&mut self, n: usize) {
         let mut t = Big::new();
         for i in 0..n {
@@ -152,7 +152,7 @@ impl FF {
         }
     }
 
-    /* shift left by BigBITS-bit words */
+    /* shift left by BIGBITS-bit words */
     pub fn shlw(&mut self, n: usize) {
         let mut t = Big::new();
         for i in 0..n {
@@ -548,7 +548,7 @@ impl FF {
         x.copy(&self);
         x.norm();
         m.dsucopy(&b);
-        let mut k = big::BigBITS * n;
+        let mut k = big::BIGBITS * n;
 
         while FF::comp(&x, &m) >= 0 {
             x.sub(&m);
@@ -793,7 +793,7 @@ impl FF {
 
         let mut i = 8 * (big::MODBYTES as usize) * n - 1;
         loop {
-            let b = (e.v[i / (big::BigBITS as usize)]).bit(i % (big::BigBITS as usize)) as isize;
+            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
             self.copy(&r0);
             self.modmul(&r1, p, &nd);
 
@@ -892,7 +892,7 @@ impl FF {
         let mut i = 8 * (big::MODBYTES as usize) * n - 1;
         loop {
             self.modsqr(p, &nd);
-            let b = (e.v[i / (big::BigBITS as usize)]).bit(i % (big::BigBITS as usize)) as isize;
+            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
             if b == 1 {
                 self.modmul(&w, p, &nd)
             }


[incubator-milagro-crypto-rust] 19/44: Add an all feature

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit b0b021d7d89fefd89a384f57661824205197c650
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Jan 21 11:20:23 2020 +1100

    Add an all feature
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 Cargo.toml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Cargo.toml b/Cargo.toml
index 6596861..259e89f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,6 +15,12 @@ path = "src/lib.rs"
 
 [features]
 default = ["bn254"]
+all = [
+  "anssi","bls24","bls48","bls381","bls383","bls461","bn254","bn254CX",
+  "brainpool","c25519","c41417","ed25519","fp256BN","fp512BN","goldilocks","hifive",
+  "nist256","nist384","nist521","nums256e","nums256w","nums384e","nums384w","nums512e",
+  "nums512w","rsa2048","rsa3072","rsa4096","secp256k1",
+]
 anssi = []
 bls24 = []
 bls48 = []


[incubator-milagro-crypto-rust] 31/44: Merge pull request #16 from sigp/fix-tests

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit d9bdc2fd415965e0923c26482a0ef6e9e97bdcd2
Merge: b114050 4a058c3
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Tue Mar 31 09:54:09 2020 +0100

    Merge pull request #16 from sigp/fix-tests
    
    Fix tests

 src/big.rs     |  12 ++---
 src/bls.rs     |   1 -
 src/bls192.rs  |   7 ++-
 src/bls256.rs  |   9 ++--
 src/ecdh.rs    |  28 ++++++------
 src/ff.rs      |  10 ++---
 src/fp.rs      |   2 +-
 src/mpin.rs    | 134 ++++++++++++++++++++++++++------------------------------
 src/mpin192.rs | 135 ++++++++++++++++++++++++++-------------------------------
 src/mpin256.rs | 135 ++++++++++++++++++++++++++-------------------------------
 src/nhs.rs     |   2 +-
 11 files changed, 217 insertions(+), 258 deletions(-)


[incubator-milagro-crypto-rust] 10/44: Add reference to Monty calculations and improve documentation for Big

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit f3fff8d4fa1956dd51acdb76fff17caf42caf6a2
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Aug 14 09:56:14 2019 +1000

    Add reference to Monty calculations and improve documentation for Big
---
 src/big.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 15 deletions(-)

diff --git a/src/big.rs b/src/big.rs
index a5424b2..8136873 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -391,34 +391,36 @@ impl Big {
         d
     }
 
-    // self -= x
+    /// self -= x
     pub fn sub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] -= x.w[i];
         }
     }
 
-    // reverse subtract this=x-this
+    /// reverse subtract this=x-this
     pub fn rsub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] = x.w[i] - self.w[i]
         }
     }
 
-    // self-=x, where x is int
+    /// 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
+    /// self*=x, where x is small int<NEXCESS
     pub fn imul(&mut self, c: isize) {
         for i in 0..NLEN {
             self.w[i] *= c as Chunk;
         }
     }
 
-    // convert this Big to byte array
+    /// To Byte Array
+    ///
+    /// Convert this Big to byte array from index `n`
     pub fn tobytearray(&mut self, b: &mut [u8], n: usize) {
         let mut c = Big::new_copy(self);
         c.norm();
@@ -429,7 +431,9 @@ impl Big {
         }
     }
 
-    // convert from byte array to Big
+    /// From Byte Array
+    ///
+    /// Convert from byte array starting at index `n` to Big
     pub fn frombytearray(b: &[u8], n: usize) -> Big {
         let mut m = Big::new();
         for i in 0..(MODBYTES as usize) {
@@ -439,10 +443,16 @@ impl Big {
         m
     }
 
+    /// To Bytes
+    ///
+    /// Convert to bytes from index 0
     pub fn tobytes(&mut self, b: &mut [u8]) {
         self.tobytearray(b, 0)
     }
 
+    /// From bytes
+    ///
+    /// Convert from bytes from index 0
     pub fn frombytes(b: &[u8]) -> Big {
         Big::frombytearray(b, 0)
     }
@@ -459,7 +469,7 @@ impl Big {
         carry
     }
 
-    // self*=c and catch overflow in DBig
+    /// 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;
@@ -472,7 +482,7 @@ impl Big {
         m
     }
 
-    // divide by 3
+    /// divide by 3
     pub fn div3(&mut self) -> Chunk {
         let mut carry = 0 as Chunk;
         self.norm();
@@ -485,7 +495,7 @@ impl Big {
         carry
     }
 
-    // return a*b where result fits in a Big
+    /// 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..NLEN {
@@ -501,7 +511,7 @@ impl Big {
         c
     }
 
-    // Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised
+    /// 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..NLEN).rev() {
             if a.w[i] == b.w[i] {
@@ -516,7 +526,7 @@ impl Big {
         0
     }
 
-    // set x = x mod 2^m
+    /// set x = x mod 2^m
     pub fn mod2m(&mut self, m: usize) {
         let wd = m / BASEBITS;
         let bt = m % BASEBITS;
@@ -527,7 +537,7 @@ impl Big {
         }
     }
 
-    // Arazi and Qi inversion mod 256
+    /// Arazi and Qi inversion mod 256
     pub fn invmod256(a: isize) -> isize {
         let mut t1: isize = 0;
         let mut c = (a >> 1) & 1;
@@ -571,7 +581,7 @@ impl Big {
         (self.w[0] % 2) as isize
     }
 
-    // Return n-th bit
+    /// Return n-th bit
     pub fn bit(&self, n: usize) -> isize {
         if (self.w[n / (BASEBITS as usize)] & (1 << (n % BASEBITS))) > 0 {
             return 1;
@@ -626,6 +636,8 @@ impl Big {
         self.norm();
     }
 
+    /// Reduciton with Modulus
+    ///
     /// reduce self mod m
     pub fn rmod(&mut self, n: &Big) {
         let mut k = 0;
@@ -657,7 +669,9 @@ impl Big {
         }
     }
 
-    /// Divide self by m
+    /// Division
+    ///
+    /// self = self / m
     pub fn div(&mut self, n: &Big) {
         let mut k = 0;
         self.norm();
@@ -690,13 +704,15 @@ impl Big {
         }
     }
 
+    /// Random
+    ///
     /// 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
 
+        // generate random Big
         for _ in 0..8 * (MODBYTES as usize) {
             if j == 0 {
                 r = rng.getbyte()
@@ -713,6 +729,8 @@ impl Big {
         m
     }
 
+    /// Random Number
+    ///
     /// 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();
@@ -779,6 +797,8 @@ impl Big {
         -1
     }
 
+    /// Inverse Modulus
+    ///
     /// self = 1/self mod p. Binary method
     pub fn invmodp(&mut self, p: &Big) {
         self.rmod(p);
@@ -837,6 +857,8 @@ impl Big {
         }
     }
 
+    /// Multiplication
+    ///
     /// return a*b as DBig
     pub fn mul(a: &Big, b: &Big) -> DBig {
         let mut c = DBig::new();
@@ -876,6 +898,8 @@ impl Big {
         c
     }
 
+    /// Square
+    ///
     /// return a^2 as DBig
     pub fn sqr(a: &Big) -> DBig {
         let mut c = DBig::new();
@@ -947,6 +971,8 @@ impl Big {
     }
 
     /// Montegomery Reduction
+    ///
+    /// https://eprint.iacr.org/2015/1247.pdf
     pub fn monty(md: &Big, mc: Chunk, d: &mut DBig) -> Big {
         let mut b = Big::new();
         let rm = BMASK as DChunk;
@@ -1008,6 +1034,8 @@ impl Big {
         ((r.w[n] >> (arch::CHUNK - 1)) & 1) as isize
     }
 
+    /// Modular Multiplication
+    ///
     /// return a*b mod m
     pub fn modmul(a1: &Big, b1: &Big, m: &Big) -> Big {
         let mut a = Big::new_copy(a1);
@@ -1026,6 +1054,8 @@ impl Big {
         d.dmod(m)
     }
 
+    /// Modular Negation
+    ///
     /// return -a mod m
     pub fn modneg(a1: &Big, m: &Big) -> Big {
         let mut a = Big::new_copy(a1);
@@ -1033,6 +1063,8 @@ impl Big {
         m.minus(&a)
     }
 
+    /// Raise to Power with Modulus
+    ///
     /// return this^e mod m
     pub fn powmod(&mut self, e1: &Big, m: &Big) -> Big {
         self.norm();


[incubator-milagro-crypto-rust] 33/44: Remove unecessary copying

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 0707ae6422c101a1113610112725419f4688964e
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Mon Apr 20 22:13:46 2020 +1000

    Remove unecessary copying
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/big.rs     |  91 +++------
 src/bls.rs     |   6 +-
 src/bls256.rs  |   6 +-
 src/dbig.rs    |  33 +--
 src/ecdh.rs    |  34 ++--
 src/ecp.rs     | 417 +++++++++++++++++---------------------
 src/ecp2.rs    | 231 ++++++++++-----------
 src/ecp4.rs    | 272 ++++++++++++-------------
 src/ecp8.rs    | 440 +++++++++++++++++++---------------------
 src/ff.rs      |  55 ++---
 src/fp.rs      | 134 ++++++------
 src/fp12.rs    | 448 ++++++++++++++++++----------------------
 src/fp16.rs    | 273 +++++++++++--------------
 src/fp2.rs     | 131 +++++-------
 src/fp24.rs    | 510 +++++++++++++++++++++-------------------------
 src/fp4.rs     | 308 +++++++++++++---------------
 src/fp48.rs    | 630 +++++++++++++++++++++++++++------------------------------
 src/fp8.rs     | 303 +++++++++++++--------------
 src/mpin.rs    |  23 +--
 src/mpin192.rs |  21 +-
 src/mpin256.rs |  21 +-
 src/nhs.rs     |   1 -
 src/pair.rs    | 284 +++++++++++---------------
 src/pair192.rs | 250 ++++++++++-------------
 src/pair256.rs | 322 ++++++++++++-----------------
 src/rsa.rs     |  10 +-
 26 files changed, 2340 insertions(+), 2914 deletions(-)

diff --git a/src/big.rs b/src/big.rs
index e4eca10..f0696c7 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -38,17 +38,11 @@ pub const HMASK: Chunk = (1 << HBITS) - 1;
 pub const NEXCESS: isize = 1 << (arch::CHUNK - BASEBITS - 1);
 pub const BIGBITS: usize = MODBYTES * 8;
 
-#[derive(Copy)]
+#[derive(Clone)]
 pub struct Big {
     pub w: [Chunk; NLEN],
 }
 
-impl Clone for Big {
-    fn clone(&self) -> Big {
-        *self
-    }
-}
-
 impl fmt::Display for Big {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "Big: [ {} ]", self.tostring())
@@ -109,15 +103,6 @@ impl Big {
         s
     }
 
-    /// Creates a copy of the Big
-    pub fn new_copy(y: &Big) -> Big {
-        let mut s = Big::new();
-        for i in 0..NLEN {
-            s.w[i] = y.w[i]
-        }
-        s
-    }
-
     pub fn new_dcopy(y: &DBig) -> Big {
         let mut s = Big::new();
         for i in 0..NLEN {
@@ -180,13 +165,6 @@ impl Big {
         }
     }
 
-    /// Copy from another Big
-    pub fn copy(&mut self, x: &Big) {
-        for i in 0..NLEN {
-            self.w[i] = x.w[i]
-        }
-    }
-
     /// Copy from a DBig
     pub fn dcopy(&mut self, x: &DBig) {
         for i in 0..NLEN {
@@ -289,7 +267,7 @@ impl Big {
     /// Return number of bits
     pub fn nbits(&self) -> usize {
         let mut k = NLEN - 1;
-        let mut s = Big::new_copy(&self);
+        let mut s = self.clone();
         s.norm();
         while (k as isize) >= 0 && s.w[k] == 0 {
             k = k.wrapping_sub(1)
@@ -323,7 +301,7 @@ impl Big {
         }
 
         for i in (0..len).rev() {
-            let mut b = Big::new_copy(&self);
+            let mut b = self.clone();
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
@@ -422,7 +400,7 @@ impl Big {
     ///
     /// Convert this Big to byte array from index `n`
     pub fn tobytearray(&self, b: &mut [u8], n: usize) {
-        let mut c = Big::new_copy(self);
+        let mut c = self.clone();
         c.norm();
 
         for i in (0..(MODBYTES as usize)).rev() {
@@ -599,19 +577,16 @@ impl Big {
     /// 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 < BIGBITS {
             u.norm();
-            b.copy(self);
+            let mut b = self.clone();
             b.mod2m(i);
             let mut t1 = Big::smul(&u, &b);
             t1.shr(i);
-            c.copy(self);
+            let mut c = self.clone();
             c.shr(i);
             c.mod2m(i);
 
@@ -620,7 +595,7 @@ impl Big {
             t1.add(&t2);
             t1.norm();
             b = Big::smul(&t1, &u);
-            t1.copy(&b);
+            t1 = b.clone();
             t1.mod2m(i);
 
             t2.one();
@@ -632,7 +607,7 @@ impl Big {
             i <<= 1;
         }
         u.mod2m(BIGBITS);
-        self.copy(&u);
+        *self = u;
         self.norm();
     }
 
@@ -641,7 +616,7 @@ impl Big {
     /// reduce self mod m
     pub fn rmod(&mut self, n: &Big) {
         let mut k = 0;
-        let mut m = Big::new_copy(n);
+        let mut m = n.clone();
         let mut r = Big::new();
         self.norm();
         if Big::comp(self, &m) < 0 {
@@ -658,7 +633,7 @@ impl Big {
         while k > 0 {
             m.fshr(1);
 
-            r.copy(self);
+            r = self.clone();
             r.sub(&m);
             r.norm();
             self.cmove(
@@ -676,8 +651,8 @@ impl 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 b = self.clone();
+        let mut m = n.clone();
         let mut r = Big::new();
         self.zero();
 
@@ -691,12 +666,12 @@ impl Big {
             m.fshr(1);
             e.fshr(1);
 
-            r.copy(&b);
+            r = b.clone();
             r.sub(&m);
             r.norm();
             let d = (1 - ((r.w[NLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
             b.cmove(&r, d);
-            r.copy(self);
+            r = self.clone();
             r.add(&e);
             r.norm();
             self.cmove(&r, d);
@@ -736,7 +711,7 @@ impl Big {
         let mut d = DBig::new();
         let mut j = 0;
         let mut r: u8 = 0;
-        let t = Big::new_copy(q);
+        let t = q.clone();
         for _ in 0..2 * t.nbits() {
             if j == 0 {
                 r = rng.getbyte();
@@ -767,8 +742,8 @@ impl Big {
         }
         self.norm();
 
-        x.copy(self);
-        n.copy(p);
+        x = self.clone();
+        n = p.clone();
         x.rmod(p);
 
         while Big::comp(&n, &one) > 0 {
@@ -785,10 +760,10 @@ impl Big {
                 m += (n8 * n8 - 1) / 8
             }
             m += (n8 - 1) * ((x.lastbits(2) as usize) - 1) / 4;
-            t.copy(&n);
+            t = n.clone();
             t.rmod(&x);
-            n.copy(&x);
-            x.copy(&t);
+            n = x.clone();
+            x = t.clone();
             m %= 2;
         }
         if m == 0 {
@@ -802,8 +777,8 @@ impl Big {
     /// 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 u = self.clone();
+        let mut v = p.clone();
         let mut x1 = Big::new_int(1);
         let mut x2 = Big::new();
         let mut t = Big::new();
@@ -832,7 +807,7 @@ impl Big {
                 if Big::comp(&x1, &x2) >= 0 {
                     x1.sub(&x2)
                 } else {
-                    t.copy(p);
+                    t = p.clone();
                     t.sub(&x2);
                     x1.add(&t);
                 }
@@ -843,7 +818,7 @@ impl Big {
                 if Big::comp(&x2, &x1) >= 0 {
                     x2.sub(&x1)
                 } else {
-                    t.copy(p);
+                    t = p.clone();
                     t.sub(&x1);
                     x2.add(&t);
                 }
@@ -851,9 +826,9 @@ impl Big {
             }
         }
         if Big::comp(&u, &one) == 0 {
-            self.copy(&x1)
+            *self = x1
         } else {
-            self.copy(&x2)
+            *self = x2
         }
     }
 
@@ -1038,8 +1013,8 @@ impl Big {
     ///
     /// return a*b mod m
     pub fn modmul(a1: &Big, b1: &Big, m: &Big) -> Big {
-        let mut a = Big::new_copy(a1);
-        let mut b = Big::new_copy(b1);
+        let mut a = a1.clone();
+        let mut b = b1.clone();
         a.rmod(m);
         b.rmod(m);
         let mut d = Big::mul(&a, &b);
@@ -1048,7 +1023,7 @@ impl Big {
 
     /// return a^2 mod m
     pub fn modsqr(a1: &Big, m: &Big) -> Big {
-        let mut a = Big::new_copy(a1);
+        let mut a = a1.clone();
         a.rmod(m);
         let mut d = Big::sqr(&a);
         d.dmod(m)
@@ -1058,7 +1033,7 @@ impl Big {
     ///
     /// return -a mod m
     pub fn modneg(a1: &Big, m: &Big) -> Big {
-        let mut a = Big::new_copy(a1);
+        let mut a = a1.clone();
         a.rmod(m);
         m.minus(&a)
     }
@@ -1068,11 +1043,11 @@ impl Big {
     /// return this^e mod m
     pub fn powmod(&mut self, e1: &Big, m: &Big) -> Big {
         self.norm();
-        let mut e = Big::new_copy(e1);
+        let mut e = e1.clone();
         e.norm();
         let mut a = Big::new_int(1);
-        let mut z = Big::new_copy(&e);
-        let mut s = Big::new_copy(self);
+        let mut z = e.clone();
+        let mut s = self.clone();
         loop {
             let bt = z.parity();
             z.fshr(1);
diff --git a/src/bls.rs b/src/bls.rs
index 1bc71cb..c956441 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::ecp::ECP;
-use super::ecp2::ECP2;
-use std::str;
 use super::big;
 use super::big::Big;
+use super::ecp::ECP;
+use super::ecp2::ECP2;
 use super::pair;
 use super::rom;
+use std::str;
 
 use rand::RAND;
 use sha3::SHA3;
diff --git a/src/bls256.rs b/src/bls256.rs
index 11fb5a1..785ad2d 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::ecp::ECP;
-use super::ecp8::ECP8;
-use std::str;
 use super::big;
 use super::big::Big;
+use super::ecp::ECP;
+use super::ecp8::ECP8;
 use super::pair256;
 use super::rom;
+use std::str;
 
 use rand::RAND;
 use sha3::SHA3;
diff --git a/src/dbig.rs b/src/dbig.rs
index 2479637..689aeb8 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -22,17 +22,11 @@ use super::super::arch::Chunk;
 use super::big;
 use super::big::Big;
 
-#[derive(Copy)]
+#[derive(Clone)]
 pub struct DBig {
     pub w: [Chunk; big::DNLEN],
 }
 
-impl Clone for DBig {
-    fn clone(&self) -> DBig {
-        *self
-    }
-}
-
 impl DBig {
     pub fn new() -> DBig {
         DBig {
@@ -40,14 +34,6 @@ impl DBig {
         }
     }
 
-    pub fn new_copy(y: &DBig) -> DBig {
-        let mut s = DBig::new();
-        for i in 0..big::DNLEN {
-            s.w[i] = y.w[i]
-        }
-        s
-    }
-
     pub fn new_scopy(x: &Big) -> DBig {
         let mut b = DBig::new();
         for i in 0..big::NLEN {
@@ -108,13 +94,6 @@ impl DBig {
         }
     }
 
-    /// Copy from another DBig
-    pub fn copy(&mut self, x: &DBig) {
-        for i in 0..big::DNLEN {
-            self.w[i] = x.w[i];
-        }
-    }
-
     /// Copy from a Big
     pub fn ucopy(&mut self, x: &Big) {
         for i in 0..big::NLEN {
@@ -202,7 +181,7 @@ impl DBig {
         while k > 0 {
             m.shr(1);
 
-            dr.copy(self);
+            dr = self.clone();
             dr.sub(&m);
             dr.norm();
             self.cmove(
@@ -236,12 +215,12 @@ impl DBig {
             m.shr(1);
             e.shr(1);
 
-            dr.copy(self);
+            dr = self.clone();
             dr.sub(&m);
             dr.norm();
             let d = (1 - ((dr.w[big::DNLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
             self.cmove(&dr, d);
-            r.copy(&a);
+            r = a.clone();
             r.add(&e);
             r.norm();
             a.cmove(&r, d);
@@ -265,7 +244,7 @@ impl DBig {
     /// Return number of bits
     pub fn nbits(&self) -> usize {
         let mut k = big::DNLEN - 1;
-        let mut s = DBig::new_copy(&self);
+        let mut s = self.clone();
         s.norm();
         while (k as isize) >= 0 && s.w[k] == 0 {
             k = k.wrapping_sub(1)
@@ -295,7 +274,7 @@ impl DBig {
         }
 
         for i in (0..len).rev() {
-            let mut b = DBig::new_copy(&self);
+            let mut b = self.clone();
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 934ea82..0772ee7 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -226,7 +226,7 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
 /// 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
+    // 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];
@@ -505,34 +505,32 @@ pub fn ecpsp_dsa(
 
     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 w = Big::randomnum(&r, rng); // side channel masking
 
-        V.copy(&G);
+        let mut V = G.clone();
         V = V.mul(&u);
         let vx = V.getx();
-        cb.copy(&vx);
+        cb = vx.clone();
         cb.rmod(&r);
         if cb.iszilch() {
             continue;
         }
 
-        tb.copy(&Big::modmul(&u, &w, &r));
-        u.copy(&tb);
+        let mut tb = Big::modmul(&u, &w, &r);
+        u = tb.clone();
 
         u.invmodp(&r);
-        db.copy(&Big::modmul(&sc, &cb, &r));
+        db = Big::modmul(&sc, &cb, &r);
         db.add(&fb);
 
-        tb.copy(&Big::modmul(&db, &w, &r));
-        db.copy(&tb);
+        tb = Big::modmul(&db, &w, &r);
+        db = tb.clone();
 
-        tb.copy(&Big::modmul(&u, &db, &r));
-        db.copy(&tb);
+        tb = Big::modmul(&u, &db, &r);
+        db = tb.clone();
     }
 
     cb.tobytes(&mut t);
@@ -556,30 +554,27 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
     hashit(sha, f, 0, None, big::MODBYTES as usize, &mut b);
 
     let G = ECP::generator();
-
     let r = Big::new_ints(&rom::CURVE_ORDER);
 
     let 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 {
+        let mut fb = Big::frombytes(&b);
         db.invmodp(&r);
-        tb.copy(&Big::modmul(&fb, &db, &r));
-        fb.copy(&tb);
+        let tb = Big::modmul(&fb, &db, &r);
+        fb = tb.clone();
         let h2 = Big::modmul(&cb, &db, &r);
 
         let WP = ECP::frombytes(&w);
         if WP.is_infinity() {
             res = ERROR;
         } else {
-            let mut P = ECP::new();
-            P.copy(&WP);
+            let mut P = WP.clone();
 
             P = P.mul2(&h2, &G, &fb);
 
@@ -754,7 +749,6 @@ mod tests {
 
     #[test]
     fn test_ecdh() {
-
         let mut rng = create_rng();
 
         let pw = "M0ng00se";
diff --git a/src/ecp.rs b/src/ecp.rs
index 07e19be..2c9b9db 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -27,7 +27,7 @@ use std::fmt;
 use std::str::SplitWhitespace;
 pub use types::CurveType;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct ECP {
     x: FP,
     y: FP,
@@ -83,7 +83,7 @@ impl ECP {
                 E.inf();
             }
         } else {
-            let mut y2 = FP::new_copy(&E.y);
+            let mut y2 = E.y.clone();
             y2.sqr();
             if !y2.equals(&rhs) {
                 E.inf();
@@ -106,11 +106,11 @@ impl ECP {
             if ny.redc().parity() != s {
                 ny.neg()
             }
-            E.y.copy(&ny);
+            E.y = ny;
         } else {
             E.inf()
         }
-        return E;
+        E
     }
 
     #[allow(non_snake_case)]
@@ -123,7 +123,7 @@ impl ECP {
         let mut rhs = ECP::rhs(&E.x);
         if rhs.jacobi() == 1 {
             if CURVETYPE != CurveType::Montgomery {
-                E.y.copy(&rhs.sqrt())
+                E.y = rhs.sqrt()
             }
         } else {
             E.inf();
@@ -146,15 +146,15 @@ impl ECP {
 
     /* Calculate RHS of curve equation */
     fn rhs(x: &FP) -> FP {
-        let mut r = FP::new_copy(x);
+        let mut r = x.clone();
         r.sqr();
 
         if CURVETYPE == CurveType::Weierstrass {
             // x^3+Ax+B
-            let b = FP::new_big(&Big::new_ints(&rom::CURVE_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);
+                let mut cx = x.clone();
                 cx.imul(3);
                 cx.neg();
                 cx.norm();
@@ -164,7 +164,7 @@ impl ECP {
         }
         if CURVETYPE == CurveType::Edwards {
             // (Ax^2-1)/(Bx^2-1)
-            let mut b = FP::new_big(&Big::new_ints(&rom::CURVE_B));
+            let mut b = FP::new_big(Big::new_ints(&rom::CURVE_B));
             let one = FP::new_int(1);
             b.mul(&r);
             b.sub(&one);
@@ -179,8 +179,7 @@ impl ECP {
         }
         if CURVETYPE == CurveType::Montgomery {
             // x^3+Ax^2+x
-            let mut x3 = FP::new();
-            x3.copy(&r);
+            let mut x3 = r.clone();
             x3.mul(x);
             r.imul(rom::CURVE_A);
             r.add(&x3);
@@ -224,15 +223,6 @@ impl ECP {
         return ((x >> 31) & 1) as isize;
     }
 
-    /* this=P */
-    pub fn copy(&mut self, P: &ECP) {
-        self.x.copy(&P.x);
-        if CURVETYPE != CurveType::Montgomery {
-            self.y.copy(&P.y)
-        }
-        self.z.copy(&P.z);
-    }
-
     /* this=-this */
     pub fn neg(&mut self) {
         if CURVETYPE == CurveType::Weierstrass {
@@ -252,8 +242,6 @@ impl ECP {
 
     /* 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;
 
@@ -268,26 +256,24 @@ impl ECP {
         self.cmove(&W[6], ECP::teq(babs, 6));
         self.cmove(&W[7], ECP::teq(babs, 7));
 
-        MP.copy(self);
+        let mut MP = self.clone();
         MP.neg();
         self.cmove(&MP, (m & 1) as isize);
     }
 
     /* Test P == Q */
     pub fn equals(&self, Q: &ECP) -> bool {
-        let mut a = FP::new();
-        let mut b = FP::new();
-        a.copy(&self.x);
+        let mut a = self.getpx();
         a.mul(&Q.z);
-        b.copy(&Q.x);
+        let mut b = Q.getpx();
         b.mul(&self.z);
         if !a.equals(&b) {
             return false;
         }
         if CURVETYPE != CurveType::Montgomery {
-            a.copy(&self.y);
+            a = self.getpy();
             a.mul(&Q.z);
-            b.copy(&Q.y);
+            b = Q.getpy();
             b.mul(&self.z);
             if !a.equals(&b) {
                 return false;
@@ -313,21 +299,19 @@ impl ECP {
             self.y.mul(&self.z);
             self.y.reduce();
         }
-        self.z.copy(&one);
+        self.z = one;
     }
 
     /* extract x as a Big */
     pub fn getx(&self) -> Big {
-        let mut W = ECP::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
         return W.x.redc();
     }
 
     /* extract y as a Big */
     pub fn gety(&self) -> Big {
-        let mut W = ECP::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
         return W.y.redc();
     }
@@ -340,27 +324,23 @@ impl ECP {
 
     /* extract x as an FP */
     pub fn getpx(&self) -> FP {
-        let w = FP::new_copy(&self.x);
-        return w;
+        self.x.clone()
     }
     /* extract y as an FP */
     pub fn getpy(&self) -> FP {
-        let w = FP::new_copy(&self.y);
-        return w;
+        self.y.clone()
     }
 
     /* extract z as an FP */
     pub fn getpz(&self) -> FP {
-        let w = FP::new_copy(&self.z);
-        return w;
+        self.z.clone()
     }
 
     /* convert to byte array */
     pub fn tobytes(&self, b: &mut [u8], compress: bool) {
         let mb = big::MODBYTES as usize;
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
-        let mut W = ECP::new();
-        W.copy(self);
+        let mut W = self.clone();
 
         W.affine();
         W.x.redc().tobytes(&mut t);
@@ -427,8 +407,7 @@ impl ECP {
 
     /* convert to hex string */
     pub fn tostring(&self) -> String {
-        let mut W = ECP::new();
-        W.copy(self);
+        let W = self.clone();
         if W.is_infinity() {
             return String::from("infinity");
         }
@@ -465,14 +444,14 @@ impl ECP {
     pub fn dbl(&mut self) {
         if CURVETYPE == CurveType::Weierstrass {
             if rom::CURVE_A == 0 {
-                let mut t0 = FP::new_copy(&self.y);
+                let mut t0 = self.y.clone();
                 t0.sqr();
-                let mut t1 = FP::new_copy(&self.y);
+                let mut t1 = self.y.clone();
                 t1.mul(&self.z);
-                let mut t2 = FP::new_copy(&self.z);
+                let mut t2 = self.z.clone();
                 t2.sqr();
 
-                self.z.copy(&t0);
+                self.z = t0.clone();
                 self.z.add(&t0);
                 self.z.norm();
                 self.z.dbl();
@@ -480,41 +459,39 @@ impl ECP {
                 self.z.norm();
                 t2.imul(3 * rom::CURVE_B_I);
 
-                let mut x3 = FP::new_copy(&t2);
+                let mut x3 = t2.clone();
                 x3.mul(&self.z);
 
-                let mut y3 = FP::new_copy(&t0);
+                let mut y3 = t0.clone();
                 y3.add(&t2);
                 y3.norm();
                 self.z.mul(&t1);
-                t1.copy(&t2);
+                t1 = t2.clone();
                 t1.add(&t2);
                 t2.add(&t1);
                 t0.sub(&t2);
                 t0.norm();
                 y3.mul(&t0);
                 y3.add(&x3);
-                t1.copy(&self.x);
+                t1 = self.getpx();
                 t1.mul(&self.y);
-                self.x.copy(&t0);
+                self.x = t0.clone();
                 self.x.norm();
                 self.x.mul(&t1);
                 self.x.dbl();
                 self.x.norm();
-                self.y.copy(&y3);
+                self.y = y3.clone();
                 self.y.norm();
             } else {
-                let mut t0 = FP::new_copy(&self.x);
-                let mut t1 = FP::new_copy(&self.y);
-                let mut t2 = FP::new_copy(&self.z);
-                let mut t3 = FP::new_copy(&self.x);
-                let mut z3 = FP::new_copy(&self.z);
-                let mut y3 = FP::new();
-                let mut x3 = FP::new();
+                let mut t0 = self.x.clone();
+                let mut t1 = self.y.clone();
+                let mut t2 = self.z.clone();
+                let mut t3 = self.x.clone();
+                let mut z3 = self.z.clone();
                 let mut b = FP::new();
 
                 if rom::CURVE_B_I == 0 {
-                    b.copy(&FP::new_big(&Big::new_ints(&rom::CURVE_B)));
+                    b = FP::new_big(Big::new_ints(&rom::CURVE_B));
                 }
 
                 t0.sqr(); //1    x^2
@@ -527,7 +504,7 @@ impl ECP {
                 z3.mul(&self.x); //6
                 z3.dbl();
                 z3.norm(); //7
-                y3.copy(&t2);
+                let mut y3 = t2.clone();
 
                 if rom::CURVE_B_I == 0 {
                     y3.mul(&b); //8
@@ -536,19 +513,19 @@ impl ECP {
                 }
 
                 y3.sub(&z3); //9  ***
-                x3.copy(&y3);
+                let mut x3 = y3.clone();
                 x3.add(&y3);
                 x3.norm(); //10
 
                 y3.add(&x3); //11
-                x3.copy(&t1);
+                x3 = t1.clone();
                 x3.sub(&y3);
                 x3.norm(); //12
                 y3.add(&t1);
                 y3.norm(); //13
                 y3.mul(&x3); //14
                 x3.mul(&t3); //15
-                t3.copy(&t2);
+                t3 = t2.clone();
                 t3.add(&t2); //16
                 t2.add(&t3); //17
 
@@ -561,12 +538,12 @@ impl ECP {
                 z3.sub(&t2); //19
                 z3.sub(&t0);
                 z3.norm(); //20  ***
-                t3.copy(&z3);
+                t3 = z3.clone();
                 t3.add(&z3); //21
 
                 z3.add(&t3);
                 z3.norm(); //22
-                t3.copy(&t0);
+                t3 = t0.clone();
                 t3.add(&t0); //23
                 t0.add(&t3); //24
                 t0.sub(&t2);
@@ -574,7 +551,7 @@ impl ECP {
 
                 t0.mul(&z3); //26
                 y3.add(&t0); //27
-                t0.copy(&self.y);
+                t0 = self.getpy();
                 t0.mul(&self.z); //28
                 t0.dbl();
                 t0.norm(); //29
@@ -584,22 +561,21 @@ impl ECP {
                 t0.norm(); //32
                 t1.dbl();
                 t1.norm(); //33
-                z3.copy(&t0);
+                z3 = t0.clone();
                 z3.mul(&t1); //34
 
-                self.x.copy(&x3);
+                self.x = x3.clone();
                 self.x.norm();
-                self.y.copy(&y3);
+                self.y = y3.clone();
                 self.y.norm();
-                self.z.copy(&z3);
+                self.z = z3.clone();
                 self.z.norm();
             }
         }
         if CURVETYPE == CurveType::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();
+            let mut c = self.x.clone();
+            let mut d = self.y.clone();
+            let mut h = self.z.clone();
 
             self.x.mul(&self.y);
             self.x.dbl();
@@ -609,13 +585,13 @@ impl ECP {
             if rom::CURVE_A == -1 {
                 c.neg()
             }
-            self.y.copy(&c);
+            self.y = c.clone();
             self.y.add(&d);
             self.y.norm();
             h.sqr();
             h.dbl();
-            self.z.copy(&self.y);
-            j.copy(&self.y);
+            self.z = self.getpy();
+            let mut j = self.getpy();
             j.sub(&h);
             j.norm();
             self.x.mul(&j);
@@ -625,36 +601,32 @@ impl ECP {
             self.z.mul(&j);
         }
         if CURVETYPE == CurveType::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();
+            let mut a = self.x.clone();
+            let mut b = self.x.clone();
 
             a.add(&self.z);
             a.norm();
-            aa.copy(&a);
+            let mut aa = a.clone();
             aa.sqr();
             b.sub(&self.z);
             b.norm();
-            bb.copy(&b);
+            let mut bb = b.clone();
             bb.sqr();
-            c.copy(&aa);
+            let mut c = aa.clone();
             c.sub(&bb);
             c.norm();
 
-            self.x.copy(&aa);
+            self.x = aa.clone();
             self.x.mul(&bb);
 
-            a.copy(&c);
+            a = c.clone();
             a.imul((rom::CURVE_A + 2) / 4);
 
             bb.add(&a);
             bb.norm();
-            self.z.copy(&bb);
+            self.z = bb;
             self.z.mul(&c);
         }
-        return;
     }
 
     /* self+=Q */
@@ -662,64 +634,64 @@ impl ECP {
         if CURVETYPE == CurveType::Weierstrass {
             if rom::CURVE_A == 0 {
                 let b = 3 * rom::CURVE_B_I;
-                let mut t0 = FP::new_copy(&self.x);
+                let mut t0 = self.x.clone();
                 t0.mul(&Q.x);
-                let mut t1 = FP::new_copy(&self.y);
+                let mut t1 = self.y.clone();
                 t1.mul(&Q.y);
-                let mut t2 = FP::new_copy(&self.z);
+                let mut t2 = self.z.clone();
                 t2.mul(&Q.z);
-                let mut t3 = FP::new_copy(&self.x);
+                let mut t3 = self.x.clone();
                 t3.add(&self.y);
                 t3.norm();
-                let mut t4 = FP::new_copy(&Q.x);
+                let mut t4 = Q.x.clone();
                 t4.add(&Q.y);
                 t4.norm();
                 t3.mul(&t4);
-                t4.copy(&t0);
+                t4 = t0.clone();
                 t4.add(&t1);
 
                 t3.sub(&t4);
                 t3.norm();
-                t4.copy(&self.y);
+                t4 = self.getpy();
                 t4.add(&self.z);
                 t4.norm();
-                let mut x3 = FP::new_copy(&Q.y);
+                let mut x3 = Q.y.clone();
                 x3.add(&Q.z);
                 x3.norm();
 
                 t4.mul(&x3);
-                x3.copy(&t1);
+                x3 = t1.clone();
                 x3.add(&t2);
 
                 t4.sub(&x3);
                 t4.norm();
-                x3.copy(&self.x);
+                x3 = self.getpx();
                 x3.add(&self.z);
                 x3.norm();
-                let mut y3 = FP::new_copy(&Q.x);
+                let mut y3 = Q.x.clone();
                 y3.add(&Q.z);
                 y3.norm();
                 x3.mul(&y3);
-                y3.copy(&t0);
+                y3 = t0.clone();
                 y3.add(&t2);
                 y3.rsub(&x3);
                 y3.norm();
-                x3.copy(&t0);
+                x3 = t0.clone();
                 x3.add(&t0);
                 t0.add(&x3);
                 t0.norm();
                 t2.imul(b);
 
-                let mut z3 = FP::new_copy(&t1);
+                let mut z3 = t1.clone();
                 z3.add(&t2);
                 z3.norm();
                 t1.sub(&t2);
                 t1.norm();
                 y3.imul(b);
 
-                x3.copy(&y3);
+                x3 = y3.clone();
                 x3.mul(&t4);
-                t2.copy(&t3);
+                t2 = t3.clone();
                 t2.mul(&t1);
                 x3.rsub(&t2);
                 y3.mul(&t0);
@@ -729,25 +701,24 @@ impl ECP {
                 z3.mul(&t4);
                 z3.add(&t0);
 
-                self.x.copy(&x3);
+                self.x = x3.clone();
                 self.x.norm();
-                self.y.copy(&y3);
+                self.y = y3.clone();
                 self.y.norm();
-                self.z.copy(&z3);
+                self.z = z3.clone();
                 self.z.norm();
             } else {
-                let mut t0 = FP::new_copy(&self.x);
-                let mut t1 = FP::new_copy(&self.y);
-                let mut t2 = FP::new_copy(&self.z);
-                let mut t3 = FP::new_copy(&self.x);
-                let mut t4 = FP::new_copy(&Q.x);
-                let mut z3 = FP::new();
-                let mut y3 = FP::new_copy(&Q.x);
-                let mut x3 = FP::new_copy(&Q.y);
+                let mut t0 = self.x.clone();
+                let mut t1 = self.y.clone();
+                let mut t2 = self.z.clone();
+                let mut t3 = self.x.clone();
+                let mut t4 = Q.x.clone();
+                let mut y3 = Q.x.clone();
+                let mut x3 = Q.y.clone();
                 let mut b = FP::new();
 
                 if rom::CURVE_B_I == 0 {
-                    b.copy(&FP::new_big(&Big::new_ints(&rom::CURVE_B)));
+                    b = FP::new_big(Big::new_ints(&rom::CURVE_B));
                 }
 
                 t0.mul(&Q.x); //1
@@ -759,34 +730,34 @@ impl ECP {
                 t4.add(&Q.y);
                 t4.norm(); //5
                 t3.mul(&t4); //6
-                t4.copy(&t0);
+                t4 = t0.clone();
                 t4.add(&t1); //7
                 t3.sub(&t4);
                 t3.norm(); //8
-                t4.copy(&self.y);
+                t4 = self.getpy();
                 t4.add(&self.z);
                 t4.norm(); //9
                 x3.add(&Q.z);
                 x3.norm(); //10
                 t4.mul(&x3); //11
-                x3.copy(&t1);
+                x3 = t1.clone();
                 x3.add(&t2); //12
 
                 t4.sub(&x3);
                 t4.norm(); //13
-                x3.copy(&self.x);
+                x3 = self.getpx();
                 x3.add(&self.z);
                 x3.norm(); //14
                 y3.add(&Q.z);
                 y3.norm(); //15
 
                 x3.mul(&y3); //16
-                y3.copy(&t0);
+                y3 = t0.clone();
                 y3.add(&t2); //17
 
                 y3.rsub(&x3);
                 y3.norm(); //18
-                z3.copy(&t2);
+                let mut z3 = t2.clone();
 
                 if rom::CURVE_B_I == 0 {
                     z3.mul(&b); //18
@@ -794,14 +765,14 @@ impl ECP {
                     z3.imul(rom::CURVE_B_I);
                 }
 
-                x3.copy(&y3);
+                x3 = y3.clone();
                 x3.sub(&z3);
                 x3.norm(); //20
-                z3.copy(&x3);
+                z3 = x3.clone();
                 z3.add(&x3); //21
 
                 x3.add(&z3); //22
-                z3.copy(&t1);
+                z3 = t1.clone();
                 z3.sub(&x3);
                 z3.norm(); //23
                 x3.add(&t1);
@@ -813,7 +784,7 @@ impl ECP {
                     y3.imul(rom::CURVE_B_I);
                 }
 
-                t1.copy(&t2);
+                t1 = t2.clone();
                 t1.add(&t2); //t1.norm();//26
                 t2.add(&t1); //27
 
@@ -821,70 +792,66 @@ impl ECP {
 
                 y3.sub(&t0);
                 y3.norm(); //29
-                t1.copy(&y3);
+                t1 = y3.clone();
                 t1.add(&y3); //30
                 y3.add(&t1);
                 y3.norm(); //31
 
-                t1.copy(&t0);
+                t1 = t0.clone();
                 t1.add(&t0); //32
                 t0.add(&t1); //33
                 t0.sub(&t2);
                 t0.norm(); //34
-                t1.copy(&t4);
+                t1 = t4.clone();
                 t1.mul(&y3); //35
-                t2.copy(&t0);
+                t2 = t0.clone();
                 t2.mul(&y3); //36
-                y3.copy(&x3);
+                y3 = x3.clone();
                 y3.mul(&z3); //37
                 y3.add(&t2); //y3.norm();//38
                 x3.mul(&t3); //39
                 x3.sub(&t1); //40
                 z3.mul(&t4); //41
-                t1.copy(&t3);
+                t1 = t3.clone();
                 t1.mul(&t0); //42
                 z3.add(&t1);
-                self.x.copy(&x3);
+                self.x = x3.clone();
                 self.x.norm();
-                self.y.copy(&y3);
+                self.y = y3.clone();
                 self.y.norm();
-                self.z.copy(&z3);
+                self.z = z3.clone();
                 self.z.norm();
             }
         }
         if CURVETYPE == CurveType::Edwards {
-            let 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();
+            let bb = FP::new_big(Big::new_ints(&rom::CURVE_B));
+            let mut a = self.z.clone();
+            let mut c = self.x.clone();
+            let mut d = self.y.clone();
 
             a.mul(&Q.z);
-            b.copy(&a);
+            let mut b = a.clone();
             b.sqr();
             c.mul(&Q.x);
             d.mul(&Q.y);
 
-            e.copy(&c);
+            let mut e = c.clone();
             e.mul(&d);
             e.mul(&bb);
-            f.copy(&b);
+            let mut f = b.clone();
             f.sub(&e);
-            g.copy(&b);
+            let mut g = b.clone();
             g.add(&e);
 
             if rom::CURVE_A == 1 {
-                e.copy(&d);
+                e = d.clone();
                 e.sub(&c);
             }
             c.add(&d);
 
-            b.copy(&self.x);
+            b = self.getpx();
             b.add(&self.y);
-            d.copy(&Q.x);
+            d = Q.getpx();
             d.add(&Q.y);
             b.norm();
             d.norm();
@@ -893,21 +860,21 @@ impl ECP {
             b.norm();
             f.norm();
             b.mul(&f);
-            self.x.copy(&a);
+            self.x = a.clone();
             self.x.mul(&b);
             g.norm();
             if rom::CURVE_A == 1 {
                 e.norm();
-                c.copy(&e);
+                c = e.clone();
                 c.mul(&g);
             }
             if rom::CURVE_A == -1 {
                 c.norm();
                 c.mul(&g);
             }
-            self.y.copy(&a);
+            self.y = a.clone();
             self.y.mul(&c);
-            self.z.copy(&f);
+            self.z = f.clone();
             self.z.mul(&g);
         }
         return;
@@ -915,12 +882,10 @@ impl ECP {
 
     /* 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();
+        let mut a = self.x.clone();
+        let mut b = self.x.clone();
+        let mut c = Q.x.clone();
+        let mut d = Q.x.clone();
 
         a.add(&self.z);
         b.sub(&self.z);
@@ -931,64 +896,61 @@ impl ECP {
         a.norm();
         d.norm();
 
-        da.copy(&d);
+        let mut da  = d.clone();
         da.mul(&a);
 
         c.norm();
         b.norm();
 
-        cb.copy(&c);
+        let mut cb = c.clone();
         cb.mul(&b);
 
-        a.copy(&da);
+        a  = da.clone();
         a.add(&cb);
         a.norm();
         a.sqr();
-        b.copy(&da);
+        b = da.clone();
         b.sub(&cb);
         b.norm();
         b.sqr();
 
-        self.x.copy(&a);
-        self.z.copy(&W.x);
+        self.x = a.clone();
+        self.z = W.getpx();
         self.z.mul(&b);
     }
 
-    /* self-=Q */
+    /// self-=Q
     pub fn sub(&mut self, Q: &ECP) {
-        let mut NQ = ECP::new();
-        NQ.copy(Q);
+        let mut NQ = Q.clone();
         NQ.neg();
         self.add(&NQ);
     }
 
-    /* constant time multiply by small integer of length bts - use ladder */
+    // Constant time multiply by small integer of length bts - use ladder
     pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
         if CURVETYPE == CurveType::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);
+            let mut R1 = self.clone();
 
             for i in (0..bts).rev() {
                 let b = ((e >> i) & 1) as isize;
-                P.copy(&R1);
+                P = R1.clone();
                 P.add(&R0);
                 R0.cswap(&mut R1, b);
-                R1.copy(&P);
+                R1 = P.clone();
                 R0.dbl();
                 R0.cswap(&mut R1, b);
             }
-            P.copy(&R0);
+            P = R0.clone();
             P.affine();
             return P;
         }
     }
 
-    /* return e.self */
-
+    /// Return e.self
     pub fn mul(&self, e: &Big) -> ECP {
         if e.iszilch() || self.is_infinity() {
             return ECP::new();
@@ -996,33 +958,24 @@ impl ECP {
         let mut P = ECP::new();
         if CURVETYPE == CurveType::Montgomery {
             /* use Ladder */
-            let mut D = ECP::new();
-            let mut R0 = ECP::new();
-            R0.copy(&self);
-            let mut R1 = ECP::new();
-            R1.copy(&self);
+            let mut R0 = self.clone();
+            let mut R1 = self.clone();
             R1.dbl();
-            D.copy(&self);
+            let mut D = self.clone();
             D.affine();
             let nb = e.nbits();
 
             for i in (0..nb - 1).rev() {
                 let b = e.bit(i);
-                P.copy(&R1);
+                P = R1.clone();
                 P.dadd(&mut R0, &D);
                 R0.cswap(&mut R1, b);
-                R1.copy(&P);
+                R1 = P.clone();
                 R0.dbl();
                 R0.cswap(&mut R1, b);
             }
-            P.copy(&R0)
+            P = R0.clone();
         } 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(),
@@ -1037,29 +990,28 @@ impl ECP {
             const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
             let mut w: [i8; CT] = [0; CT];
 
-            Q.copy(&self);
+            let mut Q = self.clone();
             Q.dbl();
 
-            W[0].copy(&self);
+            W[0] = self.clone();
 
             for i in 1..8 {
-                C.copy(&W[i - 1]);
-                W[i].copy(&C);
+                W[i]  = W[i - 1].clone();
                 W[i].add(&Q);
             }
 
             // make exponent odd - add 2P if even, P if odd
-            t.copy(&e);
+            let mut t = e.clone();
             let s = t.parity();
             t.inc(1);
             t.norm();
             let ns = t.parity();
-            mt.copy(&t);
+            let mut mt = t.clone();
             mt.inc(1);
             mt.norm();
             t.cmove(&mt, s);
             Q.cmove(&self, ns);
-            C.copy(&Q);
+            let C = Q.clone();
 
             let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -1072,7 +1024,7 @@ impl ECP {
             }
             w[nb] = t.lastbits(5) as i8;
 
-            P.copy(&W[((w[nb] as usize) - 1) / 2]);
+            P = W[((w[nb] as usize) - 1) / 2].clone();
             for i in (0..nb).rev() {
                 Q.selector(&W, w[i] as i32);
                 P.dbl();
@@ -1084,19 +1036,12 @@ impl ECP {
             P.sub(&C); /* apply correction */
         }
         P.affine();
-        return P;
+        P
     }
 
     /* Return e.this+f.Q */
 
     pub fn mul2(&self, e: &Big, Q: &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(),
@@ -1111,36 +1056,36 @@ impl ECP {
         const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 1) / 2;
         let mut w: [i8; CT] = [0; CT];
 
-        te.copy(e);
-        tf.copy(f);
+        let mut te = e.clone();
+        let mut tf = f.clone();
 
         // precompute table
 
-        W[1].copy(&self);
+        W[1] = self.clone();
         W[1].sub(Q);
-        W[2].copy(&self);
+        W[2] = self.clone();
         W[2].add(Q);
-        S.copy(&Q);
+        let mut S = Q.clone();
         S.dbl();
-        C.copy(&W[1]);
-        W[0].copy(&C);
+        let mut C = W[1].clone();
+        W[0]  = C.clone();
         W[0].sub(&S); // copy to C is stupid Rust thing..
-        C.copy(&W[2]);
-        W[3].copy(&C);
+        C = W[2].clone();
+        W[3]  = C.clone();
         W[3].add(&S);
-        T.copy(&self);
+        let mut T = self.clone();
         T.dbl();
-        C.copy(&W[1]);
-        W[5].copy(&C);
+        C = W[1].clone();
+        W[5]  = C.clone();
         W[5].add(&T);
-        C.copy(&W[2]);
-        W[6].copy(&C);
+        C = W[2].clone();
+        W[6]  = C.clone();
         W[6].add(&T);
-        C.copy(&W[5]);
-        W[4].copy(&C);
+        C = W[5].clone();
+        W[4] = C.clone();
         W[4].sub(&S);
-        C.copy(&W[6]);
-        W[7].copy(&C);
+        C = W[6].clone();
+        W[7] = C.clone();
         W[7].add(&S);
 
         // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction
@@ -1149,25 +1094,25 @@ impl ECP {
         te.inc(1);
         te.norm();
         let mut ns = te.parity();
-        mt.copy(&te);
+        let mut mt = te.clone();
         mt.inc(1);
         mt.norm();
         te.cmove(&mt, s);
         T.cmove(&self, ns);
-        C.copy(&T);
+        C = T.clone();
 
         s = tf.parity();
         tf.inc(1);
         tf.norm();
         ns = tf.parity();
-        mt.copy(&tf);
+        mt = tf.clone();
         mt.inc(1);
         mt.norm();
         tf.cmove(&mt, s);
         S.cmove(&Q, ns);
         C.add(&S);
 
-        mt.copy(&te);
+        mt = te.clone();
         mt.add(&tf);
         mt.norm();
         let nb = 1 + (mt.nbits() + 1) / 2;
@@ -1185,7 +1130,7 @@ impl ECP {
             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]);
+        S = W[((w[nb] as usize) - 1) / 2].clone();
 
         for i in (0..nb).rev() {
             T.selector(&W, w[i] as i32);
@@ -1217,7 +1162,7 @@ impl ECP {
         }
         let c = Big::new_ints(&rom::CURVE_COF);
         let P = self.mul(&c);
-        self.copy(&P);
+        *self = P.clone();
     }
 
     // Map a given byte slice to a point on the curve. The byte slice should be atleast the size of the modulus
diff --git a/src/ecp2.rs b/src/ecp2.rs
index b0892e4..f86a005 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -26,7 +26,7 @@ use std::fmt;
 use std::str::SplitWhitespace;
 use types::{CurvePairingType, SexticTwist, SignOfX};
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct ECP2 {
     x: FP2,
     y: FP2,
@@ -62,32 +62,33 @@ impl ECP2 {
     }
     #[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();
+    pub fn new_fp2s(x: FP2, y: FP2) -> ECP2 {
+        let mut E = ECP2 {
+            x,
+            y,
+            z: FP2::new_int(1),
+        };
         E.x.norm();
 
         let rhs = ECP2::rhs(&E.x);
-        let mut y2 = FP2::new_copy(&E.y);
+        let mut y2 = E.y.clone();
         y2.sqr();
         if !y2.equals(&rhs) {
             E.inf();
         }
-        return E;
+        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.x = ix.clone();
         E.y.one();
         E.z.one();
         E.x.norm();
         let mut rhs = ECP2::rhs(&E.x);
         if rhs.sqrt() {
-            E.y.copy(&rhs);
+            E.y = rhs;
         } else {
             E.inf();
         }
@@ -99,13 +100,6 @@ impl ECP2 {
         self.x.iszilch() && self.z.iszilch()
     }
 
-    /* copy self=P */
-    pub fn copy(&mut self, P: &ECP2) {
-        self.x.copy(&P.x);
-        self.y.copy(&P.y);
-        self.z.copy(&P.z);
-    }
-
     /* set self=O */
     pub fn inf(&mut self) {
         self.x.zero();
@@ -136,7 +130,6 @@ impl ECP2 {
 
     /* 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;
 
@@ -151,24 +144,24 @@ impl ECP2 {
         self.cmove(&W[6], ECP2::teq(babs, 6));
         self.cmove(&W[7], ECP2::teq(babs, 7));
 
-        MP.copy(self);
+        let mut MP = self.clone();
         MP.neg();
         self.cmove(&MP, (m & 1) as isize);
     }
 
     /* Test if P == Q */
     pub fn equals(&self, Q: &ECP2) -> bool {
-        let mut a = FP2::new_copy(&self.x);
-        let mut b = FP2::new_copy(&Q.x);
+        let mut a = self.x.clone();
+        let mut b = Q.x.clone();
 
         a.mul(&Q.z);
         b.mul(&self.z);
         if !a.equals(&b) {
             return false;
         }
-        a.copy(&self.y);
+        a = self.getpy();
         a.mul(&Q.z);
-        b.copy(&Q.y);
+        b = Q.getpy();
         b.mul(&self.z);
         if !a.equals(&b) {
             return false;
@@ -192,44 +185,41 @@ impl ECP2 {
         self.x.reduce();
         self.y.mul(&self.z);
         self.y.reduce();
-        self.z.copy(&one);
+        self.z = one.clone();
     }
 
     /* extract affine x as FP2 */
     pub fn getx(&self) -> FP2 {
-        let mut W = ECP2::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP2::new_copy(&W.x);
+        W.x.clone()
     }
 
     /* extract affine y as FP2 */
     pub fn gety(&self) -> FP2 {
-        let mut W = ECP2::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP2::new_copy(&W.y);
+        W.y.clone()
     }
 
     /* extract projective x */
     pub fn getpx(&self) -> FP2 {
-        return FP2::new_copy(&self.x);
+        self.x.clone()
     }
     /* extract projective y */
     pub fn getpy(&self) -> FP2 {
-        return FP2::new_copy(&self.y);
+        self.y.clone()
     }
     /* extract projective z */
     pub fn getpz(&self) -> FP2 {
-        return FP2::new_copy(&self.z);
+        self.z.clone()
     }
 
     /* convert to byte array */
     pub fn tobytes(&self, b: &mut [u8]) {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
-        let mut W = ECP2::new();
-        W.copy(self);
+        let mut W = self.clone();
 
         W.affine();
         W.x.geta().tobytes(&mut t);
@@ -259,30 +249,29 @@ impl ECP2 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = Big::frombytes(&t);
+        let 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);
+        let 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));
+        let ra = 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);
+        let rb = Big::frombytes(&t);
+        let ry = FP2::new_bigs(ra, rb);
 
-        return ECP2::new_fp2s(&rx, &ry);
+        ECP2::new_fp2s(rx, ry)
     }
 
     /* convert this to hex string */
     pub fn tostring(&self) -> String {
-        let mut W = ECP2::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
         if W.is_infinity() {
             return String::from("infinity");
@@ -314,9 +303,9 @@ impl ECP2 {
 
     /* Calculate RHS of twisted curve equation x^3+B/i */
     pub fn rhs(x: &FP2) -> FP2 {
-        let mut r = FP2::new_copy(x);
+        let mut r = x.clone();
         r.sqr();
-        let mut b = FP2::new_big(&Big::new_ints(&rom::CURVE_B));
+        let mut b = FP2::new_big(Big::new_ints(&rom::CURVE_B));
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_ip();
         }
@@ -335,23 +324,23 @@ impl ECP2 {
 
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
-        let mut iy = FP2::new_copy(&self.y);
+        let mut iy = self.y.clone();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.mul_ip();
             iy.norm();
         }
 
-        let mut t0 = FP2::new_copy(&self.y); //***** Change
+        let mut t0 = self.y.clone(); //***** Change
         t0.sqr();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.mul_ip();
         }
-        let mut t1 = FP2::new_copy(&iy);
+        let mut t1 = iy.clone();
         t1.mul(&self.z);
-        let mut t2 = FP2::new_copy(&self.z);
+        let mut t2 = self.z.clone();
         t2.sqr();
 
-        self.z.copy(&t0);
+        self.z = t0.clone();
         self.z.add(&t0);
         self.z.norm();
         self.z.dbl();
@@ -363,15 +352,15 @@ impl ECP2 {
             t2.mul_ip();
             t2.norm();
         }
-        let mut x3 = FP2::new_copy(&t2);
+        let mut x3 = t2.clone();
         x3.mul(&self.z);
 
-        let mut y3 = FP2::new_copy(&t0);
+        let mut y3 = t0.clone();
 
         y3.add(&t2);
         y3.norm();
         self.z.mul(&t1);
-        t1.copy(&t2);
+        t1 = t2.clone();
         t1.add(&t2);
         t2.add(&t1);
         t2.norm();
@@ -379,15 +368,15 @@ impl ECP2 {
         t0.norm(); //y^2-9bz^2
         y3.mul(&t0);
         y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
-        t1.copy(&self.x);
+        t1 = self.x.clone();
         t1.mul(&iy); //
-        self.x.copy(&t0);
+        self.x = t0.clone();
         self.x.norm();
         self.x.mul(&t1);
         self.x.dbl(); //(y^2-9bz^2)xy2
 
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3;
         self.y.norm();
 
         return 1;
@@ -396,21 +385,21 @@ impl ECP2 {
     /* self+=Q - return 0 for add, 1 for double, -1 for O */
     pub fn add(&mut self, Q: &ECP2) -> isize {
         let b = 3 * rom::CURVE_B_I;
-        let mut t0 = FP2::new_copy(&self.x);
+        let mut t0 = self.x.clone();
         t0.mul(&Q.x); // x.Q.x
-        let mut t1 = FP2::new_copy(&self.y);
+        let mut t1 = self.y.clone();
         t1.mul(&Q.y); // y.Q.y
 
-        let mut t2 = FP2::new_copy(&self.z);
+        let mut t2 = self.z.clone();
         t2.mul(&Q.z);
-        let mut t3 = FP2::new_copy(&self.x);
+        let mut t3 = self.x.clone();
         t3.add(&self.y);
         t3.norm(); //t3=X1+Y1
-        let mut t4 = FP2::new_copy(&Q.x);
+        let mut t4 = Q.x.clone();
         t4.add(&Q.y);
         t4.norm(); //t4=X2+Y2
         t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
-        t4.copy(&t0);
+        t4 = t0.clone();
         t4.add(&t1); //t4=X1.X2+Y1.Y2
 
         t3.sub(&t4);
@@ -419,15 +408,15 @@ impl ECP2 {
             t3.mul_ip();
             t3.norm(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
-        t4.copy(&self.y);
+        t4 = self.getpy();
         t4.add(&self.z);
         t4.norm(); //t4=Y1+Z1
-        let mut x3 = FP2::new_copy(&Q.y);
+        let mut x3 = Q.y.clone();
         x3.add(&Q.z);
         x3.norm(); //x3=Y2+Z2
 
         t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
-        x3.copy(&t1); //
+        x3 = t1.clone(); //
         x3.add(&t2); //X3=Y1.Y2+Z1.Z2
 
         t4.sub(&x3);
@@ -436,14 +425,14 @@ impl ECP2 {
             t4.mul_ip();
             t4.norm(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
-        x3.copy(&self.x);
+        x3 = self.getpx();
         x3.add(&self.z);
         x3.norm(); // x3=X1+Z1
-        let mut y3 = FP2::new_copy(&Q.x);
+        let mut y3 = Q.x.clone();
         y3.add(&Q.z);
         y3.norm(); // y3=X2+Z2
         x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
-        y3.copy(&t0);
+        y3 = t0.clone();
         y3.add(&t2); // y3=X1.X2+Z1+Z2
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
@@ -454,7 +443,7 @@ impl ECP2 {
             t1.mul_ip();
             t1.norm(); // y.Q.y
         }
-        x3.copy(&t0);
+        x3 = t0.clone();
         x3.add(&t0);
         t0.add(&x3);
         t0.norm();
@@ -463,7 +452,7 @@ impl ECP2 {
             t2.mul_ip();
             t2.norm();
         }
-        let mut z3 = FP2::new_copy(&t1);
+        let mut z3 = t1.clone();
         z3.add(&t2);
         z3.norm();
         t1.sub(&t2);
@@ -473,9 +462,9 @@ impl ECP2 {
             y3.mul_ip();
             y3.norm();
         }
-        x3.copy(&y3);
+        x3 = y3.clone();
         x3.mul(&t4);
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.mul(&t1);
         x3.rsub(&t2);
         y3.mul(&t0);
@@ -485,11 +474,11 @@ impl ECP2 {
         z3.mul(&t4);
         z3.add(&t0);
 
-        self.x.copy(&x3);
+        self.x = x3;
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3;
         self.y.norm();
-        self.z.copy(&z3);
+        self.z = z3;
         self.z.norm();
 
         return 0;
@@ -497,8 +486,7 @@ impl ECP2 {
 
     /* set this-=Q */
     pub fn sub(&mut self, Q: &ECP2) -> isize {
-        let mut NQ = ECP2::new();
-        NQ.copy(Q);
+        let mut NQ = Q.clone();
         NQ.neg();
         let d = self.add(&NQ);
         return d;
@@ -506,7 +494,7 @@ impl ECP2 {
 
     /* set this*=q, where q is Modulus, using Frobenius */
     pub fn frob(&mut self, x: &FP2) {
-        let mut x2 = FP2::new_copy(x);
+        let mut x2 = x.clone();
         x2.sqr();
         self.x.conj();
         self.y.conj();
@@ -519,15 +507,8 @@ impl ECP2 {
 
     /* self*=e */
     pub fn mul(&self, e: &Big) -> ECP2 {
-        /* fixed size windows */
-        let mut mt = Big::new();
-        let mut t = Big::new();
-        let mut P = ECP2::new();
-        let mut Q = ECP2::new();
-        let mut C = ECP2::new();
-
         if self.is_infinity() {
-            return P;
+            return ECP2::new();
         }
 
         let mut W: [ECP2; 8] = [
@@ -545,29 +526,28 @@ impl ECP2 {
         let mut w: [i8; CT] = [0; CT];
 
         /* precompute table */
-        Q.copy(&self);
+        let mut Q = self.clone();
         Q.dbl();
 
-        W[0].copy(&self);
+        W[0] = self.clone();
 
         for i in 1..8 {
-            C.copy(&W[i - 1]);
-            W[i].copy(&C);
+            W[i] = W[i - 1].clone();
             W[i].add(&Q);
         }
 
         /* make exponent odd - add 2P if even, P if odd */
-        t.copy(&e);
+        let mut t = e.clone();
         let s = t.parity();
         t.inc(1);
         t.norm();
         let ns = t.parity();
-        mt.copy(&t);
+        let mut mt = t.clone();
         mt.inc(1);
         mt.norm();
         t.cmove(&mt, s);
         Q.cmove(&self, ns);
-        C.copy(&Q);
+        let C = Q.clone();
 
         let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -580,7 +560,7 @@ impl ECP2 {
         }
         w[nb] = (t.lastbits(5)) as i8;
 
-        P.copy(&W[((w[nb] as usize) - 1) / 2]);
+        let mut P = W[((w[nb] as usize) - 1) / 2].clone();
         for i in (0..nb).rev() {
             Q.selector(&W, w[i] as i32);
             P.dbl();
@@ -591,7 +571,7 @@ impl ECP2 {
         }
         P.sub(&C);
         P.affine();
-        return P;
+        P
     }
 
     /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
@@ -600,7 +580,6 @@ impl ECP2 {
     // Side channel attack secure
 
     pub fn mul4(Q: &mut [ECP2], u: &[Big]) -> ECP2 {
-        let mut W = ECP2::new();
         let mut P = ECP2::new();
 
         let mut T: [ECP2; 8] = [
@@ -616,12 +595,7 @@ impl ECP2 {
 
         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]),
-        ];
+        let mut t: [Big; 4] = [u[0].clone(), u[1].clone(), u[2].clone(), u[3].clone()];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
         let mut w: [i8; CT] = [0; CT];
@@ -631,26 +605,26 @@ impl ECP2 {
             t[i].norm();
         }
 
-        T[0].copy(&Q[0]);
-        W.copy(&T[0]);
-        T[1].copy(&W);
+        T[0] = Q[0].clone();
+        let mut W = T[0].clone();
+        T[1] = W.clone();
         T[1].add(&Q[1]); // Q[0]+Q[1]
-        T[2].copy(&W);
+        T[2] = W.clone();
         T[2].add(&Q[2]);
-        W.copy(&T[1]); // Q[0]+Q[2]
-        T[3].copy(&W);
+        W = T[1].clone(); // Q[0]+Q[2]
+        T[3] = W.clone();
         T[3].add(&Q[2]);
-        W.copy(&T[0]); // Q[0]+Q[1]+Q[2]
-        T[4].copy(&W);
+        W = T[0].clone(); // Q[0]+Q[1]+Q[2]
+        T[4] = W.clone();
         T[4].add(&Q[3]);
-        W.copy(&T[1]); // Q[0]+Q[3]
-        T[5].copy(&W);
+        W = T[1].clone(); // Q[0]+Q[3]
+        T[5] = W.clone();
         T[5].add(&Q[3]);
-        W.copy(&T[2]); // Q[0]+Q[1]+Q[3]
-        T[6].copy(&W);
+        W = T[2].clone(); // Q[0]+Q[1]+Q[3]
+        T[6] = W.clone();
         T[6].add(&Q[3]);
-        W.copy(&T[3]); // Q[0]+Q[2]+Q[3]
-        T[7].copy(&W);
+        W = T[3].clone(); // Q[0]+Q[2]+Q[3]
+        T[7] = W.clone();
         T[7].add(&Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
 
         // Make it odd
@@ -697,7 +671,7 @@ impl ECP2 {
         }
 
         // apply correction
-        W.copy(&P);
+        W = P.clone();
         W.sub(&Q[0]);
         P.cmove(&W, pb);
         P.affine();
@@ -714,7 +688,7 @@ impl ECP2 {
         let one = Big::new_int(1);
 
         loop {
-            let X = FP2::new_bigs(&one, &x);
+            let X = FP2::new_bigs(one.clone(), x.clone());
             Q = ECP2::new_fp2(&X);
             if !Q.is_infinity() {
                 break;
@@ -722,7 +696,7 @@ impl ECP2 {
             x.inc(1);
             x.norm();
         }
-        let mut X = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let mut X = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             X.inverse();
             X.norm();
@@ -734,8 +708,7 @@ impl ECP2 {
             if ecp::SIGN_OF_X == SignOfX::NegativeX {
                 T.neg();
             }
-            let mut K = ECP2::new();
-            K.copy(&T);
+            let mut K = T.clone();
             K.dbl();
             K.add(&T);
 
@@ -771,18 +744,18 @@ impl ECP2 {
         }
 
         Q.affine();
-        return Q;
+        Q
     }
 
     pub fn generator() -> ECP2 {
         return ECP2::new_fp2s(
-            &FP2::new_bigs(
-                &Big::new_ints(&rom::CURVE_PXA),
-                &Big::new_ints(&rom::CURVE_PXB),
+            FP2::new_bigs(
+                Big::new_ints(&rom::CURVE_PXA),
+                Big::new_ints(&rom::CURVE_PXB),
             ),
-            &FP2::new_bigs(
-                &Big::new_ints(&rom::CURVE_PYA),
-                &Big::new_ints(&rom::CURVE_PYB),
+            FP2::new_bigs(
+                Big::new_ints(&rom::CURVE_PYA),
+                Big::new_ints(&rom::CURVE_PYB),
             ),
         );
     }
diff --git a/src/ecp4.rs b/src/ecp4.rs
index e0dc5dc..d7311b7 100644
--- a/src/ecp4.rs
+++ b/src/ecp4.rs
@@ -24,8 +24,8 @@ use super::fp2::FP2;
 use super::fp4::FP4;
 use super::rom;
 use types::{SexticTwist, SignOfX};
-//use std::str::SplitWhitespace;
 
+#[derive(Clone)]
 pub struct ECP4 {
     x: FP4,
     y: FP4,
@@ -45,13 +45,13 @@ impl ECP4 {
     /* construct this from (x,y) - but set to O if not on curve */
     pub fn new_fp4s(ix: &FP4, iy: &FP4) -> ECP4 {
         let mut E = ECP4::new();
-        E.x.copy(&ix);
-        E.y.copy(&iy);
+        E.x = ix.clone();
+        E.y = iy.clone();
         E.z.one();
         E.x.norm();
 
         let mut rhs = ECP4::rhs(&E.x);
-        let mut y2 = FP4::new_copy(&E.y);
+        let mut y2 = E.getpy();
         y2.sqr();
         if !y2.equals(&mut rhs) {
             E.inf();
@@ -62,14 +62,14 @@ impl ECP4 {
     /* construct this from x - but set to O if not on curve */
     pub fn new_fp4(ix: &FP4) -> ECP4 {
         let mut E = ECP4::new();
-        E.x.copy(&ix);
+        E.x = ix.clone();
         E.y.one();
         E.z.one();
         E.x.norm();
 
         let mut rhs = ECP4::rhs(&E.x);
         if rhs.sqrt() {
-            E.y.copy(&rhs);
+            E.y = rhs;
         } else {
             E.inf();
         }
@@ -78,18 +78,11 @@ impl ECP4 {
 
     /* Test this=O? */
     pub fn is_infinity(&self) -> bool {
-        let xx = FP4::new_copy(&self.x);
-        let zz = FP4::new_copy(&self.z);
+        let xx = self.getpx();
+        let zz = self.getpz();
         return xx.iszilch() && zz.iszilch();
     }
 
-    /* copy self=P */
-    pub fn copy(&mut self, P: &ECP4) {
-        self.x.copy(&P.x);
-        self.y.copy(&P.y);
-        self.z.copy(&P.z);
-    }
-
     /* set self=O */
     pub fn inf(&mut self) {
         self.x.zero();
@@ -120,7 +113,6 @@ impl ECP4 {
 
     /* Constant time select from pre-computed table */
     pub fn selector(&mut self, W: &[ECP4], b: i32) {
-        let mut MP = ECP4::new();
         let m = b >> 31;
         let mut babs = (b ^ m) - m;
 
@@ -135,24 +127,24 @@ impl ECP4 {
         self.cmove(&W[6], ECP4::teq(babs, 6));
         self.cmove(&W[7], ECP4::teq(babs, 7));
 
-        MP.copy(self);
+        let mut MP = self.clone();
         MP.neg();
         self.cmove(&MP, (m & 1) as isize);
     }
 
     /* Test if P == Q */
     pub fn equals(&mut self, Q: &mut ECP4) -> bool {
-        let mut a = FP4::new_copy(&self.x);
-        let mut b = FP4::new_copy(&Q.x);
+        let mut a = self.getpx();
+        let mut b = Q.getpx();
 
         a.mul(&Q.z);
         b.mul(&self.z);
         if !a.equals(&mut b) {
             return false;
         }
-        a.copy(&self.y);
+        a = self.getpy();
         a.mul(&Q.z);
-        b.copy(&Q.y);
+        b = Q.getpy();
         b.mul(&self.z);
         if !a.equals(&mut b) {
             return false;
@@ -176,36 +168,34 @@ impl ECP4 {
         self.x.reduce();
         self.y.mul(&self.z);
         self.y.reduce();
-        self.z.copy(&one);
+        self.z = one.clone();
     }
 
     /* extract affine x as FP4 */
     pub fn getx(&self) -> FP4 {
-        let mut W = ECP4::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP4::new_copy(&self.x);
+        W.getpx()
     }
 
     /* extract affine y as FP4 */
     pub fn gety(&self) -> FP4 {
-        let mut W = ECP4::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP4::new_copy(&W.y);
+        W.getpy()
     }
 
     /* extract projective x */
     pub fn getpx(&self) -> FP4 {
-        return FP4::new_copy(&self.x);
+        self.x.clone()
     }
     /* extract projective y */
     pub fn getpy(&self) -> FP4 {
-        return FP4::new_copy(&self.y);
+        self.y.clone()
     }
     /* extract projective z */
     pub fn getpz(&self) -> FP4 {
-        return FP4::new_copy(&self.z);
+        self.z.clone()
     }
 
     /* convert to byte array */
@@ -213,8 +203,7 @@ impl ECP4 {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
 
-        let mut W = ECP4::new();
-        W.copy(self);
+        let mut W = self.clone();
 
         W.affine();
 
@@ -263,58 +252,57 @@ impl ECP4 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = Big::frombytes(&t);
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + mb]
         }
-        let mut rb = Big::frombytes(&t);
+        let rb = Big::frombytes(&t);
 
-        let mut ra4 = FP2::new_bigs(&ra, &rb);
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 2 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 3 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        let mut rb4 = FP2::new_bigs(&ra, &rb);
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        let rx = FP4::new_fp2s(&ra4, &rb4);
+        let rx = FP4::new_fp2s(ra4, rb4);
 
         for i in 0..mb {
             t[i] = b[i + 4 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 5 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        ra4.copy(&FP2::new_bigs(&ra, &rb));
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 6 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 7 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        rb4.copy(&FP2::new_bigs(&ra, &rb));
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        let ry = FP4::new_fp2s(&ra4, &rb4);
+        let ry = FP4::new_fp2s(ra4, rb4);
 
-        return ECP4::new_fp4s(&rx, &ry);
+        ECP4::new_fp4s(&rx, &ry)
     }
 
     /* convert this to hex string */
     pub fn tostring(&self) -> String {
-        let mut W = ECP4::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
         if W.is_infinity() {
             return String::from("infinity");
@@ -325,9 +313,9 @@ impl ECP4 {
     /* Calculate RHS of twisted curve equation x^3+B/i */
     pub fn rhs(x: &FP4) -> FP4 {
         //x.norm();
-        let mut r = FP4::new_copy(x);
+        let mut r = x.clone();
         r.sqr();
-        let mut b = FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B)));
+        let mut b = FP4::new_fp2(FP2::new_big(Big::new_ints(&rom::CURVE_B)));
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_i();
         }
@@ -344,22 +332,22 @@ impl ECP4 {
 
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
-        let mut iy = FP4::new_copy(&self.y);
+        let mut iy = self.getpy();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.times_i(); //iy.norm();
         }
 
-        let mut t0 = FP4::new_copy(&self.y);
+        let mut t0 = self.getpy();
         t0.sqr();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i();
         }
-        let mut t1 = FP4::new_copy(&iy);
+        let mut t1 = iy.clone();
         t1.mul(&self.z);
-        let mut t2 = FP4::new_copy(&self.z);
+        let mut t2 = self.getpz();
         t2.sqr();
 
-        self.z.copy(&t0);
+        self.z = t0.clone();
         self.z.add(&t0);
         self.z.norm();
         self.z.dbl();
@@ -370,15 +358,15 @@ impl ECP4 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
-        let mut x3 = FP4::new_copy(&t2);
+        let mut x3 = t2.clone();
         x3.mul(&self.z);
 
-        let mut y3 = FP4::new_copy(&t0);
+        let mut y3 = t0.clone();
 
         y3.add(&t2);
         y3.norm();
         self.z.mul(&t1);
-        t1.copy(&t2);
+        t1 = t2.clone();
         t1.add(&t2);
         t2.add(&t1);
         t2.norm();
@@ -386,15 +374,15 @@ impl ECP4 {
         t0.norm(); //y^2-9bz^2
         y3.mul(&t0);
         y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
-        t1.copy(&self.x);
+        t1 = self.getpx();
         t1.mul(&iy); //
-        self.x.copy(&t0);
+        self.x = t0.clone();
         self.x.norm();
         self.x.mul(&t1);
         self.x.dbl(); //(y^2-9bz^2)xy2
 
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3.clone();
         self.y.norm();
 
         return 1;
@@ -403,21 +391,21 @@ impl ECP4 {
     /* self+=Q - return 0 for add, 1 for double, -1 for O */
     pub fn add(&mut self, Q: &ECP4) -> isize {
         let b = 3 * rom::CURVE_B_I;
-        let mut t0 = FP4::new_copy(&self.x);
+        let mut t0 = self.getpx();
         t0.mul(&Q.x); // x.Q.x
-        let mut t1 = FP4::new_copy(&self.y);
+        let mut t1 = self.getpy();
         t1.mul(&Q.y); // y.Q.y
 
-        let mut t2 = FP4::new_copy(&self.z);
+        let mut t2 = self.getpz();
         t2.mul(&Q.z);
-        let mut t3 = FP4::new_copy(&self.x);
+        let mut t3 = self.getpx();
         t3.add(&self.y);
         t3.norm(); //t3=X1+Y1
-        let mut t4 = FP4::new_copy(&Q.x);
+        let mut t4 = Q.getpx();
         t4.add(&Q.y);
         t4.norm(); //t4=X2+Y2
         t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
-        t4.copy(&t0);
+        t4 = t0.clone();
         t4.add(&t1); //t4=X1.X2+Y1.Y2
 
         t3.sub(&t4);
@@ -425,15 +413,15 @@ impl ECP4 {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
-        t4.copy(&self.y);
+        t4 = self.getpy();
         t4.add(&self.z);
         t4.norm(); //t4=Y1+Z1
-        let mut x3 = FP4::new_copy(&Q.y);
+        let mut x3 = Q.getpy();
         x3.add(&Q.z);
         x3.norm(); //x3=Y2+Z2
 
         t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
-        x3.copy(&t1); //
+        x3 = t1.clone(); //
         x3.add(&t2); //X3=Y1.Y2+Z1.Z2
 
         t4.sub(&x3);
@@ -441,14 +429,14 @@ impl ECP4 {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
-        x3.copy(&self.x);
+        x3 = self.getpx();
         x3.add(&self.z);
         x3.norm(); // x3=X1+Z1
-        let mut y3 = FP4::new_copy(&Q.x);
+        let mut y3 = Q.getpx();
         y3.add(&Q.z);
         y3.norm(); // y3=X2+Z2
         x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
-        y3.copy(&t0);
+        y3 = t0.clone();
         y3.add(&t2); // y3=X1.X2+Z1+Z2
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
@@ -457,7 +445,7 @@ impl ECP4 {
             t0.times_i(); // x.Q.x
             t1.times_i(); // y.Q.y
         }
-        x3.copy(&t0);
+        x3 = t0.clone();
         x3.add(&t0);
         t0.add(&x3);
         t0.norm();
@@ -465,7 +453,7 @@ impl ECP4 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
-        let mut z3 = FP4::new_copy(&t1);
+        let mut z3 = t1.clone();
         z3.add(&t2);
         z3.norm();
         t1.sub(&t2);
@@ -474,9 +462,9 @@ impl ECP4 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             y3.times_i();
         }
-        x3.copy(&y3);
+        x3 = y3.clone();
         x3.mul(&t4);
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.mul(&t1);
         x3.rsub(&t2);
         y3.mul(&t0);
@@ -486,11 +474,11 @@ impl ECP4 {
         z3.mul(&t4);
         z3.add(&t0);
 
-        self.x.copy(&x3);
+        self.x = x3.clone();
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3.clone();
         self.y.norm();
-        self.z.copy(&z3);
+        self.z = z3.clone();
         self.z.norm();
 
         return 0;
@@ -498,29 +486,27 @@ impl ECP4 {
 
     /* set this-=Q */
     pub fn sub(&mut self, Q: &ECP4) -> isize {
-        let mut NQ = ECP4::new();
-        NQ.copy(Q);
+        let mut NQ = Q.clone();
         NQ.neg();
-        let d = self.add(&NQ);
-        return d;
+        self.add(&NQ)
     }
 
     pub fn frob_constants() -> [FP2; 3] {
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
 
-        let mut f0 = FP2::new_copy(&f);
+        let mut f0 = f.clone();
         f0.sqr();
-        let mut f2 = FP2::new_copy(&f0);
+        let mut f2 = f0.clone();
         f2.mul_ip();
         f2.norm();
-        let mut f1 = FP2::new_copy(&f2);
+        let mut f1 = f2.clone();
         f1.sqr();
         f2.mul(&f1);
-        f1.copy(&f);
+        f1 = f.clone();
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f1.mul_ip();
             f1.inverse();
-            f0.copy(&f1);
+            f0 = f1.clone();
             f0.sqr();
         }
         f0.mul_ip();
@@ -548,14 +534,8 @@ impl ECP4 {
     /* self*=e */
     pub fn mul(&self, e: &Big) -> ECP4 {
         /* fixed size windows */
-        let mut mt = Big::new();
-        let mut t = Big::new();
-        let mut P = ECP4::new();
-        let mut Q = ECP4::new();
-        let mut C = ECP4::new();
-
         if self.is_infinity() {
-            return P;
+            return ECP4::new();
         }
 
         let mut W: [ECP4; 8] = [
@@ -573,29 +553,28 @@ impl ECP4 {
         let mut w: [i8; CT] = [0; CT];
 
         /* precompute table */
-        Q.copy(&self);
+        let mut Q = self.clone();
         Q.dbl();
 
-        W[0].copy(&self);
+        W[0] = self.clone();
 
         for i in 1..8 {
-            C.copy(&W[i - 1]);
-            W[i].copy(&C);
+            W[i] = W[i - 1].clone();
             W[i].add(&mut Q);
         }
 
         /* make exponent odd - add 2P if even, P if odd */
-        t.copy(&e);
+        let mut t = e.clone();
         let s = t.parity();
         t.inc(1);
         t.norm();
         let ns = t.parity();
-        mt.copy(&t);
+        let mut mt = t.clone();
         mt.inc(1);
         mt.norm();
         t.cmove(&mt, s);
         Q.cmove(&self, ns);
-        C.copy(&Q);
+        let mut C = Q.clone();
 
         let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -608,7 +587,7 @@ impl ECP4 {
         }
         w[nb] = (t.lastbits(5)) as i8;
 
-        P.copy(&W[((w[nb] as usize) - 1) / 2]);
+        let mut P = W[((w[nb] as usize) - 1) / 2].clone();
         for i in (0..nb).rev() {
             Q.selector(&W, w[i] as i32);
             P.dbl();
@@ -619,7 +598,7 @@ impl ECP4 {
         }
         P.sub(&mut C);
         P.affine();
-        return P;
+        P
     }
 
     /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3.. */
@@ -628,7 +607,6 @@ impl ECP4 {
     // Side channel attack secure
 
     pub fn mul8(Q: &mut [ECP4], u: &[Big]) -> ECP4 {
-        let mut W = ECP4::new();
         let mut P = ECP4::new();
 
         let mut T1: [ECP4; 8] = [
@@ -655,14 +633,14 @@ impl ECP4 {
         let mut mt = Big::new();
 
         let mut t: [Big; 8] = [
-            Big::new_copy(&u[0]),
-            Big::new_copy(&u[1]),
-            Big::new_copy(&u[2]),
-            Big::new_copy(&u[3]),
-            Big::new_copy(&u[4]),
-            Big::new_copy(&u[5]),
-            Big::new_copy(&u[6]),
-            Big::new_copy(&u[7]),
+            u[0].clone(),
+            u[1].clone(),
+            u[2].clone(),
+            u[3].clone(),
+            u[4].clone(),
+            u[5].clone(),
+            u[6].clone(),
+            u[7].clone(),
         ];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
@@ -676,32 +654,32 @@ impl ECP4 {
             t[i].norm();
         }
 
-        T1[0].copy(&Q[0]);
-        W.copy(&T1[0]);
-        T1[1].copy(&W);
+        T1[0] = Q[0].clone();
+        let mut W = T1[0].clone();
+        T1[1] = W.clone();
         T1[1].add(&mut Q[1]); // Q[0]+Q[1]
-        T1[2].copy(&W);
+        T1[2] = W.clone();
         T1[2].add(&mut Q[2]);
-        W.copy(&T1[1]); // Q[0]+Q[2]
-        T1[3].copy(&W);
+        W = T1[1].clone(); // Q[0]+Q[2]
+        T1[3] = W.clone();
         T1[3].add(&mut Q[2]);
-        W.copy(&T1[0]); // Q[0]+Q[1]+Q[2]
-        T1[4].copy(&W);
+        W = T1[0].clone(); // Q[0]+Q[1]+Q[2]
+        T1[4] = W.clone();
         T1[4].add(&mut Q[3]);
-        W.copy(&T1[1]); // Q[0]+Q[3]
-        T1[5].copy(&W);
+        W = T1[1].clone(); // Q[0]+Q[3]
+        T1[5] = W.clone();
         T1[5].add(&mut Q[3]);
-        W.copy(&T1[2]); // Q[0]+Q[1]+Q[3]
-        T1[6].copy(&W);
+        W = T1[2].clone(); // Q[0]+Q[1]+Q[3]
+        T1[6] = W.clone();
         T1[6].add(&mut Q[3]);
-        W.copy(&T1[3]); // Q[0]+Q[2]+Q[3]
-        T1[7].copy(&W);
+        W = T1[3].clone(); // Q[0]+Q[2]+Q[3]
+        T1[7] = W.clone();
         T1[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
 
         // Use frobenius
         let f = ECP4::frob_constants();
         for i in 0..8 {
-            T2[i].copy(&T1[i]);
+            T2[i] = T1[i].clone();
             T2[i].frob(&f, 4);
         }
 
@@ -771,11 +749,11 @@ impl ECP4 {
         }
 
         // apply correction
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[0]);
         P.cmove(&W, pb1);
 
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[4]);
         P.cmove(&W, pb2);
 
@@ -787,23 +765,23 @@ impl ECP4 {
     pub fn generator() -> ECP4 {
         return ECP4::new_fp4s(
             &FP4::new_fp2s(
-                &FP2::new_bigs(
-                    &Big::new_ints(&rom::CURVE_PXAA),
-                    &Big::new_ints(&rom::CURVE_PXAB),
+                FP2::new_bigs(
+                    Big::new_ints(&rom::CURVE_PXAA),
+                    Big::new_ints(&rom::CURVE_PXAB),
                 ),
-                &FP2::new_bigs(
-                    &Big::new_ints(&rom::CURVE_PXBA),
-                    &Big::new_ints(&rom::CURVE_PXBB),
+                FP2::new_bigs(
+                    Big::new_ints(&rom::CURVE_PXBA),
+                    Big::new_ints(&rom::CURVE_PXBB),
                 ),
             ),
             &FP4::new_fp2s(
-                &FP2::new_bigs(
-                    &Big::new_ints(&rom::CURVE_PYAA),
-                    &Big::new_ints(&rom::CURVE_PYAB),
+                FP2::new_bigs(
+                    Big::new_ints(&rom::CURVE_PYAA),
+                    Big::new_ints(&rom::CURVE_PYAB),
                 ),
-                &FP2::new_bigs(
-                    &Big::new_ints(&rom::CURVE_PYBA),
-                    &Big::new_ints(&rom::CURVE_PYBB),
+                FP2::new_bigs(
+                    Big::new_ints(&rom::CURVE_PYBA),
+                    Big::new_ints(&rom::CURVE_PYBB),
                 ),
             ),
         );
@@ -818,7 +796,7 @@ impl ECP4 {
         let one = Big::new_int(1);
 
         loop {
-            let X = FP4::new_fp2(&FP2::new_bigs(&one, &x));
+            let X = FP4::new_fp2(FP2::new_bigs(one.clone(), x.clone()));
             Q = ECP4::new_fp4(&X);
             if !Q.is_infinity() {
                 break;
diff --git a/src/ecp8.rs b/src/ecp8.rs
index 3998c2c..0261ce2 100644
--- a/src/ecp8.rs
+++ b/src/ecp8.rs
@@ -26,6 +26,7 @@ use super::fp8::FP8;
 use super::rom;
 use types::{SexticTwist, SignOfX};
 
+#[derive(Clone)]
 pub struct ECP8 {
     x: FP8,
     y: FP8,
@@ -45,13 +46,13 @@ impl ECP8 {
     /* construct this from (x,y) - but set to O if not on curve */
     pub fn new_fp8s(ix: &FP8, iy: &FP8) -> ECP8 {
         let mut E = ECP8::new();
-        E.x.copy(&ix);
-        E.y.copy(&iy);
+        E.x = ix.clone();
+        E.y = iy.clone();
         E.z.one();
         E.x.norm();
 
         let mut rhs = ECP8::rhs(&E.x);
-        let mut y2 = FP8::new_copy(&E.y);
+        let mut y2 = E.getpy();
         y2.sqr();
         if !y2.equals(&mut rhs) {
             E.inf();
@@ -62,14 +63,14 @@ impl ECP8 {
     /* construct this from x - but set to O if not on curve */
     pub fn new_fp8(ix: &FP8) -> ECP8 {
         let mut E = ECP8::new();
-        E.x.copy(&ix);
+        E.x = ix.clone();
         E.y.one();
         E.z.one();
         E.x.norm();
 
         let mut rhs = ECP8::rhs(&E.x);
         if rhs.sqrt() {
-            E.y.copy(&rhs);
+            E.y = rhs;
         } else {
             E.inf();
         }
@@ -78,18 +79,11 @@ impl ECP8 {
 
     /* Test this=O? */
     pub fn is_infinity(&self) -> bool {
-        let xx = FP8::new_copy(&self.x);
-        let zz = FP8::new_copy(&self.z);
+        let xx = self.getpx();
+        let zz = self.getpz();
         return xx.iszilch() && zz.iszilch();
     }
 
-    /* copy self=P */
-    pub fn copy(&mut self, P: &ECP8) {
-        self.x.copy(&P.x);
-        self.y.copy(&P.y);
-        self.z.copy(&P.z);
-    }
-
     /* set self=O */
     pub fn inf(&mut self) {
         self.x.zero();
@@ -120,7 +114,6 @@ impl ECP8 {
 
     /* Constant time select from pre-computed table */
     pub fn selector(&mut self, W: &[ECP8], b: i32) {
-        let mut MP = ECP8::new();
         let m = b >> 31;
         let mut babs = (b ^ m) - m;
 
@@ -135,24 +128,24 @@ impl ECP8 {
         self.cmove(&W[6], ECP8::teq(babs, 6));
         self.cmove(&W[7], ECP8::teq(babs, 7));
 
-        MP.copy(self);
+        let mut MP = self.clone();
         MP.neg();
         self.cmove(&MP, (m & 1) as isize);
     }
 
     /* Test if P == Q */
     pub fn equals(&mut self, Q: &mut ECP8) -> bool {
-        let mut a = FP8::new_copy(&self.x);
-        let mut b = FP8::new_copy(&Q.x);
+        let mut a = self.getpx();
+        let mut b = Q.getpx();
 
         a.mul(&Q.z);
         b.mul(&self.z);
         if !a.equals(&mut b) {
             return false;
         }
-        a.copy(&self.y);
+        a = self.getpy();
         a.mul(&Q.z);
-        b.copy(&Q.y);
+        b = Q.getpy();
         b.mul(&self.z);
         if !a.equals(&mut b) {
             return false;
@@ -176,44 +169,43 @@ impl ECP8 {
         self.x.reduce();
         self.y.mul(&self.z);
         self.y.reduce();
-        self.z.copy(&one);
+        self.z = one.clone();
     }
 
-    /* extract affine x as FP8 */
+    /// Extract affine x as FP8
     pub fn getx(&self) -> FP8 {
-        let mut W = ECP8::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP8::new_copy(&W.x);
+        W.getpx()
     }
 
-    /* extract affine y as FP8 */
+    /// Extract affine y as FP8
     pub fn gety(&self) -> FP8 {
-        let mut W = ECP8::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
-        return FP8::new_copy(&W.y);
+        W.getpy()
     }
 
-    /* extract projective x */
+    /// Extract projective x
     pub fn getpx(&self) -> FP8 {
-        return FP8::new_copy(&self.x);
+        self.x.clone()
     }
-    /* extract projective y */
+
+    /// Extract projective y
     pub fn getpy(&self) -> FP8 {
-        return FP8::new_copy(&self.y);
+        self.y.clone()
     }
-    /* extract projective z */
+
+    // Extract projective z
     pub fn getpz(&self) -> FP8 {
-        return FP8::new_copy(&self.z);
+        self.z.clone()
     }
 
-    /* convert to byte array */
+    /// Convert to byte array
     pub fn tobytes(&self, b: &mut [u8]) {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
-        let mut W = ECP8::new();
-        W.copy(self);
+        let mut W = self.clone();
 
         W.affine();
 
@@ -298,110 +290,109 @@ impl ECP8 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = Big::frombytes(&t);
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + mb]
         }
-        let mut rb = Big::frombytes(&t);
+        let rb = Big::frombytes(&t);
 
-        let mut ra4 = FP2::new_bigs(&ra, &rb);
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 2 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 3 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        let mut rb4 = FP2::new_bigs(&ra, &rb);
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        let mut ra8 = FP4::new_fp2s(&ra4, &rb4);
+        let ra8 = FP4::new_fp2s(ra4, rb4);
 
         for i in 0..mb {
             t[i] = b[i + 4 * mb]
         }
-        let mut ra = Big::frombytes(&t);
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 5 * mb]
         }
-        let mut rb = Big::frombytes(&t);
+        let rb = Big::frombytes(&t);
 
-        ra4.copy(&FP2::new_bigs(&ra, &rb));
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 6 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 7 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        rb4.copy(&FP2::new_bigs(&ra, &rb));
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        let mut rb8 = FP4::new_fp2s(&ra4, &rb4);
+        let rb8 = FP4::new_fp2s(ra4, rb4);
 
-        let rx = FP8::new_fp4s(&ra8, &rb8);
+        let rx = FP8::new_fp4s(ra8, rb8);
 
         for i in 0..mb {
             t[i] = b[i + 8 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 9 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        ra4.copy(&FP2::new_bigs(&ra, &rb));
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 10 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 11 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        rb4.copy(&FP2::new_bigs(&ra, &rb));
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        ra8.copy(&FP4::new_fp2s(&ra4, &rb4));
+        let ra8 = FP4::new_fp2s(ra4, rb4);
 
         for i in 0..mb {
             t[i] = b[i + 12 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 13 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        ra4.copy(&FP2::new_bigs(&ra, &rb));
+        let ra4 = FP2::new_bigs(ra, rb);
 
         for i in 0..mb {
             t[i] = b[i + 14 * mb]
         }
-        ra.copy(&Big::frombytes(&t));
+        let ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 15 * mb]
         }
-        rb.copy(&Big::frombytes(&t));
+        let rb = Big::frombytes(&t);
 
-        rb4.copy(&FP2::new_bigs(&ra, &rb));
+        let rb4 = FP2::new_bigs(ra, rb);
 
-        rb8.copy(&FP4::new_fp2s(&ra4, &rb4));
+        let rb8 = FP4::new_fp2s(ra4, rb4);
 
-        let ry = FP8::new_fp4s(&ra8, &rb8);
+        let ry = FP8::new_fp4s(ra8, rb8);
 
         return ECP8::new_fp8s(&rx, &ry);
     }
 
     /* convert this to hex string */
     pub fn tostring(&self) -> String {
-        let mut W = ECP8::new();
-        W.copy(self);
+        let mut W = self.clone();
         W.affine();
         if W.is_infinity() {
             return String::from("infinity");
@@ -411,9 +402,9 @@ impl ECP8 {
 
     /* Calculate RHS of twisted curve equation x^3+B/i */
     pub fn rhs(x: &FP8) -> FP8 {
-        let mut r = FP8::new_copy(x);
+        let mut r = x.clone();
         r.sqr();
-        let mut b = FP8::new_fp4(&FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B))));
+        let mut b = FP8::new_fp4(FP4::new_fp2(FP2::new_big(Big::new_ints(&rom::CURVE_B))));
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_i();
         }
@@ -430,22 +421,22 @@ impl ECP8 {
 
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
-        let mut iy = FP8::new_copy(&self.y);
+        let mut iy = self.getpy();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.times_i(); //iy.norm();
         }
 
-        let mut t0 = FP8::new_copy(&self.y);
+        let mut t0 = self.getpy();
         t0.sqr();
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i();
         }
-        let mut t1 = FP8::new_copy(&iy);
+        let mut t1 = iy.clone();
         t1.mul(&self.z);
-        let mut t2 = FP8::new_copy(&self.z);
+        let mut t2 = self.getpz();
         t2.sqr();
 
-        self.z.copy(&t0);
+        self.z = t0.clone();
         self.z.add(&t0);
         self.z.norm();
         self.z.dbl();
@@ -456,15 +447,15 @@ impl ECP8 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
-        let mut x3 = FP8::new_copy(&t2);
+        let mut x3 = t2.clone();
         x3.mul(&self.z);
 
-        let mut y3 = FP8::new_copy(&t0);
+        let mut y3 = t0.clone();
 
         y3.add(&t2);
         y3.norm();
         self.z.mul(&t1);
-        t1.copy(&t2);
+        t1 = t2.clone();
         t1.add(&t2);
         t2.add(&t1);
         t2.norm();
@@ -472,15 +463,15 @@ impl ECP8 {
         t0.norm(); //y^2-9bz^2
         y3.mul(&t0);
         y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
-        t1.copy(&self.x);
+        t1 = self.getpx();
         t1.mul(&iy); //
-        self.x.copy(&t0);
+        self.x = t0.clone();
         self.x.norm();
         self.x.mul(&t1);
         self.x.dbl(); //(y^2-9bz^2)xy2
 
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3.clone();
         self.y.norm();
 
         return 1;
@@ -489,21 +480,21 @@ impl ECP8 {
     /* self+=Q - return 0 for add, 1 for double, -1 for O */
     pub fn add(&mut self, Q: &ECP8) -> isize {
         let b = 3 * rom::CURVE_B_I;
-        let mut t0 = FP8::new_copy(&self.x);
+        let mut t0 = self.getpx();
         t0.mul(&Q.x); // x.Q.x
-        let mut t1 = FP8::new_copy(&self.y);
+        let mut t1 = self.getpy();
         t1.mul(&Q.y); // y.Q.y
 
-        let mut t2 = FP8::new_copy(&self.z);
+        let mut t2 = self.getpz();
         t2.mul(&Q.z);
-        let mut t3 = FP8::new_copy(&self.x);
+        let mut t3 = self.getpx();
         t3.add(&self.y);
         t3.norm(); //t3=X1+Y1
-        let mut t4 = FP8::new_copy(&Q.x);
+        let mut t4 = Q.getpx();
         t4.add(&Q.y);
         t4.norm(); //t4=X2+Y2
         t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
-        t4.copy(&t0);
+        t4 = t0.clone();
         t4.add(&t1); //t4=X1.X2+Y1.Y2
 
         t3.sub(&t4);
@@ -511,15 +502,15 @@ impl ECP8 {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
-        t4.copy(&self.y);
+        t4 = self.getpy();
         t4.add(&self.z);
         t4.norm(); //t4=Y1+Z1
-        let mut x3 = FP8::new_copy(&Q.y);
+        let mut x3 = Q.getpy();
         x3.add(&Q.z);
         x3.norm(); //x3=Y2+Z2
 
         t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
-        x3.copy(&t1); //
+        x3 = t1.clone(); //
         x3.add(&t2); //X3=Y1.Y2+Z1.Z2
 
         t4.sub(&x3);
@@ -527,14 +518,14 @@ impl ECP8 {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
-        x3.copy(&self.x);
+        x3 = self.getpx();
         x3.add(&self.z);
         x3.norm(); // x3=X1+Z1
-        let mut y3 = FP8::new_copy(&Q.x);
+        let mut y3 = Q.getpx();
         y3.add(&Q.z);
         y3.norm(); // y3=X2+Z2
         x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
-        y3.copy(&t0);
+        y3 = t0.clone();
         y3.add(&t2); // y3=X1.X2+Z1+Z2
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
@@ -543,7 +534,7 @@ impl ECP8 {
             t0.times_i(); // x.Q.x
             t1.times_i(); // y.Q.y
         }
-        x3.copy(&t0);
+        x3 = t0.clone();
         x3.add(&t0);
         t0.add(&x3);
         t0.norm();
@@ -551,7 +542,7 @@ impl ECP8 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
-        let mut z3 = FP8::new_copy(&t1);
+        let mut z3 = t1.clone();
         z3.add(&t2);
         z3.norm();
         t1.sub(&t2);
@@ -560,9 +551,9 @@ impl ECP8 {
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             y3.times_i();
         }
-        x3.copy(&y3);
+        x3 = y3.clone();
         x3.mul(&t4);
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.mul(&t1);
         x3.rsub(&t2);
         y3.mul(&t0);
@@ -572,11 +563,11 @@ impl ECP8 {
         z3.mul(&t4);
         z3.add(&t0);
 
-        self.x.copy(&x3);
+        self.x = x3.clone();
         self.x.norm();
-        self.y.copy(&y3);
+        self.y = y3.clone();
         self.y.norm();
-        self.z.copy(&z3);
+        self.z = z3.clone();
         self.z.norm();
 
         return 0;
@@ -584,33 +575,32 @@ impl ECP8 {
 
     /* set this-=Q */
     pub fn sub(&mut self, Q: &ECP8) -> isize {
-        let mut NQ = ECP8::new();
-        NQ.copy(Q);
+        let mut NQ = Q.clone();
         NQ.neg();
         let d = self.add(&NQ);
         return d;
     }
 
     pub fn frob_constants() -> [FP2; 3] {
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
 
-        let mut f0 = FP2::new_copy(&f);
+        let mut f0 = f.clone();
         f0.sqr();
-        let mut f2 = FP2::new_copy(&f0);
+        let mut f2 = f0.clone();
         f2.mul_ip();
         f2.norm();
-        let mut f1 = FP2::new_copy(&f2);
+        let mut f1 = f2.clone();
         f1.sqr();
         f2.mul(&f1);
 
         f2.mul_ip();
         f2.norm();
 
-        f1.copy(&f);
+        f1 = f.clone();
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f1.mul_ip();
             f1.inverse();
-            f0.copy(&f1);
+            f0 = f1.clone();
             f0.sqr();
         }
         f0.mul_ip();
@@ -650,11 +640,7 @@ impl ECP8 {
     /* self*=e */
     pub fn mul(&self, e: &Big) -> ECP8 {
         /* fixed size windows */
-        let mut mt = Big::new();
-        let mut t = Big::new();
         let mut P = ECP8::new();
-        let mut Q = ECP8::new();
-        let mut C = ECP8::new();
 
         if self.is_infinity() {
             return P;
@@ -675,29 +661,28 @@ impl ECP8 {
         let mut w: [i8; CT] = [0; CT];
 
         /* precompute table */
-        Q.copy(&self);
+        let mut Q = self.clone();
         Q.dbl();
 
-        W[0].copy(&self);
+        W[0] = self.clone();
 
         for i in 1..8 {
-            C.copy(&W[i - 1]);
-            W[i].copy(&C);
+            W[i] = W[i - 1].clone();
             W[i].add(&mut Q);
         }
 
         /* make exponent odd - add 2P if even, P if odd */
-        t.copy(&e);
+        let mut t = e.clone();
         let s = t.parity();
         t.inc(1);
         t.norm();
         let ns = t.parity();
-        mt.copy(&t);
+        let mut mt = t.clone();
         mt.inc(1);
         mt.norm();
         t.cmove(&mt, s);
         Q.cmove(&self, ns);
-        C.copy(&Q);
+        let mut C = Q.clone();
 
         let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -710,7 +695,7 @@ impl ECP8 {
         }
         w[nb] = (t.lastbits(5)) as i8;
 
-        P.copy(&W[((w[nb] as usize) - 1) / 2]);
+        P = W[((w[nb] as usize) - 1) / 2].clone();
         for i in (0..nb).rev() {
             Q.selector(&W, w[i] as i32);
             P.dbl();
@@ -730,7 +715,6 @@ impl ECP8 {
     // Side channel attack secure
 
     pub fn mul16(Q: &mut [ECP8], u: &[Big]) -> ECP8 {
-        let mut W = ECP8::new();
         let mut P = ECP8::new();
 
         let mut T1: [ECP8; 8] = [
@@ -777,22 +761,22 @@ impl ECP8 {
         let mut mt = Big::new();
 
         let mut t: [Big; 16] = [
-            Big::new_copy(&u[0]),
-            Big::new_copy(&u[1]),
-            Big::new_copy(&u[2]),
-            Big::new_copy(&u[3]),
-            Big::new_copy(&u[4]),
-            Big::new_copy(&u[5]),
-            Big::new_copy(&u[6]),
-            Big::new_copy(&u[7]),
-            Big::new_copy(&u[8]),
-            Big::new_copy(&u[9]),
-            Big::new_copy(&u[10]),
-            Big::new_copy(&u[11]),
-            Big::new_copy(&u[12]),
-            Big::new_copy(&u[13]),
-            Big::new_copy(&u[14]),
-            Big::new_copy(&u[15]),
+            u[0].clone(),
+            u[1].clone(),
+            u[2].clone(),
+            u[3].clone(),
+            u[4].clone(),
+            u[5].clone(),
+            u[6].clone(),
+            u[7].clone(),
+            u[8].clone(),
+            u[9].clone(),
+            u[10].clone(),
+            u[11].clone(),
+            u[12].clone(),
+            u[13].clone(),
+            u[14].clone(),
+            u[15].clone(),
         ];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
@@ -810,92 +794,92 @@ impl ECP8 {
             t[i].norm();
         }
 
-        T1[0].copy(&Q[0]);
-        W.copy(&T1[0]);
-        T1[1].copy(&W);
+        T1[0] = Q[0].clone();
+        let mut W = T1[0].clone();
+        T1[1] = W.clone();
         T1[1].add(&mut Q[1]); // Q[0]+Q[1]
-        T1[2].copy(&W);
+        T1[2] = W.clone();
         T1[2].add(&mut Q[2]);
-        W.copy(&T1[1]); // Q[0]+Q[2]
-        T1[3].copy(&W);
+        W = T1[1].clone(); // Q[0]+Q[2]
+        T1[3] = W.clone();
         T1[3].add(&mut Q[2]);
-        W.copy(&T1[0]); // Q[0]+Q[1]+Q[2]
-        T1[4].copy(&W);
+        W = T1[0].clone(); // Q[0]+Q[1]+Q[2]
+        T1[4] = W.clone();
         T1[4].add(&mut Q[3]);
-        W.copy(&T1[1]); // Q[0]+Q[3]
-        T1[5].copy(&W);
+        W = T1[1].clone(); // Q[0]+Q[3]
+        T1[5] = W.clone();
         T1[5].add(&mut Q[3]);
-        W.copy(&T1[2]); // Q[0]+Q[1]+Q[3]
-        T1[6].copy(&W);
+        W = T1[2].clone(); // Q[0]+Q[1]+Q[3]
+        T1[6] = W.clone();
         T1[6].add(&mut Q[3]);
-        W.copy(&T1[3]); // Q[0]+Q[2]+Q[3]
-        T1[7].copy(&W);
+        W = T1[3].clone(); // Q[0]+Q[2]+Q[3]
+        T1[7] = W.clone();
         T1[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
 
-        T2[0].copy(&Q[4]);
-        W.copy(&T2[0]);
-        T2[1].copy(&W);
+        T2[0] = Q[4].clone();
+        W = T2[0].clone();
+        T2[1] = W.clone();
         T2[1].add(&mut Q[5]); // Q[0]+Q[1]
-        T2[2].copy(&W);
+        T2[2] = W.clone();
         T2[2].add(&mut Q[6]);
-        W.copy(&T2[1]); // Q[0]+Q[2]
-        T2[3].copy(&W);
+        W = T2[1].clone(); // Q[0]+Q[2]
+        T2[3] = W.clone();
         T2[3].add(&mut Q[6]);
-        W.copy(&T2[0]); // Q[0]+Q[1]+Q[2]
-        T2[4].copy(&W);
+        W = T2[0].clone(); // Q[0]+Q[1]+Q[2]
+        T2[4] = W.clone();
         T2[4].add(&mut Q[7]);
-        W.copy(&T2[1]); // Q[0]+Q[3]
-        T2[5].copy(&W);
+        W = T2[1].clone(); // Q[0]+Q[3]
+        T2[5] = W.clone();
         T2[5].add(&mut Q[7]);
-        W.copy(&T2[2]); // Q[0]+Q[1]+Q[3]
-        T2[6].copy(&W);
+        W = T2[2].clone(); // Q[0]+Q[1]+Q[3]
+        T2[6] = W.clone();
         T2[6].add(&mut Q[7]);
-        W.copy(&T2[3]); // Q[0]+Q[2]+Q[3]
-        T2[7].copy(&W);
+        W = T2[3].clone(); // Q[0]+Q[2]+Q[3]
+        T2[7] = W.clone();
         T2[7].add(&mut Q[7]); // Q[0]+Q[1]+Q[2]+Q[3]
 
-        T3[0].copy(&Q[8]);
-        W.copy(&T3[0]);
-        T3[1].copy(&W);
+        T3[0] = Q[8].clone();
+        W = T3[0].clone();
+        T3[1] = W.clone();
         T3[1].add(&mut Q[9]); // Q[0]+Q[1]
-        T3[2].copy(&W);
+        T3[2] = W.clone();
         T3[2].add(&mut Q[10]);
-        W.copy(&T3[1]); // Q[0]+Q[2]
-        T3[3].copy(&W);
+        W = T3[1].clone(); // Q[0]+Q[2]
+        T3[3] = W.clone();
         T3[3].add(&mut Q[10]);
-        W.copy(&T3[0]); // Q[0]+Q[1]+Q[2]
-        T3[4].copy(&W);
+        W = T3[0].clone(); // Q[0]+Q[1]+Q[2]
+        T3[4] = W.clone();
         T3[4].add(&mut Q[11]);
-        W.copy(&T3[1]); // Q[0]+Q[3]
-        T3[5].copy(&W);
+        W = T3[1].clone(); // Q[0]+Q[3]
+        T3[5] = W.clone();
         T3[5].add(&mut Q[11]);
-        W.copy(&T3[2]); // Q[0]+Q[1]+Q[3]
-        T3[6].copy(&W);
+        W = T3[2].clone(); // Q[0]+Q[1]+Q[3]
+        T3[6] = W.clone();
         T3[6].add(&mut Q[11]);
-        W.copy(&T3[3]); // Q[0]+Q[2]+Q[3]
-        T3[7].copy(&W);
+        W = T3[3].clone(); // Q[0]+Q[2]+Q[3]
+        T3[7] = W.clone();
         T3[7].add(&mut Q[11]); // Q[0]+Q[1]+Q[2]+Q[3]
 
-        T4[0].copy(&Q[12]);
-        W.copy(&T4[0]);
-        T4[1].copy(&W);
+        T4[0] = Q[12].clone();
+        W = T4[0].clone();
+        T4[1] = W.clone();
         T4[1].add(&mut Q[13]); // Q[0]+Q[1]
-        T4[2].copy(&W);
+        T4[2] = W.clone();
         T4[2].add(&mut Q[14]);
-        W.copy(&T4[1]); // Q[0]+Q[2]
-        T4[3].copy(&W);
+        W = T4[1].clone(); // Q[0]+Q[2]
+        T4[3] = W.clone();
         T4[3].add(&mut Q[14]);
-        W.copy(&T4[0]); // Q[0]+Q[1]+Q[2]
-        T4[4].copy(&W);
+        W = T4[0].clone(); // Q[0]+Q[1]+Q[2]
+        T4[4] = W.clone();
         T4[4].add(&mut Q[15]);
-        W.copy(&T4[1]); // Q[0]+Q[3]
-        T4[5].copy(&W);
+        W = T4[1].clone(); // Q[0]+Q[3]
+        T4[5] = W.clone();
         T4[5].add(&mut Q[15]);
-        W.copy(&T4[2]); // Q[0]+Q[1]+Q[3]
-        T4[6].copy(&W);
+        W = T4[2].clone(); // Q[0]+Q[1]+Q[3]
+        T4[6] = W.clone();
         T4[6].add(&mut Q[15]);
-        W.copy(&T4[3]); // Q[0]+Q[2]+Q[3]
-        T4[7].copy(&W);
+        W = T4[3].clone(); // Q[0]+Q[2]+Q[3]
+        T4[7] = W.clone();
         T4[7].add(&mut Q[15]); // Q[0]+Q[1]+Q[2]+Q[3]
 
         // Make it odd
@@ -1005,19 +989,19 @@ impl ECP8 {
         }
 
         // apply correction
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[0]);
         P.cmove(&W, pb1);
 
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[4]);
         P.cmove(&W, pb2);
 
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[8]);
         P.cmove(&W, pb3);
 
-        W.copy(&P);
+        W = P.clone();
         W.sub(&mut Q[12]);
         P.cmove(&W, pb4);
 
@@ -1029,46 +1013,46 @@ impl ECP8 {
     pub fn generator() -> ECP8 {
         return ECP8::new_fp8s(
             &FP8::new_fp4s(
-                &FP4::new_fp2s(
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PXAAA),
-                        &Big::new_ints(&rom::CURVE_PXAAB),
+                FP4::new_fp2s(
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PXAAA),
+                        Big::new_ints(&rom::CURVE_PXAAB),
                     ),
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PXABA),
-                        &Big::new_ints(&rom::CURVE_PXABB),
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PXABA),
+                        Big::new_ints(&rom::CURVE_PXABB),
                     ),
                 ),
-                &FP4::new_fp2s(
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PXBAA),
-                        &Big::new_ints(&rom::CURVE_PXBAB),
+                FP4::new_fp2s(
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PXBAA),
+                        Big::new_ints(&rom::CURVE_PXBAB),
                     ),
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PXBBA),
-                        &Big::new_ints(&rom::CURVE_PXBBB),
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PXBBA),
+                        Big::new_ints(&rom::CURVE_PXBBB),
                     ),
                 ),
             ),
             &FP8::new_fp4s(
-                &FP4::new_fp2s(
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PYAAA),
-                        &Big::new_ints(&rom::CURVE_PYAAB),
+                FP4::new_fp2s(
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PYAAA),
+                        Big::new_ints(&rom::CURVE_PYAAB),
                     ),
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PYABA),
-                        &Big::new_ints(&rom::CURVE_PYABB),
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PYABA),
+                        Big::new_ints(&rom::CURVE_PYABB),
                     ),
                 ),
-                &FP4::new_fp2s(
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PYBAA),
-                        &Big::new_ints(&rom::CURVE_PYBAB),
+                FP4::new_fp2s(
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PYBAA),
+                        Big::new_ints(&rom::CURVE_PYBAB),
                     ),
-                    &FP2::new_bigs(
-                        &Big::new_ints(&rom::CURVE_PYBBA),
-                        &Big::new_ints(&rom::CURVE_PYBBB),
+                    FP2::new_bigs(
+                        Big::new_ints(&rom::CURVE_PYBBA),
+                        Big::new_ints(&rom::CURVE_PYBBB),
                     ),
                 ),
             ),
@@ -1084,7 +1068,7 @@ impl ECP8 {
         let one = Big::new_int(1);
 
         loop {
-            let X = FP8::new_fp4(&FP4::new_fp2(&FP2::new_bigs(&one, &x)));
+            let X = FP8::new_fp4(FP4::new_fp2(FP2::new_bigs(one.clone(), x.clone())));
             Q = ECP8::new_fp8(&X);
             if !Q.is_infinity() {
                 break;
diff --git a/src/ff.rs b/src/ff.rs
index 316c156..0f23b87 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -39,6 +39,7 @@ pub const P_OMASK: Chunk = (-1) << (P_MBITS % big::BASEBITS);
 pub const P_FEXCESS: Chunk = 1 << (big::BASEBITS * big::NLEN - P_MBITS - 1);
 pub const P_TBITS: usize = P_MBITS % big::BASEBITS;
 
+#[derive(Clone)]
 pub struct FF {
     v: Vec<Big>,
     length: usize,
@@ -98,14 +99,14 @@ impl FF {
     /* copy from FF b */
     pub fn copy(&mut self, b: &FF) {
         for i in 0..self.length {
-            self.v[i].copy(&b.v[i]);
+            self.v[i] = b.v[i].clone();
         }
     }
 
     /* 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[b.length + i] = b.v[i].clone();
             self.v[i].zero();
         }
     }
@@ -113,7 +114,7 @@ impl FF {
     /* x=y */
     pub fn dscopy(&mut self, b: &FF) {
         for i in 0..b.length {
-            self.v[i].copy(&b.v[i]);
+            self.v[i] = b.v[i].clone();
             self.v[b.length + i].zero();
         }
     }
@@ -121,7 +122,7 @@ impl FF {
     /* 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]);
+            self.v[i] = b.v[self.length + i].clone();
         }
     }
 
@@ -146,8 +147,8 @@ impl FF {
     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);
+            t = self.v[i + n].clone();
+            self.v[i] = t.clone();
             self.v[i + n].zero();
         }
     }
@@ -156,8 +157,8 @@ impl FF {
     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);
+            t = self.v[i].clone();
+            self.v[n + i] = t.clone();
             self.v[i].zero();
         }
     }
@@ -191,7 +192,7 @@ impl FF {
     /* 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] = x.v[xp + i].clone();
             self.v[vp + i].add(&y.v[yp + i]);
         }
     }
@@ -206,7 +207,7 @@ impl FF {
     pub fn rsinc(&mut self, n: usize) {
         let mut t = Big::new();
         for i in 0..n {
-            t.copy(&self.v[i]);
+            t = self.v[i].clone();
             self.v[n + i].add(&t);
         }
     }
@@ -214,7 +215,7 @@ impl FF {
     /* 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] = x.v[xp + i].clone();
             self.v[vp + i].sub(&y.v[yp + i]);
         }
     }
@@ -357,8 +358,8 @@ impl FF {
         n: usize,
     ) {
         if n == 1 {
-            let xx = Big::new_copy(&x.v[xp]);
-            let yy = Big::new_copy(&y.v[yp]);
+            let xx = x.v[xp].clone();
+            let yy = y.v[yp].clone();
             let mut d = Big::mul(&xx, &yy);
             self.v[vp + 1] = d.split(8 * big::MODBYTES);
             self.v[vp].dcopy(&d);
@@ -384,9 +385,9 @@ impl FF {
 
     fn karsqr(&mut self, vp: usize, x: &FF, xp: usize, t: *mut FF, tp: usize, n: usize) {
         if n == 1 {
-            let xx = Big::new_copy(&x.v[xp]);
+            let xx = x.v[xp].clone();
             let mut d = Big::sqr(&xx);
-            self.v[vp + 1].copy(&d.split(8 * big::MODBYTES));
+            self.v[vp + 1] = d.split(8 * big::MODBYTES);
             self.v[vp].dcopy(&d);
             return;
         }
@@ -416,7 +417,7 @@ impl FF {
     ) {
         if n == 1 {
             /* only calculate bottom half of product */
-            self.v[vp].copy(&Big::smul(&x.v[xp], &y.v[yp]));
+            self.v[vp] = Big::smul(&x.v[xp], &y.v[yp]);
             return;
         }
         let nd2 = n / 2;
@@ -643,7 +644,7 @@ impl FF {
         if n == 1 {
             let mut d = DBig::new_scopy(&(self.v[0]));
             d.shl(big::NLEN * (big::BASEBITS as usize));
-            self.v[0].copy(&d.dmod(&(m.v[0])));
+            self.v[0] = d.dmod(&(m.v[0]));
         } else {
             let mut d = FF::new_int(2 * n);
             d.dsucopy(&self);
@@ -655,11 +656,11 @@ impl FF {
         let n = m.length;
         if n == 1 {
             let mut d = DBig::new_scopy(&(self.v[0]));
-            self.v[0].copy(&Big::monty(
+            self.v[0] = Big::monty(
                 &(m.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - md.v[0].w[0],
                 &mut d,
-            ));
+            );
         } else {
             let mut d = FF::new_int(2 * n);
             self.rmod(m);
@@ -684,7 +685,7 @@ impl FF {
         let mut u = FF::new_int(n);
 
         u.zero();
-        u.v[0].copy(&self.v[0]);
+        u.v[0] = self.v[0].clone();
         u.v[0].invmod2m();
 
         let mut i = 1;
@@ -720,11 +721,11 @@ impl FF {
     pub fn random(&mut self, rng: &mut RAND) {
         let n = self.length;
         for i in 0..n {
-            self.v[i].copy(&Big::random(rng))
+            self.v[i] = Big::random(rng)
         }
         /* make sure top bit is 1 */
         while self.v[n - 1].nbits() < (big::MODBYTES as usize) * 8 {
-            self.v[n - 1].copy(&Big::random(rng));
+            self.v[n - 1] = Big::random(rng);
         }
     }
 
@@ -734,7 +735,7 @@ impl FF {
         let mut d = FF::new_int(2 * n);
 
         for i in 0..2 * n {
-            d.v[i].copy(&Big::random(rng));
+            d.v[i] = Big::random(rng);
         }
         self.copy(&d.dmod(p));
     }
@@ -747,11 +748,11 @@ impl FF {
         let n = p.length;
         if n == 1 {
             let mut d = Big::mul(&self.v[0], &y.v[0]);
-            self.v[0].copy(&Big::monty(
+            self.v[0] = Big::monty(
                 &(p.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                 &mut d,
-            ));
+            );
         } else {
             let mut d = FF::mul(&self, y);
             self.copy(&d.reduce(p, nd));
@@ -766,11 +767,11 @@ impl FF {
         let n = p.length;
         if n == 1 {
             let mut d = Big::sqr(&self.v[0]);
-            self.v[0].copy(&Big::monty(
+            self.v[0] = Big::monty(
                 &(p.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                 &mut d,
-            ));
+            );
         } else {
             let mut d = FF::sqr(&self);
             d.norm();
diff --git a/src/fp.rs b/src/fp.rs
index 95cddff..4437d21 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -26,7 +26,7 @@ use super::rom;
 use std::str::FromStr;
 use types::ModType;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP {
     pub x: Big,
     pub xes: i32,
@@ -54,7 +54,7 @@ pub use super::rom::{MOD8, MODBITS, MODTYPE, SH};
 use std::fmt;
 use std::str::SplitWhitespace;
 
-pub const FEXCESS: i32 = ((1 as i32) << SH) - 1;
+pub const FEXCESS: i32 = (1 << SH) - 1;
 pub const OMASK: Chunk = (-1) << (MODBITS % big::BASEBITS);
 pub const TBITS: usize = MODBITS % big::BASEBITS; // Number of active bits in top word
 pub const TMASK: Chunk = (1 << TBITS) - 1;
@@ -75,25 +75,17 @@ impl FP {
         return f;
     }
 
-    pub fn new_copy(y: &FP) -> FP {
-        let mut f = FP::new();
-        f.x.copy(&(y.x));
-        f.xes = y.xes;
-        return f;
-    }
-
-    pub fn new_big(y: &Big) -> FP {
-        let mut f = FP::new();
-        f.x.copy(y);
+    pub fn new_big(x: Big) -> FP {
+        let mut f = FP { x, xes: 1 };
         f.nres();
-        return f;
+        f
     }
 
     pub fn nres(&mut self) {
         if MODTYPE != ModType::PseudoMersenne && MODTYPE != ModType::GeneralisedMersenne {
             let r = Big::new_ints(&rom::R2MODP);
             let mut d = Big::mul(&(self.x), &r);
-            self.x.copy(&FP::modulo(&mut d));
+            self.x = FP::modulo(&mut d);
             self.xes = 2;
         } else {
             self.xes = 1;
@@ -124,7 +116,7 @@ impl FP {
             let mut d = DBig::new_scopy(&(self.x));
             return FP::modulo(&mut d);
         }
-        Big::new_copy(&(self.x))
+        self.x.clone()
     }
 
     // reduce a DBig to a Big using the appropriate form of the modulus
@@ -206,7 +198,7 @@ impl FP {
     // reduce this mod Modulus
     pub fn reduce(&mut self) {
         let mut m = Big::new_ints(&rom::MODULUS);
-        let mut r = Big::new_copy(&m);
+        let mut r = m.clone();
         let mut sb: usize;
         self.x.norm();
         if self.xes > 16 {
@@ -232,20 +224,14 @@ impl FP {
 
     // test this=0?
     pub fn iszilch(&self) -> bool {
-        let mut a = FP::new_copy(self);
+        let mut a = self.clone();
         a.reduce();
         a.x.iszilch()
     }
 
-    // copy from FP b
-    pub fn copy(&mut self, b: &FP) {
-        self.x.copy(&(b.x));
-        self.xes = b.xes;
-    }
-
     // copy from Big b
     pub fn bcopy(&mut self, b: &Big) {
-        self.x.copy(&b);
+        self.x = b.clone();
         self.nres();
     }
 
@@ -289,7 +275,7 @@ impl FP {
         }
 
         let mut d = Big::mul(&(self.x), &(b.x));
-        self.x.copy(&FP::modulo(&mut d));
+        self.x = FP::modulo(&mut d);
         self.xes = 2;
     }
 
@@ -348,7 +334,7 @@ impl FP {
 
         if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
             let mut d = self.x.pxmul(cc);
-            self.x.copy(&FP::modulo(&mut d));
+            self.x = FP::modulo(&mut d);
             self.xes = 2
         } else {
             if self.xes * (cc as i32) <= FEXCESS {
@@ -373,7 +359,7 @@ impl FP {
         }
 
         let mut d = Big::sqr(&(self.x));
-        self.x.copy(&FP::modulo(&mut d));
+        self.x = FP::modulo(&mut d);
         self.xes = 2
     }
 
@@ -397,7 +383,7 @@ impl FP {
 
     // self-=b
     pub fn sub(&mut self, b: &FP) {
-        let mut n = FP::new_copy(b);
+        let mut n = b.clone();
         n.neg();
         self.add(&n);
     }
@@ -438,37 +424,36 @@ impl FP {
             FP::new(),
         ];
         // phase 1
-        let mut t = FP::new();
-        xp[0].copy(&self); // 1
-        xp[1].copy(&self);
+        xp[0] = self.clone(); // 1
+        xp[1] = self.clone();
         xp[1].sqr(); // 2
-        t.copy(&xp[1]);
-        xp[2].copy(&t);
+        let mut t = xp[1].clone();
+        xp[2] = t.clone();
         xp[2].mul(&self); // 3
-        t.copy(&xp[2]);
-        xp[3].copy(&t);
+        t = xp[2].clone();
+        xp[3] = t.clone();
         xp[3].sqr(); // 6
-        t.copy(&xp[3]);
-        xp[4].copy(&t);
+        t = xp[3].clone();
+        xp[4] = t.clone();
         xp[4].sqr(); // 12
-        t.copy(&xp[4]);
+        t = xp[4].clone();
         t.mul(&xp[2]);
-        xp[5].copy(&t); // 15
-        t.copy(&xp[5]);
-        xp[6].copy(&t);
+        xp[5] = t.clone(); // 15
+        t = xp[5].clone();
+        xp[6] = t.clone();
         xp[6].sqr(); // 30
-        t.copy(&xp[6]);
-        xp[7].copy(&t);
+        t = xp[6].clone();
+        xp[7] = t.clone();
         xp[7].sqr(); // 60
-        t.copy(&xp[7]);
-        xp[8].copy(&t);
+        t = xp[7].clone();
+        xp[8] = t.clone();
         xp[8].sqr(); // 120
-        t.copy(&xp[8]);
-        xp[9].copy(&t);
+        t = xp[8].clone();
+        xp[9] = t.clone();
         xp[9].sqr(); // 240
-        t.copy(&xp[9]);
+        t = xp[9].clone();
         t.mul(&xp[5]);
-        xp[10].copy(&t); // 255
+        xp[10] = t.clone(); // 255
 
         let mut n = MODBITS as isize;
         let c: isize;
@@ -499,7 +484,7 @@ impl FP {
             while ac[i] > k {
                 i -= 1;
             }
-            key.copy(&xp[i]);
+            key = xp[i].clone();
             k -= ac[i];
         }
         while k != 0 {
@@ -511,31 +496,30 @@ impl FP {
             k -= ac[i];
         }
         // phase 2
-        t.copy(&xp[2]);
-        xp[1].copy(&t);
-        t.copy(&xp[5]);
-        xp[2].copy(&t);
-        t.copy(&xp[10]);
-        xp[3].copy(&t);
+        t = xp[2].clone();
+        xp[1] = t.clone();
+        t = xp[5].clone();
+        xp[2] = t.clone();
+        t = xp[10].clone();
+        xp[3] = t.clone();
 
         let mut j = 3;
         let mut m = 8;
         let nw = n - bw;
-        let mut r = FP::new();
 
         while 2 * m < nw {
-            t.copy(&xp[j]);
+            t = xp[j].clone();
             j += 1;
             for _ in 0..m {
                 t.sqr();
             }
-            r.copy(&xp[j - 1]);
+            let mut r = xp[j - 1].clone();
             r.mul(&t);
-            xp[j].copy(&r);
+            xp[j] = r.clone();
             m *= 2;
         }
         let mut lo = nw - m;
-        r.copy(&xp[j]);
+        let mut r = xp[j].clone();
 
         while lo != 0 {
             m /= 2;
@@ -544,11 +528,11 @@ impl FP {
                 continue;
             }
             lo -= m;
-            t.copy(&r);
+            t = r.clone();
             for _ in 0..m {
                 t.sqr();
             }
-            r.copy(&t);
+            r = t.clone();
             r.mul(&xp[j]);
         }
         // phase 3
@@ -560,7 +544,7 @@ impl FP {
         }
         if MODTYPE == ModType::GeneralisedMersenne {
             // Goldilocks ONLY
-            key.copy(&r);
+            key = r.clone();
             r.sqr();
             r.mul(&self);
             for _ in 0..=n {
@@ -575,7 +559,7 @@ impl FP {
         if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
             let mut y = self.fpow();
             if MOD8 == 5 {
-                let mut t = FP::new_copy(self);
+                let mut t = self.clone();
                 t.sqr();
                 self.mul(&t);
                 y.sqr();
@@ -590,14 +574,14 @@ impl FP {
             m2.dec(2);
             m2.norm();
             let inv = self.pow(&mut m2);
-            self.copy(&inv);
+            *self = inv.clone();
         }
     }
 
     // return TRUE if self==a
     pub fn equals(&self, a: &FP) -> bool {
-        let mut f = FP::new_copy(self);
-        let mut s = FP::new_copy(a);
+        let mut f = self.clone();
+        let mut s = a.clone();
         f.reduce();
         s.reduce();
         if Big::comp(&(f.x), &(s.x)) == 0 {
@@ -630,7 +614,7 @@ impl FP {
         let mut w: [i8; CT] = [0; CT];
 
         self.norm();
-        let mut t = Big::new_copy(e);
+        let mut t = e.clone();
         t.norm();
         let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -642,15 +626,13 @@ impl FP {
             t.fshr(4);
         }
         tb[0].one();
-        tb[1].copy(&self);
+        tb[1] = self.clone();
 
-        let mut c = FP::new();
         for i in 2..16 {
-            c.copy(&tb[i - 1]);
-            tb[i].copy(&c);
+            tb[i] = tb[i - 1].clone();
             tb[i].mul(&self);
         }
-        let mut r = FP::new_copy(&tb[w[nb - 1] as usize]);
+        let mut r = tb[w[nb - 1] as usize].clone();
         for i in (0..nb - 1).rev() {
             r.sqr();
             r.sqr();
@@ -668,7 +650,7 @@ impl FP {
 
         if MOD8 == 5 {
             let v: FP;
-            let mut i = FP::new_copy(self);
+            let mut i = self.clone();
             i.x.shl(1);
             if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
                 v = i.fpow();
@@ -682,7 +664,7 @@ impl FP {
             i.mul(&v);
             i.mul(&v);
             i.x.dec(1);
-            let mut r = FP::new_copy(self);
+            let mut r = self.clone();
             r.mul(&v);
             r.mul(&i);
             r.reduce();
diff --git a/src/fp12.rs b/src/fp12.rs
index e0dc648..bac4b65 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -32,7 +32,7 @@ pub const SPARSER: usize = 2;
 pub const SPARSE: usize = 3;
 pub const DENSE: usize = 4;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP12 {
     a: FP4,
     b: FP4,
@@ -61,47 +61,36 @@ impl FP12 {
     }
 
     pub fn gettype(&self) -> usize {
-        return self.stype;
+        self.stype
     }
 
     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();
-        if a == 1 {
-            f.stype = ONE;
-        } else {
-            f.stype = SPARSER;
-        }
-        return f;
-    }
+        let stype = if a == 1 { ONE } else { SPARSER };
 
-    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);
-        f.stype = x.stype;
-        return f;
+        FP12 {
+            a: FP4::new_int(a),
+            b: FP4::new(),
+            c: FP4::new(),
+            stype,
+        }
     }
 
-    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);
-        g.stype = DENSE;
-        return g;
+    pub fn new_fp4s(a: FP4, b: FP4, c: FP4) -> FP12 {
+        FP12 {
+            a,
+            b,
+            c,
+            stype: DENSE,
+        }
     }
 
-    pub fn new_fp4(d: &FP4) -> FP12 {
-        let mut g = FP12::new();
-        g.a.copy(d);
-        g.b.zero();
-        g.c.zero();
-        g.stype = SPARSER;
-        return g;
+    pub fn new_fp4(a: FP4) -> FP12 {
+        FP12 {
+            a,
+            b: FP4::new(),
+            c: FP4::new(),
+            stype: SPARSER,
+        }
     }
 
     /* reduce components mod Modulus */
@@ -157,7 +146,7 @@ impl FP12 {
         self.cmove(&g[6], FP12::teq(babs, 6));
         self.cmove(&g[7], FP12::teq(babs, 7));
 
-        let mut invf = FP12::new_copy(self);
+        let mut invf = self.clone();
         invf.conj();
         self.cmove(&invf, (m & 1) as isize);
     }
@@ -174,23 +163,15 @@ impl FP12 {
     }
 
     pub fn geta(&self) -> FP4 {
-        self.a
+        self.a.clone()
     }
 
     pub fn getb(&self) -> FP4 {
-        self.b
+        self.b.clone()
     }
 
     pub fn getc(&mut self) -> FP4 {
-        self.c
-    }
-
-    /* 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);
-        self.stype = x.stype;
+        self.c.clone()
     }
 
     /* set self=1 */
@@ -218,13 +199,12 @@ impl FP12 {
 
     /* 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();
+        let mut a = self.geta();
+        let mut b = self.getc();
+        let mut c = self.getb();
 
         self.a.sqr();
-        d.copy(&self.a);
+        let mut d = self.geta();
         d.add(&self.a);
         self.a.add(&d);
 
@@ -236,13 +216,13 @@ impl FP12 {
         b.sqr();
         b.times_i();
 
-        d.copy(&b);
+        d = b.clone();
         d.add(&b);
         b.add(&d);
         b.norm();
 
         c.sqr();
-        d.copy(&c);
+        d = c.clone();
         d.add(&c);
         c.add(&d);
         c.norm();
@@ -264,10 +244,10 @@ impl FP12 {
             return;
         }
 
-        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);
+        let mut a = self.geta();
+        let mut b = self.getb();
+        let mut c = self.getc();
+        let mut d = self.geta();
 
         a.sqr();
         b.mul(&self.c);
@@ -282,7 +262,7 @@ impl FP12 {
         self.c.norm();
         self.c.sqr();
 
-        self.a.copy(&a);
+        self.a = a.clone();
         a.add(&b);
         a.norm();
         a.add(&c);
@@ -295,7 +275,7 @@ impl FP12 {
 
         self.a.add(&b);
 
-        self.b.copy(&c);
+        self.b = c.clone();
         self.b.add(&d);
         self.c.add(&a);
         if self.stype == SPARSER {
@@ -308,12 +288,10 @@ impl FP12 {
 
     /* FP12 full multiplication self=self*y */
     pub fn mul(&mut self, y: &FP12) {
-        let mut z0 = FP4::new_copy(&self.a);
-        let mut z1 = FP4::new();
-        let mut z2 = FP4::new_copy(&self.b);
-        let mut z3 = FP4::new();
-        let mut t0 = FP4::new_copy(&self.a);
-        let mut t1 = FP4::new_copy(&y.a);
+        let mut z0 = self.geta();
+        let mut z2 = self.getb();
+        let mut t0 = self.geta();
+        let mut t1 = y.a.clone();
 
         z0.mul(&y.a);
         z2.mul(&y.b);
@@ -324,46 +302,46 @@ impl FP12 {
         t0.norm();
         t1.norm();
 
-        z1.copy(&t0);
+        let mut z1 = t0.clone();
         z1.mul(&t1);
-        t0.copy(&self.b);
+        t0 = self.getb();
         t0.add(&self.c);
-        t1.copy(&y.b);
+        t1 = y.getb();
         t1.add(&y.c);
 
         t0.norm();
         t1.norm();
 
-        z3.copy(&t0);
+        let mut z3 = t0.clone();
         z3.mul(&t1);
 
-        t0.copy(&z0);
+        t0 = z0.clone();
         t0.neg();
-        t1.copy(&z2);
+        t1 = z2.clone();
         t1.neg();
 
         z1.add(&t0);
-        self.b.copy(&z1);
+        self.b = z1.clone();
         self.b.add(&t1);
 
         z3.add(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.a);
+        t0 = self.geta();
         t0.add(&self.c);
         t0.norm();
-        t1.copy(&y.a);
+        t1 = y.geta();
         t1.add(&y.c);
         t1.norm();
         t0.mul(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.c);
+        t0 = self.getc();
         t0.mul(&y.c);
-        t1.copy(&t0);
+        t1 = t0.clone();
         t1.neg();
 
-        self.c.copy(&z2);
+        self.c = z2;
         self.c.add(&t1);
         z3.add(&t1);
         t0.times_i();
@@ -371,7 +349,7 @@ impl FP12 {
         z3.norm();
 
         z3.times_i();
-        self.a.copy(&z0);
+        self.a = z0;
         self.a.add(&z3);
         self.stype = DENSE;
         self.norm();
@@ -382,80 +360,75 @@ impl FP12 {
     /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP12) {
         if self.stype == ONE {
-            self.copy(&y);
+            *self = y.clone();
             return;
         }
         if y.stype == ONE {
             return;
         }
         if y.stype >= SPARSE {
-            let mut z0 = FP4::new_copy(&self.a);
-            let mut z1 = FP4::new_int(0);
-            let mut z2 = FP4::new_int(0);
-            let mut z3 = FP4::new_int(0);
+            let mut z0 = self.geta();
+            let mut z2 = FP4::new();
             z0.mul(&y.a);
 
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP2::new_int(0);
-                    let mut gb = FP2::new_int(0);
-
-                    gb.copy(&self.b.getb());
+                    let mut gb = self.b.getb();
                     gb.mul(&y.b.getb());
-                    ga.zero();
+                    let mut ga = FP2::new();
                     if y.stype != SPARSE {
-                        ga.copy(&self.b.getb());
+                        ga = self.b.getb();
                         ga.mul(&y.b.geta());
                     }
                     if self.stype != SPARSE {
-                        ga.copy(&self.b.geta());
+                        ga = self.b.geta();
                         ga.mul(&y.b.getb());
                     }
                     z2.set_fp2s(&ga, &gb);
                     z2.times_i();
                 } else {
-                    z2.copy(&self.b);
+                    z2 = self.getb();
                     z2.mul(&y.b);
                 }
             } else {
-                z2.copy(&self.b);
+                z2 = self.getb();
                 z2.mul(&y.b);
             }
-            let mut t0 = FP4::new_copy(&self.a);
-            let mut t1 = FP4::new_copy(&y.a);
+            let mut t0 = self.geta();
+            let mut t1 = y.a.clone();
             t0.add(&self.b);
             t0.norm();
             t1.add(&y.b);
             t1.norm();
 
-            z1.copy(&t0);
+            let mut z1 = t0.clone();
             z1.mul(&t1);
-            t0.copy(&self.b);
+            t0 = self.getb();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.b);
+            t1 = y.getb();
             t1.add(&y.c);
             t1.norm();
 
-            z3.copy(&t0);
+            let mut z3 = t0.clone();
             z3.mul(&t1);
 
-            t0.copy(&z0);
+            t0 = z0.clone();
             t0.neg();
-            t1.copy(&z2);
+            t1 = z2.clone();
             t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1);
+            self.b = z1.clone();
             self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a);
+            t0 = self.geta();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.a);
+            t1 = y.geta();
             t1.add(&y.c);
             t1.norm();
 
@@ -464,40 +437,37 @@ impl FP12 {
 
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP2::new_int(0);
-                    let mut gb = FP2::new_int(0);
-
-                    ga.copy(&self.c.geta());
+                    let mut ga = self.c.geta();
                     ga.mul(&y.c.geta());
-                    gb.zero();
+                    let mut gb = FP2::new();
                     if y.stype != SPARSE {
-                        gb.copy(&self.c.geta());
+                        gb = self.c.geta();
                         gb.mul(&y.c.getb());
                     }
                     if self.stype != SPARSE {
-                        gb.copy(&self.c.getb());
+                        gb = self.c.getb();
                         gb.mul(&y.c.geta());
                     }
                     t0.set_fp2s(&ga, &gb);
                 } else {
-                    t0.copy(&self.c);
+                    t0 = self.getc();
                     t0.mul(&y.c);
                 }
             } else {
-                t0.copy(&self.c);
+                t0 = self.getc();
                 t0.mul(&y.c);
             }
-            t1.copy(&t0);
+            t1 = t0.clone();
             t1.neg();
 
-            self.c.copy(&z2);
+            self.c = z2.clone();
             self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0);
+            self.a = z0.clone();
             self.a.add(&z3);
         } else {
             if self.stype == SPARSER {
@@ -506,11 +476,10 @@ impl FP12 {
             }
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 // dense by sparser - 13m
-                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_int(0);
-                let mut t1 = FP4::new_copy(&y.a);
+                let mut z0 = self.geta();
+                let mut z2 = self.getb();
+                let mut z3 = self.getb();
+                let mut t1 = y.a.clone();
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -524,9 +493,9 @@ impl FP12 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0);
+                let mut t0 = z0.clone();
                 t0.neg();
-                t1.copy(&z2);
+                t1 = z2.clone();
                 t1.neg();
 
                 self.b.add(&t0);
@@ -535,70 +504,66 @@ impl FP12 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2);
+                self.c = z2.clone();
                 self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0.clone();
                 self.a.add(&z3);
             }
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
-                let mut z0 = FP4::new_copy(&self.a);
-                let mut z1 = FP4::new();
-                let mut z2 = FP4::new();
-                let mut z3 = FP4::new();
-                let mut t0 = FP4::new_copy(&self.a);
-                let mut t1 = FP4::new();
+                let mut z0 = self.geta();
+                let mut t0 = self.geta();
 
                 z0.mul(&y.a);
                 t0.add(&self.b);
                 t0.norm();
 
-                z1.copy(&t0);
+                let mut z1 = t0.clone();
                 z1.mul(&y.a);
-                t0.copy(&self.b);
+                t0 = self.getb();
                 t0.add(&self.c);
                 t0.norm();
 
-                z3.copy(&t0);
+                let mut z3 = t0.clone();
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0);
+                t0 = z0.clone();
                 t0.neg();
                 z1.add(&t0);
-                self.b.copy(&z1);
-                z2.copy(&t0);
+                self.b = z1.clone();
+                let mut z2 = t0.clone();
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
-                t1.copy(&y.a);
+                let mut t1 = y.geta();
                 t1.add(&y.c);
                 t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
-                t0.copy(&self.c);
+                t0 = self.getc();
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0);
+                t1 = t0.clone();
                 t1.neg();
 
-                self.c.copy(&z2);
+                self.c = z2;
                 self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0;
                 self.a.add(&z3);
             }
         }
@@ -609,49 +574,49 @@ impl FP12 {
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP12) {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
-            let mut w1 = FP2::new_copy(&self.a.geta());
-            let mut w2 = FP2::new_copy(&self.a.getb());
-            let mut w3 = FP2::new_copy(&self.b.geta());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.b.geta();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta = FP2::new_copy(&self.a.geta());
-            let mut tb = FP2::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP2::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP2::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut td = FP2::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut te = FP2::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -666,49 +631,49 @@ impl FP12 {
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1 = FP2::new_copy(&self.a.geta());
-            let mut w2 = FP2::new_copy(&self.a.getb());
-            let mut w3 = FP2::new_copy(&self.c.getb());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.c.getb();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta = FP2::new_copy(&self.a.geta());
-            let mut tb = FP2::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP2::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP2::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut td = FP2::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut te = FP2::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -733,10 +698,9 @@ impl FP12 {
 
     /* 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();
+        let mut f0 = self.geta();
+        let mut f1 = self.getb();
+        let mut f2 = self.geta();
 
         self.norm();
         f0.sqr();
@@ -745,21 +709,21 @@ impl FP12 {
         f0.sub(&f1);
         f0.norm();
 
-        f1.copy(&self.c);
+        f1 = self.getc();
         f1.sqr();
         f1.times_i();
         f2.mul(&self.b);
         f1.sub(&f2);
         f1.norm();
 
-        f2.copy(&self.b);
+        f2 = self.getb();
         f2.sqr();
-        f3.copy(&self.a);
+        let mut f3 = self.geta();
         f3.mul(&self.c);
         f2.sub(&f3);
         f2.norm();
 
-        f3.copy(&self.b);
+        f3 = self.getb();
         f3.mul(&f2);
         f3.times_i();
         self.a.mul(&f0);
@@ -770,19 +734,19 @@ impl FP12 {
         f3.add(&self.c);
         f3.norm();
         f3.inverse();
-        self.a.copy(&f0);
+        self.a = f0.clone();
         self.a.mul(&f3);
-        self.b.copy(&f1);
+        self.b = f1.clone();
         self.b.mul(&f3);
-        self.c.copy(&f2);
+        self.c = f2.clone();
         self.c.mul(&f3);
         self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
     pub fn frob(&mut self, f: &FP2) {
-        let mut f2 = FP2::new_copy(f);
-        let mut f3 = FP2::new_copy(f);
+        let mut f2 = f.clone();
+        let mut f3 = f.clone();
 
         f2.sqr();
         f3.mul(&f2);
@@ -798,8 +762,7 @@ impl FP12 {
 
     /* trace function */
     pub fn trace(&mut self) -> FP4 {
-        let mut t = FP4::new();
-        t.copy(&self.a);
+        let mut t = self.geta();
         t.imul(3);
         t.reduce();
         return t;
@@ -813,71 +776,71 @@ impl FP12 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = Big::frombytes(&t);
+        let 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);
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 2 * mb]
         }
-        a = Big::frombytes(&t);
+        let 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 b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let e = FP4::new_fp2s(&c, &d);
+        let e = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a = Big::frombytes(&t);
+        let 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);
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 6 * mb]
         }
-        a = Big::frombytes(&t);
+        let 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 b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let f = FP4::new_fp2s(&c, &d);
+        let f = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        a = Big::frombytes(&t);
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        b = Big::frombytes(&t);
+        let b = Big::frombytes(&t);
 
-        c = FP2::new_bigs(&a, &b);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 10 * mb]
         }
-        a = Big::frombytes(&t);
+        let 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 b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let g = FP4::new_fp2s(&c, &d);
+        let g = FP4::new_fp2s(c, d);
 
-        return FP12::new_fp4s(&e, &f, &g);
+        FP12::new_fp4s(e, f, g)
     }
 
     /* convert this to byte array */
@@ -972,14 +935,14 @@ impl FP12 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP12 {
-        let mut r = FP12::new_copy(self);
+        let mut r = self.clone();
         r.norm();
-        let mut e1 = Big::new_copy(e);
+        let mut e1 = e.clone();
         e1.norm();
-        let mut e3 = Big::new_copy(&e1);
+        let mut e3 = e1.clone();
         e3.pmul(3);
         e3.norm();
-        let mut w = FP12::new_copy(&r);
+        let mut w = r.clone();
 
         let nb = e3.nbits();
         for i in (1..nb - 1).rev() {
@@ -1001,32 +964,31 @@ impl FP12 {
 
     /* 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();
+        let mut r: [FP12; 2] = [FP12::new_int(1), self.clone()];
 
         for i in (0..bts).rev() {
             let b: usize = ((e >> i) & 1) as usize;
-            t.copy(&r[b]);
+            let t = r[b].clone();
             r[1 - b].mul(&t);
             r[b].usqr();
         }
-        self.copy(&r[0]);
+        *self = r[0].clone();
     }
 
     pub fn compow(&mut self, e: &Big, r: &Big) -> FP4 {
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         let q = Big::new_ints(&rom::MODULUS);
 
-        let mut g1 = FP12::new_copy(self);
-        let mut g2 = FP12::new_copy(self);
+        let mut g1 = self.clone();
+        let mut g2 = self.clone();
 
-        let mut m = Big::new_copy(&q);
+        let mut m = q.clone();
         m.rmod(&r);
 
-        let mut a = Big::new_copy(&e);
+        let mut a = e.clone();
         a.rmod(&m);
 
-        let mut b = Big::new_copy(&e);
+        let mut b = e.clone();
         b.div(&m);
 
         let mut c = g1.trace();
@@ -1065,45 +1027,39 @@ impl FP12 {
             FP12::new(),
         ];
 
-        let mut r = FP12::new();
         let mut p = FP12::new();
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
         let mut w: [i8; CT] = [0; CT];
         let mut s: [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]),
-        ];
+        let mut t: [Big; 4] = [u[0].clone(), u[1].clone(), u[2].clone(), u[3].clone()];
 
         for i in 0..4 {
             t[i].norm();
         }
 
         // precomputation
-        g[0].copy(&q[0]);
-        r.copy(&g[0]);
-        g[1].copy(&r);
+        g[0] = q[0].clone();
+        let mut r = g[0].clone();
+        g[1] = r.clone();
         g[1].mul(&q[1]); // q[0].q[1]
-        g[2].copy(&r);
+        g[2] = r.clone();
         g[2].mul(&q[2]);
-        r.copy(&g[1]); // q[0].q[2]
-        g[3].copy(&r);
+        r = g[1].clone(); // q[0].q[2]
+        g[3] = r.clone();
         g[3].mul(&q[2]);
-        r.copy(&g[0]); // q[0].q[1].q[2]
-        g[4].copy(&r);
+        r = g[0].clone(); // q[0].q[1].q[2]
+        g[4] = r.clone();
         g[4].mul(&q[3]);
-        r.copy(&g[1]); // q[0].q[3]
-        g[5].copy(&r);
+        r = g[1].clone(); // q[0].q[3]
+        g[5] = r.clone();
         g[5].mul(&q[3]);
-        r.copy(&g[2]); // q[0].q[1].q[3]
-        g[6].copy(&r);
+        r = g[2].clone(); // q[0].q[1].q[3]
+        g[6] = r.clone();
         g[6].mul(&q[3]);
-        r.copy(&g[3]); // q[0].q[2].q[3]
-        g[7].copy(&r);
+        r = g[3].clone(); // q[0].q[2].q[3]
+        g[7] = r.clone();
         g[7].mul(&q[3]); // q[0].q[1].q[2].q[3]
 
         // Make it odd
@@ -1150,7 +1106,7 @@ impl FP12 {
         }
 
         // apply correction
-        r.copy(&q[0]);
+        r = q[0].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb);
diff --git a/src/fp16.rs b/src/fp16.rs
index d650771..be9e12d 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -22,7 +22,7 @@ use super::fp2::FP2;
 use super::fp8::FP8;
 //use std::str::SplitWhitespace;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP16 {
     a: FP8,
     b: FP8,
@@ -37,45 +37,32 @@ impl FP16 {
     }
 
     pub fn new_int(a: isize) -> FP16 {
-        let mut f = FP16::new();
-        f.a.copy(&FP8::new_int(a));
-        f.b.zero();
-        return f;
-    }
-
-    pub fn new_copy(x: &FP16) -> FP16 {
-        let mut f = FP16::new();
-        f.a.copy(&x.a);
-        f.b.copy(&x.b);
-        return f;
+        FP16 {
+            a: FP8::new_int(a),
+            b: FP8::new(),
+        }
     }
 
-    pub fn new_fp8s(c: &FP8, d: &FP8) -> FP16 {
-        let mut f = FP16::new();
-        f.a.copy(c);
-        f.b.copy(d);
-        return f;
+    pub fn new_fp8s(a: FP8, b: FP8) -> FP16 {
+        FP16 { a, b }
     }
 
-    pub fn new_fp8(c: &FP8) -> FP16 {
-        let mut f = FP16::new();
-        f.a.copy(c);
-        f.b.zero();
-        return f;
+    pub fn new_fp8(a: FP8) -> FP16 {
+        FP16 { a, b: FP8::new() }
     }
 
     pub fn set_fp8s(&mut self, c: &FP8, d: &FP8) {
-        self.a.copy(&c);
-        self.b.copy(&d);
+        self.a = c.clone();
+        self.b = d.clone();
     }
 
     pub fn set_fp8(&mut self, c: &FP8) {
-        self.a.copy(&c);
+        self.a = c.clone();
         self.b.zero();
     }
 
     pub fn set_fp8h(&mut self, c: &FP8) {
-        self.b.copy(&c);
+        self.b = c.clone();
         self.a.zero();
     }
 
@@ -107,37 +94,29 @@ impl FP16 {
         return self.a.equals(&one) && self.b.iszilch();
     }
 
-    /* test is w real? That is in a+ib test b is zero */
+    /// Test is w real? That is in a+ib test b is zero */
     pub fn isreal(&self) -> bool {
         return self.b.iszilch();
     }
-    /* extract real part a */
+
+    /// Extract real part a
     pub fn real(&self) -> FP8 {
-        let f = FP8::new_copy(&self.a);
-        return f;
+        self.geta()
     }
 
     pub fn geta(&self) -> FP8 {
-        return self.a;
-        //        let f = FP8::new_copy(&self.a);
-        //        return f;
+        self.a.clone()
     }
-    /* extract imaginary part b */
+
+    /// Extract imaginary part b
     pub fn getb(&self) -> FP8 {
-        return self.b;
-        //        let f = FP8::new_copy(&self.b);
-        //        return f;
+        self.b.clone()
     }
 
     /* test self=x */
     pub fn equals(&self, x: &FP16) -> bool {
         return self.a.equals(&x.a) && self.b.equals(&x.b);
     }
-    /* copy self=x */
-    pub fn copy(&mut self, x: &FP16) {
-        self.a.copy(&x.a);
-        self.b.copy(&x.b);
-    }
 
     /* set self=0 */
     pub fn zero(&mut self) {
@@ -154,16 +133,15 @@ impl FP16 {
     /* negate self mod Modulus */
     pub fn neg(&mut self) {
         self.norm();
-        let mut m = FP8::new_copy(&self.a);
-        let mut t = FP8::new();
+        let mut m = self.geta();
 
         m.add(&self.b);
         m.neg();
-        t.copy(&m);
+        let mut t = m.clone();
         t.add(&self.b);
-        self.b.copy(&m);
+        self.b = m.clone();
         self.b.add(&self.a);
-        self.a.copy(&t);
+        self.a = t.clone();
         self.norm();
     }
 
@@ -196,7 +174,7 @@ impl FP16 {
 
     /* self-=a */
     pub fn sub(&mut self, x: &FP16) {
-        let mut m = FP16::new_copy(x);
+        let mut m = x.clone();
         m.neg();
         self.add(&m);
     }
@@ -228,9 +206,9 @@ impl FP16 {
     /* self*=self */
 
     pub fn sqr(&mut self) {
-        let mut t1 = FP8::new_copy(&self.a);
-        let mut t2 = FP8::new_copy(&self.b);
-        let mut t3 = FP8::new_copy(&self.a);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = self.geta();
 
         t3.mul(&self.b);
         t1.add(&self.b);
@@ -241,11 +219,11 @@ impl FP16 {
         t1.norm();
         t2.norm();
 
-        self.a.copy(&t1);
+        self.a = t1.clone();
 
         self.a.mul(&t2);
 
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.times_i();
         t2.add(&t3);
         t2.norm();
@@ -253,21 +231,20 @@ impl FP16 {
         self.a.add(&t2);
 
         t3.dbl();
-        self.b.copy(&t3);
+        self.b = t3.clone();
 
         self.norm();
     }
 
     /* self*=y */
     pub fn mul(&mut self, y: &FP16) {
-        let mut t1 = FP8::new_copy(&self.a);
-        let mut t2 = FP8::new_copy(&self.b);
-        let mut t3 = FP8::new();
-        let mut t4 = FP8::new_copy(&self.b);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = y.getb();
+        let mut t4 = self.getb();
 
         t1.mul(&y.a);
         t2.mul(&y.b);
-        t3.copy(&y.b);
         t3.add(&y.a);
         t4.add(&self.a);
 
@@ -276,18 +253,18 @@ impl FP16 {
 
         t4.mul(&t3);
 
-        t3.copy(&t1);
+        t3 = t1.clone();
         t3.neg();
         t4.add(&t3);
         t4.norm();
 
-        t3.copy(&t2);
+        t3 = t2.clone();
         t3.neg();
-        self.b.copy(&t4);
+        self.b = t4.clone();
         self.b.add(&t3);
 
         t2.times_i();
-        self.a.copy(&t2);
+        self.a = t2.clone();
         self.a.add(&t1);
 
         self.norm();
@@ -300,8 +277,8 @@ impl FP16 {
 
     /* self=1/self */
     pub fn inverse(&mut self) {
-        let mut t1 = FP8::new_copy(&self.a);
-        let mut t2 = FP8::new_copy(&self.b);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
 
         t1.sqr();
         t2.sqr();
@@ -318,11 +295,11 @@ impl FP16 {
 
     /* self*=i where i = sqrt(-1+sqrt(-1)) */
     pub fn times_i(&mut self) {
-        let mut s = FP8::new_copy(&self.b);
-        let t = FP8::new_copy(&self.a);
+        let mut s = self.getb();
+        let t = self.geta();
         s.times_i();
-        self.a.copy(&s);
-        self.b.copy(&t);
+        self.a = s.clone();
+        self.b = t.clone();
 
         self.norm();
     }
@@ -339,7 +316,7 @@ impl FP16 {
 
     /* self=self^p using Frobenius */
     pub fn frob(&mut self, f: &FP2) {
-        let mut ff = FP2::new_copy(f);
+        let mut ff = f.clone();
         ff.sqr();
         ff.norm();
         self.a.frob(&ff);
@@ -350,9 +327,9 @@ impl FP16 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP16 {
-        let mut w = FP16::new_copy(self);
+        let mut w = self.clone();
         w.norm();
-        let mut z = Big::new_copy(&e);
+        let mut z = e.clone();
         let mut r = FP16::new_int(1);
         z.norm();
         loop {
@@ -372,8 +349,8 @@ impl FP16 {
 
     /* XTR xtr_a function */
     pub fn xtr_a(&mut self, w: &FP16, y: &FP16, z: &FP16) {
-        let mut r = FP16::new_copy(w);
-        let mut t = FP16::new_copy(w);
+        let mut r = w.clone();
+        let mut t = w.clone();
         r.sub(y);
         r.norm();
         r.pmul(&self.a);
@@ -382,7 +359,7 @@ impl FP16 {
         t.pmul(&self.b);
         t.times_i();
 
-        self.copy(&r);
+        *self = r.clone();
         self.add(&t);
         self.add(z);
 
@@ -391,7 +368,7 @@ impl FP16 {
 
     /* XTR xtr_d function */
     pub fn xtr_d(&mut self) {
-        let mut w = FP16::new_copy(self);
+        let mut w = self.clone();
         self.sqr();
         w.conj();
         w.dbl();
@@ -402,17 +379,15 @@ impl FP16 {
 
     /* r=x^n using XTR method on traces of FP24s */
     pub fn xtr_pow(&self, n: &Big) -> FP16 {
-        let mut sf = FP16::new_copy(self);
+        let mut sf = self.clone();
         sf.norm();
         let mut a = FP16::new_int(3);
-        let mut b = FP16::new_copy(&sf);
-        let mut c = FP16::new_copy(&b);
+        let mut b = sf.clone();
+        let mut c = b.clone();
         c.xtr_d();
-        let mut t = FP16::new();
-        let mut r = FP16::new();
 
         let par = n.parity();
-        let mut v = Big::new_copy(n);
+        let mut v = n.clone();
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -423,46 +398,39 @@ impl FP16 {
         let nb = v.nbits();
         for i in (0..nb).rev() {
             if v.bit(i) != 1 {
-                t.copy(&b);
+                let t = b.clone();
                 sf.conj();
                 c.conj();
                 b.xtr_a(&a, &sf, &c);
                 sf.conj();
-                c.copy(&t);
+                c = t.clone();
                 c.xtr_d();
                 a.xtr_d();
             } else {
-                t.copy(&a);
+                let mut t = a.clone();
                 t.conj();
-                a.copy(&b);
+                a = b.clone();
                 a.xtr_d();
                 b.xtr_a(&c, &sf, &t);
                 c.xtr_d();
             }
         }
-        if par == 0 {
-            r.copy(&c)
-        } else {
-            r.copy(&b)
-        }
+        let mut r = if par == 0 { c } else { b };
         r.reduce();
-        return r;
+        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: &FP16, ckml: &FP16, ckm2l: &FP16, a: &Big, b: &Big) -> FP16 {
-        let mut e = Big::new_copy(a);
-        let mut d = Big::new_copy(b);
-        let mut w = Big::new();
+        let mut e = a.clone();
+        let mut d = b.clone();
         d.norm();
         e.norm();
 
-        let mut cu = FP16::new_copy(ck); // can probably be passed in w/o copying
-        let mut cv = FP16::new_copy(self);
-        let mut cumv = FP16::new_copy(ckml);
-        let mut cum2v = FP16::new_copy(ckm2l);
-        let mut r = FP16::new();
-        let mut t = FP16::new();
+        let mut cu = ck.clone(); // can probably be passed in w/o copying
+        let mut cv = self.clone();
+        let mut cumv = ckml.clone();
+        let mut cum2v = ckm2l.clone();
 
         let mut f2: usize = 0;
         while d.parity() == 0 && e.parity() == 0 {
@@ -473,130 +441,129 @@ impl FP16 {
 
         while Big::comp(&d, &e) != 0 {
             if Big::comp(&d, &e) > 0 {
-                w.copy(&e);
+                let mut w = e.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&d, &w) <= 0 {
-                    w.copy(&d);
-                    d.copy(&e);
+                    w = d.clone();
+                    d = e.clone();
                     e.rsub(&w);
                     e.norm();
 
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
+                    cum2v = cumv.clone();
                     cum2v.conj();
-                    cumv.copy(&cv);
-                    cv.copy(&cu);
-                    cu.copy(&t);
+                    cumv = cv.clone();
+                    cv = cu.clone();
+                    cu = t.clone();
                 } else {
                     if d.parity() == 0 {
                         d.fshr(1);
-                        r.copy(&cum2v);
+                        let mut r = cum2v.clone();
                         r.conj();
-                        t.copy(&cumv);
+                        let mut t = cumv.clone();
                         t.xtr_a(&cu, &cv, &r);
-                        cum2v.copy(&cumv);
+                        cum2v = cumv.clone();
                         cum2v.xtr_d();
-                        cumv.copy(&t);
+                        cumv = t.clone();
                         cu.xtr_d();
                     } else {
                         if e.parity() == 1 {
                             d.sub(&e);
                             d.norm();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cu.xtr_d();
-                            cum2v.copy(&cv);
+                            cum2v = cv.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cv.copy(&t);
+                            cv = t.clone();
                         } else {
-                            w.copy(&d);
-                            d.copy(&e);
+                            w = d.clone();
+                            d = e.clone();
                             d.fshr(1);
-                            e.copy(&w);
-                            t.copy(&cumv);
+                            e = w.clone();
+                            let mut t = cumv.clone();
                             t.xtr_d();
-                            cumv.copy(&cum2v);
+                            cumv = cum2v.clone();
                             cumv.conj();
-                            cum2v.copy(&t);
+                            cum2v = t.clone();
                             cum2v.conj();
-                            t.copy(&cv);
+                            t = cv.clone();
                             t.xtr_d();
-                            cv.copy(&cu);
-                            cu.copy(&t);
+                            cv = cu.clone();
+                            cu = t.clone();
                         }
                     }
                 }
             }
             if Big::comp(&d, &e) < 0 {
-                w.copy(&d);
+                let mut w = d.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
-                    cumv.copy(&cu);
-                    cu.copy(&t);
+                    cum2v = cumv.clone();
+                    cumv = cu.clone();
+                    cu = t;
                 } else {
                     if e.parity() == 0 {
-                        w.copy(&d);
-                        d.copy(&e);
+                        w = d.clone();
+                        d = e.clone();
                         d.fshr(1);
-                        e.copy(&w);
-                        t.copy(&cumv);
+                        e = w.clone();
+                        let mut t = cumv.clone();
                         t.xtr_d();
-                        cumv.copy(&cum2v);
+                        cumv = cum2v.clone();
                         cumv.conj();
-                        cum2v.copy(&t);
+                        cum2v = t;
                         cum2v.conj();
-                        t.copy(&cv);
+                        t = cv.clone();
                         t.xtr_d();
-                        cv.copy(&cu);
-                        cu.copy(&t);
+                        cv = cu.clone();
+                        cu = t;
                     } else {
                         if d.parity() == 1 {
-                            w.copy(&e);
-                            e.copy(&d);
+                            w = e.clone();
+                            e = d.clone();
                             w.sub(&d);
                             w.norm();
-                            d.copy(&w);
+                            d = w.clone();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cumv.conj();
-                            cum2v.copy(&cu);
+                            cum2v = cu.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cu.copy(&cv);
+                            cu = cv.clone();
                             cu.xtr_d();
-                            cv.copy(&t);
+                            cv = t;
                         } else {
                             d.fshr(1);
-                            r.copy(&cum2v);
+                            let mut r = cum2v.clone();
                             r.conj();
-                            t.copy(&cumv);
+                            let mut t = cumv.clone();
                             t.xtr_a(&cu, &cv, &r);
-                            cum2v.copy(&cumv);
+                            cum2v = cumv.clone();
                             cum2v.xtr_d();
-                            cumv.copy(&t);
+                            cumv = t.clone();
                             cu.xtr_d();
                         }
                     }
                 }
             }
         }
-        r.copy(&cv);
+        let mut r = cv;
         r.xtr_a(&cu, &cumv, &cum2v);
         for _ in 0..f2 {
             r.xtr_d()
         }
-        r = r.xtr_pow(&mut d);
-        return r;
+        r.xtr_pow(&mut d)
     }
 }
diff --git a/src/fp2.rs b/src/fp2.rs
index 87a0db1..84a6c85 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -25,7 +25,7 @@ use super::rom;
 use std::fmt;
 use std::str::SplitWhitespace;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP2 {
     a: FP,
     b: FP,
@@ -58,45 +58,32 @@ impl FP2 {
     }
 
     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;
+        FP2 {
+            a: FP::new_int(a),
+            b: FP::new(),
+        }
     }
 
-    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_fps(a: FP, b: FP) -> FP2 {
+        FP2 { a, b }
     }
 
-    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_bigs(c: Big, d: Big) -> FP2 {
+        FP2 {
+            a: FP::new_big(c),
+            b: FP::new_big(d),
+        }
     }
 
-    pub fn new_fp(c: &FP) -> FP2 {
-        let mut f = FP2::new();
-        f.a.copy(c);
-        f.b.zero();
-        return f;
+    pub fn new_fp(a: FP) -> FP2 {
+        FP2 { a, b: FP::new() }
     }
 
-    pub fn new_big(c: &Big) -> FP2 {
-        let mut f = FP2::new();
-        f.a.copy(&FP::new_big(c));
-        f.b.zero();
-        return f;
+    pub fn new_big(c: Big) -> FP2 {
+        FP2 {
+            a: FP::new_big(c),
+            b: FP::new(),
+        }
     }
 
     /* reduce components mod Modulus */
@@ -142,12 +129,6 @@ impl FP2 {
         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();
@@ -162,16 +143,14 @@ impl FP2 {
 
     /* negate self mod Modulus */
     pub fn neg(&mut self) {
-        let mut m = FP::new_copy(&self.a);
-        let mut t = FP::new();
-
+        let mut m = self.a.clone();
         m.add(&self.b);
         m.neg();
-        t.copy(&m);
+        let mut t = m.clone();
         t.add(&self.b);
-        self.b.copy(&m);
+        self.b = m;
         self.b.add(&self.a);
-        self.a.copy(&t);
+        self.a = t;
     }
 
     /* set to a-ib */
@@ -193,7 +172,7 @@ impl FP2 {
 
     /* self-=a */
     pub fn sub(&mut self, x: &FP2) {
-        let mut m = FP2::new_copy(x);
+        let mut m = x.clone();
         m.neg();
         self.add(&m);
     }
@@ -218,9 +197,9 @@ impl FP2 {
 
     /* self*=self */
     pub fn sqr(&mut self) {
-        let mut w1 = FP::new_copy(&self.a);
-        let mut w3 = FP::new_copy(&self.a);
-        let mut mb = FP::new_copy(&self.b);
+        let mut w1 = self.a.clone();
+        let mut w3 = self.a.clone();
+        let mut mb = self.b.clone();
 
         w1.add(&self.b);
 
@@ -255,8 +234,8 @@ impl FP2 {
 
         pr.ucopy(&p);
 
-        let mut c = Big::new_copy(&(self.a.x));
-        let mut d = Big::new_copy(&(y.a.x));
+        let mut c = self.a.x.clone();
+        let mut d = y.a.x.clone();
 
         let mut a = Big::mul(&self.a.x, &y.a.x);
         let mut b = Big::mul(&self.b.x, &y.b.x);
@@ -267,7 +246,7 @@ impl FP2 {
         d.norm();
 
         let mut e = Big::mul(&c, &d);
-        let mut f = DBig::new_copy(&a);
+        let mut f = a.clone();
         f.add(&b);
         b.rsub(&pr);
 
@@ -276,9 +255,9 @@ impl FP2 {
         e.sub(&f);
         e.norm();
 
-        self.a.x.copy(&FP::modulo(&mut a));
+        self.a.x = FP::modulo(&mut a);
         self.a.xes = 3;
-        self.b.x.copy(&FP::modulo(&mut e));
+        self.b.x = FP::modulo(&mut e);
         self.b.xes = 2;
     }
 
@@ -288,8 +267,8 @@ impl FP2 {
         if self.iszilch() {
             return true;
         }
-        let mut w1 = FP::new_copy(&self.b);
-        let mut w2 = FP::new_copy(&self.a);
+        let mut w1 = self.b.clone();
+        let mut w2 = self.a.clone();
         w1.sqr();
         w2.sqr();
         w1.add(&w2);
@@ -297,14 +276,14 @@ impl FP2 {
             self.zero();
             return false;
         }
-        w2.copy(&w1.sqrt());
-        w1.copy(&w2);
-        w2.copy(&self.a);
+        w2 = w1.sqrt();
+        w1 = w2.clone();
+        w2 = self.a.clone();
         w2.add(&w1);
         w2.norm();
         w2.div2();
         if w2.jacobi() != 1 {
-            w2.copy(&self.a);
+            w2 = self.a.clone();
             w2.sub(&w1);
             w2.norm();
             w2.div2();
@@ -313,8 +292,8 @@ impl FP2 {
                 return false;
             }
         }
-        w1.copy(&w2.sqrt());
-        self.a.copy(&w1);
+        w1 = w2.sqrt();
+        self.a = w1.clone();
         w1.dbl();
         w1.inverse();
         self.b.mul(&w1);
@@ -345,8 +324,8 @@ impl FP2 {
     /* 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);
+        let mut w1 = self.a.clone();
+        let mut w2 = self.b.clone();
 
         w1.sqr();
         w2.sqr();
@@ -366,44 +345,44 @@ impl FP2 {
 
     /* self*=sqrt(-1) */
     pub fn times_i(&mut self) {
-        let z = FP::new_copy(&self.a);
-        self.a.copy(&self.b);
+        let z = self.a.clone();
+        self.a = self.b.clone();
         self.a.neg();
-        self.b.copy(&z);
+        self.b = 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) {
-        let t = FP2::new_copy(self);
-        let z = FP::new_copy(&self.a);
-        self.a.copy(&self.b);
+        let t = self.clone();
+        let z = self.a.clone();
+        self.a = self.b.clone();
         self.a.neg();
-        self.b.copy(&z);
+        self.b = z.clone();
         self.add(&t);
     }
 
     pub fn div_ip2(&mut self) {
         let mut t = FP2::new();
         self.norm();
-        t.a.copy(&self.a);
+        t.a = self.a.clone();
         t.a.add(&self.b);
-        t.b.copy(&self.b);
+        t.b = self.b.clone();
         t.b.sub(&self.a);
         t.norm();
-        self.copy(&t);
+        *self = t;
     }
 
     /* w/=(1+sqrt(-1)) */
     pub fn div_ip(&mut self) {
         let mut t = FP2::new();
         self.norm();
-        t.a.copy(&self.a);
+        t.a = self.a.clone();
         t.a.add(&self.b);
-        t.b.copy(&self.b);
+        t.b = self.b.clone();
         t.b.sub(&self.a);
         t.norm();
-        self.copy(&t);
+        *self = t;
         self.div2();
     }
 }
diff --git a/src/fp24.rs b/src/fp24.rs
index 12cd1ab..5a74ac1 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -33,7 +33,7 @@ pub const SPARSER: usize = 2;
 pub const SPARSE: usize = 3;
 pub const DENSE: usize = 4;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP24 {
     a: FP8,
     b: FP8,
@@ -60,43 +60,32 @@ impl FP24 {
     }
 
     pub fn new_int(a: isize) -> FP24 {
-        let mut f = FP24::new();
-        f.a.copy(&FP8::new_int(a));
-        f.b.zero();
-        f.c.zero();
-        if a == 1 {
-            f.stype = ONE;
-        } else {
-            f.stype = SPARSER;
-        }
-        return f;
-    }
+        let stype = if a == 1 { ONE } else { SPARSER };
 
-    pub fn new_copy(x: &FP24) -> FP24 {
-        let mut f = FP24::new();
-        f.a.copy(&x.a);
-        f.b.copy(&x.b);
-        f.c.copy(&x.c);
-        f.stype = x.stype;
-        return f;
+        FP24 {
+            a: FP8::new_int(a),
+            b: FP8::new(),
+            c: FP8::new(),
+            stype,
+        }
     }
 
-    pub fn new_fp8s(d: &FP8, e: &FP8, f: &FP8) -> FP24 {
-        let mut g = FP24::new();
-        g.a.copy(d);
-        g.b.copy(e);
-        g.c.copy(f);
-        g.stype = DENSE;
-        return g;
+    pub fn new_fp8s(a: FP8, b: FP8, c: FP8) -> FP24 {
+        FP24 {
+            a,
+            b,
+            c,
+            stype: DENSE,
+        }
     }
 
-    pub fn new_fp8(d: &FP8) -> FP24 {
-        let mut g = FP24::new();
-        g.a.copy(d);
-        g.b.zero();
-        g.c.zero();
-        g.stype = SPARSER;
-        return g;
+    pub fn new_fp8(a: FP8) -> FP24 {
+        FP24 {
+            a,
+            b: FP8::new(),
+            c: FP8::new(),
+            stype: SPARSER,
+        }
     }
 
     /* reduce components mod Modulus */
@@ -151,7 +140,7 @@ impl FP24 {
         self.cmove(&g[6], FP24::teq(babs, 6));
         self.cmove(&g[7], FP24::teq(babs, 7));
 
-        let mut invf = FP24::new_copy(self);
+        let mut invf = self.clone();
         invf.conj();
         self.cmove(&invf, (m & 1) as isize);
     }
@@ -168,23 +157,15 @@ impl FP24 {
     }
 
     pub fn geta(&self) -> FP8 {
-        return self.a;
+        self.a.clone()
     }
 
     pub fn getb(&self) -> FP8 {
-        return self.b;
+        self.b.clone()
     }
 
     pub fn getc(&self) -> FP8 {
-        return self.c;
-    }
-
-    /* copy self=x */
-    pub fn copy(&mut self, x: &FP24) {
-        self.a.copy(&x.a);
-        self.b.copy(&x.b);
-        self.c.copy(&x.c);
-        self.stype = x.stype;
+        self.c.clone()
     }
 
     /* set self=1 */
@@ -212,13 +193,12 @@ impl FP24 {
 
     /* Granger-Scott Unitary Squaring */
     pub fn usqr(&mut self) {
-        let mut a = FP8::new_copy(&self.a);
-        let mut b = FP8::new_copy(&self.c);
-        let mut c = FP8::new_copy(&self.b);
-        let mut d = FP8::new();
+        let mut a = self.geta();
+        let mut b = self.getc();
+        let mut c = self.getb();
 
         self.a.sqr();
-        d.copy(&self.a);
+        let mut d = self.geta();
         d.add(&self.a);
         self.a.add(&d);
 
@@ -230,13 +210,13 @@ impl FP24 {
         b.sqr();
         b.times_i();
 
-        d.copy(&b);
+        d = b.clone();
         d.add(&b);
         b.add(&d);
         b.norm();
 
         c.sqr();
-        d.copy(&c);
+        d = c.clone();
         d.add(&c);
         c.add(&d);
         c.norm();
@@ -257,10 +237,10 @@ impl FP24 {
         if self.stype == ONE {
             return;
         }
-        let mut a = FP8::new_copy(&self.a);
-        let mut b = FP8::new_copy(&self.b);
-        let mut c = FP8::new_copy(&self.c);
-        let mut d = FP8::new_copy(&self.a);
+        let mut a = self.geta();
+        let mut b = self.getb();
+        let mut c = self.getc();
+        let mut d = self.geta();
 
         a.sqr();
         b.mul(&self.c);
@@ -275,7 +255,7 @@ impl FP24 {
         self.c.norm();
         self.c.sqr();
 
-        self.a.copy(&a);
+        self.a = a.clone();
         a.add(&b);
         a.norm();
         a.add(&c);
@@ -288,7 +268,7 @@ impl FP24 {
 
         self.a.add(&b);
 
-        self.b.copy(&c);
+        self.b = c.clone();
         self.b.add(&d);
         self.c.add(&a);
         if self.stype == SPARSER {
@@ -301,12 +281,10 @@ impl FP24 {
 
     /* FP24 full multiplication self=self*y */
     pub fn mul(&mut self, y: &FP24) {
-        let mut z0 = FP8::new_copy(&self.a);
-        let mut z1 = FP8::new();
-        let mut z2 = FP8::new_copy(&mut self.b);
-        let mut z3 = FP8::new();
-        let mut t0 = FP8::new_copy(&self.a);
-        let mut t1 = FP8::new_copy(&y.a);
+        let mut z0 = self.geta();
+        let mut z2 = self.getb();
+        let mut t0 = self.geta();
+        let mut t1 = y.geta();
 
         z0.mul(&y.a);
         z2.mul(&y.b);
@@ -317,47 +295,47 @@ impl FP24 {
         t0.norm();
         t1.norm();
 
-        z1.copy(&t0);
+        let mut z1 = t0.clone();
         z1.mul(&t1);
-        t0.copy(&self.b);
+        t0 = self.getb();
         t0.add(&self.c);
-        t1.copy(&y.b);
+        t1 = y.getb();
         t1.add(&y.c);
 
         t0.norm();
         t1.norm();
 
-        z3.copy(&t0);
+        let mut z3 = t0.clone();
         z3.mul(&t1);
 
-        t0.copy(&z0);
+        t0 = z0.clone();
         t0.neg();
-        t1.copy(&z2);
+        t1 = z2.clone();
         t1.neg();
 
         z1.add(&t0);
         //z1.norm();
-        self.b.copy(&z1);
+        self.b = z1.clone();
         self.b.add(&t1);
 
         z3.add(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.a);
+        t0 = self.geta();
         t0.add(&self.c);
         t0.norm();
-        t1.copy(&y.a);
+        t1 = y.geta();
         t1.add(&y.c);
         t1.norm();
         t0.mul(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.c);
+        t0 = self.getc();
         t0.mul(&y.c);
-        t1.copy(&t0);
+        t1 = t0.clone();
         t1.neg();
 
-        self.c.copy(&z2);
+        self.c = z2.clone();
         self.c.add(&t1);
         z3.add(&t1);
         t0.times_i();
@@ -365,7 +343,7 @@ impl FP24 {
         z3.norm();
 
         z3.times_i();
-        self.a.copy(&z0);
+        self.a = z0.clone();
         self.a.add(&z3);
         self.stype = DENSE;
         self.norm();
@@ -376,80 +354,75 @@ impl FP24 {
     /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP24) {
         if self.stype == ONE {
-            self.copy(&y);
+            *self = y.clone();
             return;
         }
         if y.stype == ONE {
             return;
         }
         if y.stype >= SPARSE {
-            let mut z0 = FP8::new_copy(&self.a);
-            let mut z1 = FP8::new_int(0);
-            let mut z2 = FP8::new_int(0);
-            let mut z3 = FP8::new_int(0);
+            let mut z0 = self.geta();
+            let mut z2 = FP8::new();
             z0.mul(&y.a);
 
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP4::new_int(0);
-                    let mut gb = FP4::new_int(0);
-
-                    gb.copy(&self.b.getb());
+                    let mut gb = self.b.getb();
                     gb.mul(&y.b.getb());
-                    ga.zero();
+                    let mut ga = FP4::new();
                     if y.stype != SPARSE {
-                        ga.copy(&self.b.getb());
+                        ga = self.b.getb();
                         ga.mul(&y.b.geta());
                     }
                     if self.stype != SPARSE {
-                        ga.copy(&self.b.geta());
+                        ga = self.b.geta();
                         ga.mul(&y.b.getb());
                     }
                     z2.set_fp4s(&ga, &gb);
                     z2.times_i();
                 } else {
-                    z2.copy(&self.b);
+                    z2 = self.getb();
                     z2.mul(&y.b);
                 }
             } else {
-                z2.copy(&self.b);
+                z2 = self.getb();
                 z2.mul(&y.b);
             }
-            let mut t0 = FP8::new_copy(&self.a);
-            let mut t1 = FP8::new_copy(&y.a);
+            let mut t0 = self.geta();
+            let mut t1 = y.geta();
             t0.add(&self.b);
             t0.norm();
             t1.add(&y.b);
             t1.norm();
 
-            z1.copy(&t0);
+            let mut z1 = t0.clone();
             z1.mul(&t1);
-            t0.copy(&self.b);
+            t0 = self.getb();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.b);
+            t1 = y.getb();
             t1.add(&y.c);
             t1.norm();
 
-            z3.copy(&t0);
+            let mut z3 = t0.clone();
             z3.mul(&t1);
 
-            t0.copy(&z0);
+            t0 = z0.clone();
             t0.neg();
-            t1.copy(&z2);
+            t1 = z2.clone();
             t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1);
+            self.b = z1.clone();
             self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a);
+            t0 = self.geta();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.a);
+            t1 = y.geta();
             t1.add(&y.c);
             t1.norm();
 
@@ -458,40 +431,37 @@ impl FP24 {
 
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP4::new_int(0);
-                    let mut gb = FP4::new_int(0);
-
-                    ga.copy(&self.c.geta());
+                    let mut ga = self.c.geta();
                     ga.mul(&y.c.geta());
-                    gb.zero();
+                    let mut gb = FP4::new();
                     if y.stype != SPARSE {
-                        gb.copy(&self.c.geta());
+                        gb = self.c.geta();
                         gb.mul(&y.c.getb());
                     }
                     if self.stype != SPARSE {
-                        gb.copy(&self.c.getb());
+                        gb = self.c.getb();
                         gb.mul(&y.c.geta());
                     }
                     t0.set_fp4s(&ga, &gb);
                 } else {
-                    t0.copy(&self.c);
+                    t0 = self.getc();
                     t0.mul(&y.c);
                 }
             } else {
-                t0.copy(&self.c);
+                t0 = self.getc();
                 t0.mul(&y.c);
             }
-            t1.copy(&t0);
+            t1 = t0.clone();
             t1.neg();
 
-            self.c.copy(&z2);
+            self.c = z2;
             self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0);
+            self.a = z0;
             self.a.add(&z3);
         } else {
             if self.stype == SPARSER {
@@ -500,11 +470,10 @@ impl FP24 {
             }
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 // dense by sparser - 13m
-                let mut z0 = FP8::new_copy(&self.a);
-                let mut z2 = FP8::new_copy(&self.b);
-                let mut z3 = FP8::new_copy(&self.b);
-                let mut t0 = FP8::new_int(0);
-                let mut t1 = FP8::new_copy(&y.a);
+                let mut z0 = self.geta();
+                let mut z2 = self.getb();
+                let mut z3 = self.getb();
+                let mut t1 = y.geta();
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -518,9 +487,9 @@ impl FP24 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0);
+                let mut t0 = z0.clone();
                 t0.neg();
-                t1.copy(&z2);
+                t1 = z2.clone();
                 t1.neg();
 
                 self.b.add(&t0);
@@ -529,70 +498,65 @@ impl FP24 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2);
+                self.c = z2;
                 self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0;
                 self.a.add(&z3);
             }
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
-                let mut z0 = FP8::new_copy(&self.a);
-                let mut z1 = FP8::new();
-                let mut z2 = FP8::new();
-                let mut z3 = FP8::new();
-                let mut t0 = FP8::new_copy(&self.a);
-                let mut t1 = FP8::new();
-
+                let mut z0 = self.geta();
+                let mut t0 = self.geta();
                 z0.mul(&y.a);
                 t0.add(&self.b);
                 t0.norm();
 
-                z1.copy(&t0);
+                let mut z1 = t0.clone();
                 z1.mul(&y.a);
-                t0.copy(&self.b);
+                t0 = self.getb();
                 t0.add(&self.c);
                 t0.norm();
 
-                z3.copy(&t0);
+                let mut z3 = t0.clone();
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0);
+                t0 = z0.clone();
                 t0.neg();
                 z1.add(&t0);
-                self.b.copy(&z1);
-                z2.copy(&t0);
+                self.b = z1.clone();
+                let mut z2 = t0.clone();
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
-                t1.copy(&y.a);
+                let mut t1 = y.geta();
                 t1.add(&y.c);
                 t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
-                t0.copy(&self.c);
+                t0 = self.getc();
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0);
+                t1 = t0.clone();
                 t1.neg();
 
-                self.c.copy(&z2);
+                self.c = z2.clone();
                 self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0.clone();
                 self.a.add(&z3);
             }
         }
@@ -603,49 +567,49 @@ impl FP24 {
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP24) {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
-            let mut w1 = FP4::new_copy(&self.a.geta());
-            let mut w2 = FP4::new_copy(&self.a.getb());
-            let mut w3 = FP4::new_copy(&self.b.geta());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.b.geta();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta = FP4::new_copy(&self.a.geta());
-            let mut tb = FP4::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP4::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP4::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut td = FP4::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut te = FP4::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -660,49 +624,49 @@ impl FP24 {
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1 = FP4::new_copy(&self.a.geta());
-            let mut w2 = FP4::new_copy(&self.a.getb());
-            let mut w3 = FP4::new_copy(&self.c.getb());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.c.getb();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta = FP4::new_copy(&self.a.geta());
-            let mut tb = FP4::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP4::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP4::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut td = FP4::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut te = FP4::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -727,10 +691,10 @@ impl FP24 {
 
     /* self=1/self */
     pub fn inverse(&mut self) {
-        let mut f0 = FP8::new_copy(&self.a);
-        let mut f1 = FP8::new_copy(&self.b);
-        let mut f2 = FP8::new_copy(&self.a);
-        let mut f3 = FP8::new();
+        let mut f0 = self.geta();
+        let mut f1 = self.getb();
+        let mut f2 = self.geta();
+        let mut f3 = self.geta();
 
         //self.norm();
         f0.sqr();
@@ -739,21 +703,20 @@ impl FP24 {
         f0.sub(&f1);
         f0.norm();
 
-        f1.copy(&self.c);
+        f1 = self.getc();
         f1.sqr();
         f1.times_i();
         f2.mul(&self.b);
         f1.sub(&f2);
         f1.norm();
 
-        f2.copy(&self.b);
+        f2 = self.getb();
         f2.sqr();
-        f3.copy(&self.a);
         f3.mul(&self.c);
         f2.sub(&f3);
         f2.norm();
 
-        f3.copy(&self.b);
+        f3 = self.getb();
         f3.mul(&f2);
         f3.times_i();
         self.a.mul(&f0);
@@ -764,19 +727,19 @@ impl FP24 {
         f3.add(&self.c);
         f3.norm();
         f3.inverse();
-        self.a.copy(&f0);
+        self.a = f0.clone();
         self.a.mul(&f3);
-        self.b.copy(&f1);
+        self.b = f1.clone();
         self.b.mul(&f3);
-        self.c.copy(&f2);
+        self.c = f2.clone();
         self.c.mul(&f3);
         self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
     pub fn frob(&mut self, f: &FP2, n: isize) {
-        let mut f2 = FP2::new_copy(f);
-        let mut f3 = FP2::new_copy(f);
+        let mut f2 = f.clone();
+        let mut f3 = f.clone();
 
         f2.sqr();
         f3.mul(&f2);
@@ -800,8 +763,7 @@ impl FP24 {
 
     /* trace function */
     pub fn trace(&mut self) -> FP8 {
-        let mut t = FP8::new();
-        t.copy(&self.a);
+        let mut t = self.geta();
         t.imul(3);
         t.reduce();
         return t;
@@ -815,144 +777,144 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = Big::frombytes(&t);
+        let 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);
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 2 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 3 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        let mut d = FP2::new_bigs(&a, &b);
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let mut ea = FP4::new_fp2s(&c, &d);
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 5 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 6 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 7 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let mut eb = FP4::new_fp2s(&c, &d);
+        let eb = FP4::new_fp2s(c, d);
 
-        let e = FP8::new_fp4s(&ea, &eb);
+        let e = FP8::new_fp4s(ea, eb);
 
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 10 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 11 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 12 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 13 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 14 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 15 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        let f = FP8::new_fp4s(&ea, &eb);
+        let f = FP8::new_fp4s(ea, eb);
 
         for i in 0..mb {
             t[i] = w[i + 16 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 17 * mb]
         }
-        b.copy(&Big::frombytes(&t));
+        let b = Big::frombytes(&t);
 
-        c.copy(&FP2::new_bigs(&a, &b));
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 18 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 19 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 20 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 21 * mb]
         }
-        b.copy(&Big::frombytes(&t));
+        let b = Big::frombytes(&t);
 
-        c.copy(&FP2::new_bigs(&a, &b));
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 22 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 23 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        let g = FP8::new_fp4s(&ea, &eb);
+        let g = FP8::new_fp4s(ea, eb);
 
-        return FP24::new_fp8s(&e, &f, &g);
+        return FP24::new_fp8s(e, f, g);
     }
 
     /* convert this to byte array */
@@ -1075,14 +1037,14 @@ impl FP24 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP24 {
-        let mut r = FP24::new_copy(self);
+        let mut r = self.clone();
         r.norm();
-        let mut e1 = Big::new_copy(e);
+        let mut e1 = e.clone();
         e1.norm();
-        let mut e3 = Big::new_copy(&e1);
+        let mut e3 = e1.clone();
         e3.pmul(3);
         e3.norm();
-        let mut w = FP24::new_copy(&r);
+        let mut w = r.clone();
 
         let nb = e3.nbits();
         for i in (1..nb - 1).rev() {
@@ -1104,32 +1066,31 @@ impl FP24 {
 
     /* constant time powering by small integer of max length bts */
     pub fn pinpow(&mut self, e: i32, bts: i32) {
-        let mut r: [FP24; 2] = [FP24::new_int(1), FP24::new_copy(self)];
-        let mut t = FP24::new();
+        let mut r: [FP24; 2] = [FP24::new_int(1), self.clone()];
 
         for i in (0..bts).rev() {
             let b: usize = ((e >> i) & 1) as usize;
-            t.copy(&r[b]);
+            let t = r[b].clone();
             r[1 - b].mul(&t);
             r[b].usqr();
         }
-        self.copy(&r[0]);
+        *self = r[0].clone();
     }
 
     pub fn compow(&mut self, e: &Big, r: &Big) -> FP8 {
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         let q = Big::new_ints(&rom::MODULUS);
 
-        let mut g1 = FP24::new_copy(self);
-        let mut g2 = FP24::new_copy(self);
+        let mut g1 = self.clone();
+        let mut g2 = self.clone();
 
-        let mut m = Big::new_copy(&q);
+        let mut m = q.clone();
         m.rmod(&r);
 
-        let mut a = Big::new_copy(&e);
+        let mut a = e.clone();
         a.rmod(&mut m);
 
-        let mut b = Big::new_copy(&e);
+        let mut b = e.clone();
         b.div(&mut m);
 
         let mut c = g1.trace();
@@ -1178,7 +1139,6 @@ impl FP24 {
             FP24::new(),
         ];
 
-        let mut r = FP24::new();
         let mut p = FP24::new();
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
         let mut w1: [i8; CT] = [0; CT];
@@ -1188,14 +1148,14 @@ impl FP24 {
 
         let mut mt = Big::new();
         let mut t: [Big; 8] = [
-            Big::new_copy(&u[0]),
-            Big::new_copy(&u[1]),
-            Big::new_copy(&u[2]),
-            Big::new_copy(&u[3]),
-            Big::new_copy(&u[4]),
-            Big::new_copy(&u[5]),
-            Big::new_copy(&u[6]),
-            Big::new_copy(&u[7]),
+            u[0].clone(),
+            u[1].clone(),
+            u[2].clone(),
+            u[3].clone(),
+            u[4].clone(),
+            u[5].clone(),
+            u[6].clone(),
+            u[7].clone(),
         ];
 
         for i in 0..8 {
@@ -1203,32 +1163,32 @@ impl FP24 {
         }
 
         // precomputation
-        g1[0].copy(&q[0]);
-        r.copy(&g1[0]);
-        g1[1].copy(&r);
+        g1[0] = q[0].clone();
+        let mut r = g1[0].clone();
+        g1[1] = r.clone();
         g1[1].mul(&q[1]); // q[0].q[1]
-        g1[2].copy(&r);
+        g1[2] = r.clone();
         g1[2].mul(&q[2]);
-        r.copy(&g1[1]); // q[0].q[2]
-        g1[3].copy(&r);
+        r = g1[1].clone(); // q[0].q[2]
+        g1[3] = r.clone();
         g1[3].mul(&q[2]);
-        r.copy(&g1[0]); // q[0].q[1].q[2]
-        g1[4].copy(&r);
+        r = g1[0].clone(); // q[0].q[1].q[2]
+        g1[4] = r.clone();
         g1[4].mul(&q[3]);
-        r.copy(&g1[1]); // q[0].q[3]
-        g1[5].copy(&r);
+        r = g1[1].clone(); // q[0].q[3]
+        g1[5] = r.clone();
         g1[5].mul(&q[3]);
-        r.copy(&g1[2]); // q[0].q[1].q[3]
-        g1[6].copy(&r);
+        r = g1[2].clone(); // q[0].q[1].q[3]
+        g1[6] = r.clone();
         g1[6].mul(&q[3]);
-        r.copy(&g1[3]); // q[0].q[2].q[3]
-        g1[7].copy(&r);
+        r = g1[3].clone(); // q[0].q[2].q[3]
+        g1[7] = r.clone();
         g1[7].mul(&q[3]); // q[0].q[1].q[2].q[3]
 
         // Use Frobenius
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         for i in 0..8 {
-            g2[i].copy(&g1[i]);
+            g2[i] = g1[i].clone();
             g2[i].frob(&f, 4);
         }
 
@@ -1298,12 +1258,12 @@ impl FP24 {
         }
 
         // apply correction
-        r.copy(&q[0]);
+        r = q[0].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb1);
 
-        r.copy(&q[4]);
+        r = q[4].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb2);
diff --git a/src/fp4.rs b/src/fp4.rs
index 88b5d03..a9d972b 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -22,7 +22,7 @@ use super::fp::FP;
 use super::fp2::FP2;
 use std::str::SplitWhitespace;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP4 {
     a: FP2,
     b: FP2,
@@ -43,45 +43,32 @@ impl FP4 {
     }
 
     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;
+        FP4 {
+            a: FP2::new_int(a),
+            b: FP2::new(),
+        }
     }
 
-    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_fp2s(a: FP2, b: FP2) -> FP4 {
+        FP4 { a, b }
     }
 
-    pub fn new_fp2(c: &FP2) -> FP4 {
-        let mut f = FP4::new();
-        f.a.copy(c);
-        f.b.zero();
-        return f;
+    pub fn new_fp2(a: FP2) -> FP4 {
+        FP4 { a, b: FP2::new() }
     }
 
     pub fn set_fp2s(&mut self, c: &FP2, d: &FP2) {
-        self.a.copy(&c);
-        self.b.copy(&d);
+        self.a = c.clone();
+        self.b = d.clone();
     }
 
     pub fn set_fp2(&mut self, c: &FP2) {
-        self.a.copy(&c);
+        self.a = c.clone();
         self.b.zero();
     }
 
     pub fn set_fp2h(&mut self, c: &FP2) {
-        self.b.copy(&c);
+        self.b = c.clone();
         self.a.zero();
     }
 
@@ -104,46 +91,38 @@ impl FP4 {
 
     /* test self=0 ? */
     pub fn iszilch(&self) -> bool {
-        return self.a.iszilch() && self.b.iszilch();
+        self.a.iszilch() && self.b.iszilch()
     }
 
     /* test self=1 ? */
     pub fn isunity(&self) -> bool {
         let one = FP2::new_int(1);
-        return self.a.equals(&one) && self.b.iszilch();
+        self.a.equals(&one) && self.b.iszilch()
     }
 
     /* test is w real? That is in a+ib test b is zero */
     pub fn isreal(&self) -> bool {
-        return self.b.iszilch();
+        self.b.iszilch()
     }
+
     /* extract real part a */
     pub fn real(&self) -> FP2 {
-        let f = FP2::new_copy(&self.a);
-        return f;
+        self.geta()
     }
 
     pub fn geta(&self) -> FP2 {
-        return self.a;
-        //        let f = FP2::new_copy(&self.a);
-        //        return f;
+        self.a.clone()
     }
+
     /* extract imaginary part b */
     pub fn getb(&self) -> FP2 {
-        return self.b;
-        //        let f = FP2::new_copy(&self.b);
-        //        return f;
+        self.b.clone()
     }
 
     /* test self=x */
     pub fn equals(&self, x: &FP4) -> bool {
         return self.a.equals(&x.a) && self.b.equals(&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) {
@@ -160,16 +139,15 @@ impl FP4 {
     /* negate self mod Modulus */
     pub fn neg(&mut self) {
         self.norm();
-        let mut m = FP2::new_copy(&self.a);
-        let mut t = FP2::new();
+        let mut m = self.geta();
 
         m.add(&self.b);
         m.neg();
-        t.copy(&m);
+        let mut t = m.clone();
         t.add(&self.b);
-        self.b.copy(&m);
+        self.b = m.clone();
         self.b.add(&self.a);
-        self.a.copy(&t);
+        self.a = t.clone();
         self.norm();
     }
 
@@ -202,7 +180,7 @@ impl FP4 {
 
     /* self-=a */
     pub fn sub(&mut self, x: &FP4) {
-        let mut m = FP4::new_copy(x);
+        let mut m = x.clone();
         m.neg();
         self.add(&m);
     }
@@ -234,9 +212,9 @@ impl FP4 {
     /* self*=self */
 
     pub fn sqr(&mut self) {
-        let mut t1 = FP2::new_copy(&self.a);
-        let mut t2 = FP2::new_copy(&self.b);
-        let mut t3 = FP2::new_copy(&self.a);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = self.geta();
 
         t3.mul(&self.b);
         t1.add(&self.b);
@@ -247,11 +225,11 @@ impl FP4 {
         t1.norm();
         t2.norm();
 
-        self.a.copy(&t1);
+        self.a = t1.clone();
 
         self.a.mul(&t2);
 
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.mul_ip();
         t2.add(&t3);
         t2.norm();
@@ -259,7 +237,7 @@ impl FP4 {
         self.a.add(&t2);
 
         t3.dbl();
-        self.b.copy(&t3);
+        self.b = t3.clone();
 
         self.norm();
     }
@@ -268,14 +246,13 @@ impl FP4 {
     pub fn mul(&mut self, y: &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);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = y.getb();
+        let mut t4 = self.getb();
 
         t1.mul(&y.a);
         t2.mul(&y.b);
-        t3.copy(&y.b);
         t3.add(&y.a);
         t4.add(&self.a);
 
@@ -284,18 +261,18 @@ impl FP4 {
 
         t4.mul(&t3);
 
-        t3.copy(&t1);
+        t3 = t1.clone();
         t3.neg();
         t4.add(&t3);
         t4.norm();
 
-        t3.copy(&t2);
+        t3 = t2.clone();
         t3.neg();
-        self.b.copy(&t4);
+        self.b = t4.clone();
         self.b.add(&t3);
 
         t2.mul_ip();
-        self.a.copy(&t2);
+        self.a = t2.clone();
         self.a.add(&t1);
 
         self.norm();
@@ -326,8 +303,8 @@ impl FP4 {
     pub fn inverse(&mut self) {
         //self.norm();
 
-        let mut t1 = FP2::new_copy(&self.a);
-        let mut t2 = FP2::new_copy(&self.b);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
 
         t1.sqr();
         t2.sqr();
@@ -343,12 +320,12 @@ impl FP4 {
 
     /* self*=i where i = sqrt(-1+sqrt(-1)) */
     pub fn times_i(&mut self) {
-        let mut s = FP2::new_copy(&self.b);
-        let mut t = FP2::new_copy(&self.b);
+        let mut s = self.getb();
+        let mut t = self.getb();
         s.times_i();
         t.add(&s);
-        self.b.copy(&self.a);
-        self.a.copy(&t);
+        self.b = self.geta();
+        self.a = t.clone();
         self.norm();
     }
 
@@ -361,9 +338,9 @@ impl FP4 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP4 {
-        let mut w = FP4::new_copy(self);
+        let mut w = self.clone();
         w.norm();
-        let mut z = Big::new_copy(&e);
+        let mut z = e.clone();
         let mut r = FP4::new_int(1);
         z.norm();
         loop {
@@ -383,8 +360,8 @@ impl FP4 {
 
     /* 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);
+        let mut r = w.clone();
+        let mut t = w.clone();
         r.sub(y);
         r.norm();
         r.pmul(&self.a);
@@ -393,7 +370,7 @@ impl FP4 {
         t.pmul(&self.b);
         t.times_i();
 
-        self.copy(&r);
+        *self = r.clone();
         self.add(&t);
         self.add(z);
 
@@ -402,7 +379,7 @@ impl FP4 {
 
     /* XTR xtr_d function */
     pub fn xtr_d(&mut self) {
-        let mut w = FP4::new_copy(self);
+        let mut w = self.clone();
         self.sqr();
         w.conj();
         w.dbl();
@@ -413,17 +390,15 @@ impl FP4 {
 
     /* r=x^n using XTR method on traces of FP12s */
     pub fn xtr_pow(&self, n: &Big) -> FP4 {
-        let mut sf = FP4::new_copy(self);
+        let mut sf = self.clone();
         sf.norm();
         let mut a = FP4::new_int(3);
-        let mut b = FP4::new_copy(&sf);
-        let mut c = FP4::new_copy(&b);
+        let mut b = sf.clone();
+        let mut c = b.clone();
         c.xtr_d();
-        let mut t = FP4::new();
-        let mut r = FP4::new();
 
         let par = n.parity();
-        let mut v = Big::new_copy(n);
+        let mut v = n.clone();
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -434,46 +409,39 @@ impl FP4 {
         let nb = v.nbits();
         for i in (0..nb).rev() {
             if v.bit(i) != 1 {
-                t.copy(&b);
+                let t = b.clone();
                 sf.conj();
                 c.conj();
                 b.xtr_a(&a, &sf, &c);
                 sf.conj();
-                c.copy(&t);
+                c = t.clone();
                 c.xtr_d();
                 a.xtr_d();
             } else {
-                t.copy(&a);
+                let mut t = a.clone();
                 t.conj();
-                a.copy(&b);
+                a = b.clone();
                 a.xtr_d();
                 b.xtr_a(&c, &sf, &t);
                 c.xtr_d();
             }
         }
-        if par == 0 {
-            r.copy(&c)
-        } else {
-            r.copy(&b)
-        }
+        let mut r = if par == 0 { c.clone() } else { b.clone() };
         r.reduce();
-        return r;
+        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: &Big, b: &Big) -> FP4 {
-        let mut e = Big::new_copy(a);
-        let mut d = Big::new_copy(b);
-        let mut w = Big::new();
+        let mut e = a.clone();
+        let mut d = b.clone();
         e.norm();
         d.norm();
 
-        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 cu = ck.clone(); // can probably be passed in w/o copying
+        let mut cv = self.clone();
+        let mut cumv = ckml.clone();
+        let mut cum2v = ckm2l.clone();
 
         let mut f2: usize = 0;
         while d.parity() == 0 && e.parity() == 0 {
@@ -484,125 +452,125 @@ impl FP4 {
 
         while Big::comp(&d, &e) != 0 {
             if Big::comp(&d, &e) > 0 {
-                w.copy(&e);
+                let mut w = e.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&d, &w) <= 0 {
-                    w.copy(&d);
-                    d.copy(&e);
+                    w = d.clone();
+                    d = e.clone();
                     e.rsub(&w);
                     e.norm();
 
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
+                    cum2v = cumv.clone();
                     cum2v.conj();
-                    cumv.copy(&cv);
-                    cv.copy(&cu);
-                    cu.copy(&t);
+                    cumv = cv.clone();
+                    cv = cu.clone();
+                    cu = t.clone();
                 } else {
                     if d.parity() == 0 {
                         d.fshr(1);
-                        r.copy(&cum2v);
+                        let mut r = cum2v.clone();
                         r.conj();
-                        t.copy(&cumv);
+                        let mut t = cumv.clone();
                         t.xtr_a(&cu, &cv, &r);
-                        cum2v.copy(&cumv);
+                        cum2v = cumv.clone();
                         cum2v.xtr_d();
-                        cumv.copy(&t);
+                        cumv = t.clone();
                         cu.xtr_d();
                     } else {
                         if e.parity() == 1 {
                             d.sub(&e);
                             d.norm();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cu.xtr_d();
-                            cum2v.copy(&cv);
+                            cum2v = cv.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cv.copy(&t);
+                            cv = t.clone();
                         } else {
-                            w.copy(&d);
-                            d.copy(&e);
+                            w = d.clone();
+                            d = e.clone();
                             d.fshr(1);
-                            e.copy(&w);
-                            t.copy(&cumv);
+                            e = w.clone();
+                            let mut t = cumv.clone();
                             t.xtr_d();
-                            cumv.copy(&cum2v);
+                            cumv = cum2v.clone();
                             cumv.conj();
-                            cum2v.copy(&t);
+                            cum2v = t.clone();
                             cum2v.conj();
-                            t.copy(&cv);
+                            t = cv.clone();
                             t.xtr_d();
-                            cv.copy(&cu);
-                            cu.copy(&t);
+                            cv = cu.clone();
+                            cu = t.clone();
                         }
                     }
                 }
             }
             if Big::comp(&d, &e) < 0 {
-                w.copy(&d);
+                let mut w = d.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
-                    cumv.copy(&cu);
-                    cu.copy(&t);
+                    cum2v = cumv.clone();
+                    cumv = cu.clone();
+                    cu = t.clone()
                 } else {
                     if e.parity() == 0 {
-                        w.copy(&d);
-                        d.copy(&e);
+                        w = d.clone();
+                        d = e.clone();
                         d.fshr(1);
-                        e.copy(&w);
-                        t.copy(&cumv);
+                        e = w.clone();
+                        let mut t = cumv.clone();
                         t.xtr_d();
-                        cumv.copy(&cum2v);
+                        cumv = cum2v.clone();
                         cumv.conj();
-                        cum2v.copy(&t);
+                        cum2v = t.clone();
                         cum2v.conj();
-                        t.copy(&cv);
+                        t = cv.clone();
                         t.xtr_d();
-                        cv.copy(&cu);
-                        cu.copy(&t);
+                        cv = cu.clone();
+                        cu = t.clone();
                     } else {
                         if d.parity() == 1 {
-                            w.copy(&e);
-                            e.copy(&d);
+                            w = e.clone();
+                            e = d.clone();
                             w.sub(&d);
                             w.norm();
-                            d.copy(&w);
+                            d = w.clone();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cumv.conj();
-                            cum2v.copy(&cu);
+                            cum2v = cu.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cu.copy(&cv);
+                            cu = cv.clone();
                             cu.xtr_d();
-                            cv.copy(&t);
+                            cv = t.clone();
                         } else {
                             d.fshr(1);
-                            r.copy(&cum2v);
+                            let mut r = cum2v.clone();
                             r.conj();
-                            t.copy(&cumv);
+                            let mut t = cumv.clone();
                             t.xtr_a(&cu, &cv, &r);
-                            cum2v.copy(&cumv);
+                            cum2v = cumv.clone();
                             cum2v.xtr_d();
-                            cumv.copy(&t);
+                            cumv = t.clone();
                             cu.xtr_d();
                         }
                     }
                 }
             }
         }
-        r.copy(&cv);
+        let mut r = cv.clone();
         r.xtr_a(&cu, &cumv, &cum2v);
         for _ in 0..f2 {
             r.xtr_d()
@@ -618,21 +586,21 @@ impl FP4 {
     }
 
     pub fn div_i(&mut self) {
-        let mut u = FP2::new_copy(&self.a);
-        let v = FP2::new_copy(&self.b);
+        let mut u = self.geta();
+        let v = self.getb();
         u.div_ip();
-        self.a.copy(&v);
-        self.b.copy(&u);
+        self.a = v;
+        self.b = u;
     }
 
     pub fn div_2i(&mut self) {
-        let mut u = FP2::new_copy(&self.a);
-        let mut v = FP2::new_copy(&self.b);
+        let mut u = self.geta();
+        let mut v = self.getb();
         u.div_ip2();
         v.dbl();
         v.norm();
-        self.a.copy(&v);
-        self.b.copy(&u);
+        self.a = v.clone();
+        self.b = u.clone();
     }
 
     /* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
@@ -642,18 +610,18 @@ impl FP4 {
             return true;
         }
 
-        let mut a = FP2::new_copy(&self.a);
-        let mut s = FP2::new_copy(&self.b);
-        let mut t = FP2::new_copy(&self.a);
+        let mut a = self.geta();
+        let mut s = self.getb();
+        let mut t = self.geta();
 
         if s.iszilch() {
             if t.sqrt() {
-                self.a.copy(&t);
+                self.a = t.clone();
                 self.b.zero();
             } else {
                 t.div_ip();
                 t.sqrt();
-                self.b.copy(&t);
+                self.b = t.clone();
                 self.a.zero();
             }
             return true;
@@ -664,18 +632,18 @@ impl FP4 {
         s.norm();
         a.sub(&s);
 
-        s.copy(&a);
+        s = a.clone();
         if !s.sqrt() {
             return false;
         }
 
-        a.copy(&t);
+        a = t.clone();
         a.add(&s);
         a.norm();
         a.div2();
 
         if !a.sqrt() {
-            a.copy(&t);
+            a = t.clone();
             a.sub(&s);
             a.norm();
             a.div2();
@@ -683,14 +651,14 @@ impl FP4 {
                 return false;
             }
         }
-        t.copy(&self.b);
-        s.copy(&a);
+        t = self.getb();
+        s = a.clone();
         s.add(&a);
         s.inverse();
 
         t.mul(&s);
-        self.a.copy(&a);
-        self.b.copy(&t);
+        self.a = a;
+        self.b = t;
 
         return true;
     }
diff --git a/src/fp48.rs b/src/fp48.rs
index ad1cf53..fd8b412 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -34,7 +34,7 @@ pub const SPARSER: usize = 2;
 pub const SPARSE: usize = 3;
 pub const DENSE: usize = 4;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP48 {
     a: FP16,
     b: FP16,
@@ -62,7 +62,7 @@ impl FP48 {
 
     pub fn new_int(a: isize) -> FP48 {
         let mut f = FP48::new();
-        f.a.copy(&FP16::new_int(a));
+        f.a = FP16::new_int(a);
         f.b.zero();
         f.c.zero();
         if a == 1 {
@@ -73,31 +73,22 @@ impl FP48 {
         return f;
     }
 
-    pub fn new_copy(x: &FP48) -> FP48 {
-        let mut f = FP48::new();
-        f.a.copy(&x.a);
-        f.b.copy(&x.b);
-        f.c.copy(&x.c);
-        f.stype = x.stype;
-        return f;
-    }
-
-    pub fn new_fp16s(d: &FP16, e: &FP16, f: &FP16) -> FP48 {
-        let mut g = FP48::new();
-        g.a.copy(d);
-        g.b.copy(e);
-        g.c.copy(f);
-        g.stype = DENSE;
-        return g;
+    pub fn new_fp16s(a: FP16, b: FP16, c: FP16) -> FP48 {
+        FP48 {
+            a,
+            b,
+            c,
+            stype: DENSE,
+        }
     }
 
-    pub fn new_fp16(d: &FP16) -> FP48 {
-        let mut g = FP48::new();
-        g.a.copy(d);
-        g.b.zero();
-        g.c.zero();
-        g.stype = SPARSER;
-        return g;
+    pub fn new_fp16(a: FP16) -> FP48 {
+        FP48 {
+            a,
+            b: FP16::new(),
+            c: FP16::new(),
+            stype: SPARSER,
+        }
     }
 
     /* reduce components mod Modulus */
@@ -152,7 +143,7 @@ impl FP48 {
         self.cmove(&g[6], FP48::teq(babs, 6));
         self.cmove(&g[7], FP48::teq(babs, 7));
 
-        let mut invf = FP48::new_copy(self);
+        let mut invf = self.clone();
         invf.conj();
         self.cmove(&invf, (m & 1) as isize);
     }
@@ -169,23 +160,15 @@ impl FP48 {
     }
 
     pub fn geta(&self) -> FP16 {
-        return self.a;
+        self.a.clone()
     }
 
     pub fn getb(&self) -> FP16 {
-        return self.b;
+        self.b.clone()
     }
 
     pub fn getc(&self) -> FP16 {
-        return self.c;
-    }
-
-    /* copy self=x */
-    pub fn copy(&mut self, x: &FP48) {
-        self.a.copy(&x.a);
-        self.b.copy(&x.b);
-        self.c.copy(&x.c);
-        self.stype = x.stype;
+        self.c.clone()
     }
 
     /* set self=1 */
@@ -213,13 +196,12 @@ impl FP48 {
 
     /* Granger-Scott Unitary Squaring */
     pub fn usqr(&mut self) {
-        let mut a = FP16::new_copy(&self.a);
-        let mut b = FP16::new_copy(&self.c);
-        let mut c = FP16::new_copy(&self.b);
-        let mut d = FP16::new();
+        let mut a = self.geta();
+        let mut b = self.getc();
+        let mut c = self.getb();
 
         self.a.sqr();
-        d.copy(&self.a);
+        let mut d = self.geta();
         d.add(&self.a);
         self.a.add(&d);
 
@@ -231,13 +213,13 @@ impl FP48 {
         b.sqr();
         b.times_i();
 
-        d.copy(&b);
+        d = b.clone();
         d.add(&b);
         b.add(&d);
         b.norm();
 
         c.sqr();
-        d.copy(&c);
+        d = c.clone();
         d.add(&c);
         c.add(&d);
         c.norm();
@@ -258,10 +240,10 @@ impl FP48 {
         if self.stype == ONE {
             return;
         }
-        let mut a = FP16::new_copy(&self.a);
-        let mut b = FP16::new_copy(&self.b);
-        let mut c = FP16::new_copy(&self.c);
-        let mut d = FP16::new_copy(&self.a);
+        let mut a = self.geta();
+        let mut b = self.getb();
+        let mut c = self.getc();
+        let mut d = self.geta();
 
         a.sqr();
         b.mul(&self.c);
@@ -276,7 +258,7 @@ impl FP48 {
         self.c.norm();
         self.c.sqr();
 
-        self.a.copy(&a);
+        self.a = a.clone();
         a.add(&b);
         a.norm();
         a.add(&c);
@@ -289,7 +271,7 @@ impl FP48 {
 
         self.a.add(&b);
 
-        self.b.copy(&c);
+        self.b = c;
         self.b.add(&d);
         self.c.add(&a);
         if self.stype == SPARSER {
@@ -302,12 +284,10 @@ impl FP48 {
 
     /* FP48 full multiplication self=self*y */
     pub fn mul(&mut self, y: &FP48) {
-        let mut z0 = FP16::new_copy(&self.a);
-        let mut z1 = FP16::new();
-        let mut z2 = FP16::new_copy(&mut self.b);
-        let mut z3 = FP16::new();
-        let mut t0 = FP16::new_copy(&self.a);
-        let mut t1 = FP16::new_copy(&y.a);
+        let mut z0 = self.geta();
+        let mut z2 = self.getb();
+        let mut t0 = self.geta();
+        let mut t1 = y.geta();
 
         z0.mul(&y.a);
         z2.mul(&y.b);
@@ -318,46 +298,46 @@ impl FP48 {
         t0.norm();
         t1.norm();
 
-        z1.copy(&t0);
+        let mut z1 = t0.clone();
         z1.mul(&t1);
-        t0.copy(&self.b);
+        t0 = self.getb();
         t0.add(&self.c);
-        t1.copy(&y.b);
+        t1 = y.getb();
         t1.add(&y.c);
 
         t0.norm();
         t1.norm();
 
-        z3.copy(&t0);
+        let mut z3 = t0.clone();
         z3.mul(&t1);
 
-        t0.copy(&z0);
+        t0 = z0.clone();
         t0.neg();
-        t1.copy(&z2);
+        t1 = z2.clone();
         t1.neg();
 
         z1.add(&t0);
-        self.b.copy(&z1);
+        self.b = z1.clone();
         self.b.add(&t1);
 
         z3.add(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.a);
+        t0 = self.geta();
         t0.add(&self.c);
         t0.norm();
-        t1.copy(&y.a);
+        t1 = y.geta();
         t1.add(&y.c);
         t1.norm();
         t0.mul(&t1);
         z2.add(&t0);
 
-        t0.copy(&self.c);
+        t0 = self.getc();
         t0.mul(&y.c);
-        t1.copy(&t0);
+        t1 = t0.clone();
         t1.neg();
 
-        self.c.copy(&z2);
+        self.c = z2;
         self.c.add(&t1);
         z3.add(&t1);
         t0.times_i();
@@ -365,91 +345,86 @@ impl FP48 {
         z3.norm();
 
         z3.times_i();
-        self.a.copy(&z0);
+        self.a = z0;
         self.a.add(&z3);
         self.stype = DENSE;
         self.norm();
     }
 
-    /* FP48 full multiplication w=w*y */
-    /* Supports sparse multiplicands */
-    /* Usually w is denser than y */
+    /// FP48 full multiplication w=w*y
+    /// Supports sparse multiplicands
+    /// Usually w is denser than y
     pub fn ssmul(&mut self, y: &FP48) {
         if self.stype == ONE {
-            self.copy(&y);
+            *self = y.clone();
             return;
         }
         if y.stype == ONE {
             return;
         }
         if y.stype >= SPARSE {
-            let mut z0 = FP16::new_copy(&self.a);
-            let mut z1 = FP16::new_int(0);
+            let mut z0 = self.geta();
             let mut z2 = FP16::new_int(0);
-            let mut z3 = FP16::new_int(0);
             z0.mul(&y.a);
 
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP8::new_int(0);
-                    let mut gb = FP8::new_int(0);
-
-                    gb.copy(&self.b.getb());
+                    let mut gb = self.b.getb();
                     gb.mul(&y.b.getb());
-                    ga.zero();
+                    let mut ga = FP8::new_int(0);
                     if y.stype != SPARSE {
-                        ga.copy(&self.b.getb());
+                        ga = self.b.getb();
                         ga.mul(&y.b.geta());
                     }
                     if self.stype != SPARSE {
-                        ga.copy(&self.b.geta());
+                        ga = self.b.geta();
                         ga.mul(&y.b.getb());
                     }
                     z2.set_fp8s(&ga, &gb);
                     z2.times_i();
                 } else {
-                    z2.copy(&self.b);
+                    z2 = self.getb();
                     z2.mul(&y.b);
                 }
             } else {
-                z2.copy(&self.b);
+                z2 = self.getb();
                 z2.mul(&y.b);
             }
-            let mut t0 = FP16::new_copy(&self.a);
-            let mut t1 = FP16::new_copy(&y.a);
+            let mut t0 = self.geta();
+            let mut t1 = y.geta();
             t0.add(&self.b);
             t0.norm();
             t1.add(&y.b);
             t1.norm();
 
-            z1.copy(&t0);
+            let mut z1 = t0.clone();
             z1.mul(&t1);
-            t0.copy(&self.b);
+            t0 = self.getb();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.b);
+            t1 = y.getb();
             t1.add(&y.c);
             t1.norm();
 
-            z3.copy(&t0);
+            let mut z3 = t0.clone();
             z3.mul(&t1);
 
-            t0.copy(&z0);
+            t0 = z0.clone();
             t0.neg();
-            t1.copy(&z2);
+            t1 = z2.clone();
             t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1);
+            self.b = z1.clone();
             self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a);
+            t0 = self.geta();
             t0.add(&self.c);
             t0.norm();
-            t1.copy(&y.a);
+            t1 = y.geta();
             t1.add(&y.c);
             t1.norm();
 
@@ -458,40 +433,37 @@ impl FP48 {
 
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 if y.stype == SPARSE || self.stype == SPARSE {
-                    let mut ga = FP8::new_int(0);
-                    let mut gb = FP8::new_int(0);
-
-                    ga.copy(&self.c.geta());
+                    let mut ga = self.c.geta();
                     ga.mul(&y.c.geta());
-                    gb.zero();
+                    let mut gb = FP8::new_int(0);
                     if y.stype != SPARSE {
-                        gb.copy(&self.c.geta());
+                        gb = self.c.geta();
                         gb.mul(&y.c.getb());
                     }
                     if self.stype != SPARSE {
-                        gb.copy(&self.c.getb());
+                        gb = self.c.getb();
                         gb.mul(&y.c.geta());
                     }
                     t0.set_fp8s(&ga, &gb);
                 } else {
-                    t0.copy(&self.c);
+                    t0 = self.getc();
                     t0.mul(&y.c);
                 }
             } else {
-                t0.copy(&self.c);
+                t0 = self.getc();
                 t0.mul(&y.c);
             }
-            t1.copy(&t0);
+            t1 = t0.clone();
             t1.neg();
 
-            self.c.copy(&z2);
+            self.c = z2.clone();
             self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0);
+            self.a = z0.clone();
             self.a.add(&z3);
         } else {
             if self.stype == SPARSER {
@@ -500,11 +472,10 @@ impl FP48 {
             }
             if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 // dense by sparser - 13m
-                let mut z0 = FP16::new_copy(&self.a);
-                let mut z2 = FP16::new_copy(&self.b);
-                let mut z3 = FP16::new_copy(&self.b);
-                let mut t0 = FP16::new_int(0);
-                let mut t1 = FP16::new_copy(&y.a);
+                let mut z0 = self.geta();
+                let mut z2 = self.getb();
+                let mut z3 = self.getb();
+                let mut t1 = y.geta();
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -518,9 +489,9 @@ impl FP48 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0);
+                let mut t0 = z0.clone();
                 t0.neg();
-                t1.copy(&z2);
+                t1 = z2.clone();
                 t1.neg();
 
                 self.b.add(&t0);
@@ -529,70 +500,65 @@ impl FP48 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2);
+                self.c = z2.clone();
                 self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0.clone();
                 self.a.add(&z3);
             }
             if ecp::SEXTIC_TWIST == SexticTwist::MType {
-                let mut z0 = FP16::new_copy(&self.a);
-                let mut z1 = FP16::new();
-                let mut z2 = FP16::new();
-                let mut z3 = FP16::new();
-                let mut t0 = FP16::new_copy(&self.a);
-                let mut t1 = FP16::new();
-
+                let mut t0 = self.geta();
+                let mut z0 = self.geta();
                 z0.mul(&y.a);
                 t0.add(&self.b);
                 t0.norm();
 
-                z1.copy(&t0);
+                let mut z1 = t0.clone();
                 z1.mul(&y.a);
-                t0.copy(&self.b);
+                t0 = self.getb();
                 t0.add(&self.c);
                 t0.norm();
 
-                z3.copy(&t0);
+                let mut z3 = t0.clone();
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0);
+                t0 = z0.clone();
                 t0.neg();
                 z1.add(&t0);
-                self.b.copy(&z1);
-                z2.copy(&t0);
+                self.b = z1.clone();
+                let mut z2 = t0.clone();
 
-                t0.copy(&self.a);
+                t0 = self.geta();
                 t0.add(&self.c);
                 t0.norm();
-                t1.copy(&y.a);
+                let mut t1 = y.geta();
                 t1.add(&y.c);
                 t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
-                t0.copy(&self.c);
+                t0 = self.getc();
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0);
+                t1 = t0.clone();
                 t1.neg();
 
-                self.c.copy(&z2);
+                self.c = z2;
                 self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0);
+                self.a = z0;
                 self.a.add(&z3);
             }
         }
@@ -603,49 +569,49 @@ impl FP48 {
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP48) {
         if ecp::SEXTIC_TWIST == SexticTwist::DType {
-            let mut w1 = FP8::new_copy(&self.a.geta());
-            let mut w2 = FP8::new_copy(&self.a.getb());
-            let mut w3 = FP8::new_copy(&self.b.geta());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.b.geta();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta = FP8::new_copy(&self.a.geta());
-            let mut tb = FP8::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP8::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP8::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut td = FP8::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.b.geta());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.b.geta());
             tb.norm();
-            let mut te = FP8::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -660,49 +626,49 @@ impl FP48 {
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1 = FP8::new_copy(&self.a.geta());
-            let mut w2 = FP8::new_copy(&self.a.getb());
-            let mut w3 = FP8::new_copy(&self.c.getb());
+            let mut w1 = self.a.geta();
+            let mut w2 = self.a.getb();
+            let mut w3 = self.c.getb();
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta = FP8::new_copy(&self.a.geta());
-            let mut tb = FP8::new_copy(&y.a.geta());
+            let mut ta = self.a.geta();
+            let mut tb = y.a.geta();
             ta.add(&self.a.getb());
             ta.norm();
             tb.add(&y.a.getb());
             tb.norm();
-            let mut tc = FP8::new_copy(&ta);
+            let mut tc = ta.clone();
             tc.mul(&tb);
-            let mut t = FP8::new_copy(&w1);
+            let mut t = w1.clone();
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta());
+            ta = self.a.geta();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.geta());
+            tb = y.a.geta();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut td = FP8::new_copy(&ta);
+            let mut td = ta.clone();
             td.mul(&tb);
-            t.copy(&w1);
+            t = w1.clone();
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb());
+            ta = self.a.getb();
             ta.add(&self.c.getb());
             ta.norm();
-            tb.copy(&y.a.getb());
+            tb = y.a.getb();
             tb.add(&y.c.getb());
             tb.norm();
-            let mut te = FP8::new_copy(&ta);
+            let mut te = ta.clone();
             te.mul(&tb);
-            t.copy(&w2);
+            t = w2.clone();
             t.add(&w3);
             t.neg();
             te.add(&t);
@@ -727,10 +693,9 @@ impl FP48 {
 
     /* self=1/self */
     pub fn inverse(&mut self) {
-        let mut f0 = FP16::new_copy(&self.a);
-        let mut f1 = FP16::new_copy(&self.b);
-        let mut f2 = FP16::new_copy(&self.a);
-        let mut f3 = FP16::new();
+        let mut f0 = self.geta();
+        let mut f1 = self.getb();
+        let mut f2 = self.geta();
 
         //self.norm();
         f0.sqr();
@@ -739,21 +704,21 @@ impl FP48 {
         f0.sub(&f1);
         f0.norm();
 
-        f1.copy(&self.c);
+        f1 = self.getc();
         f1.sqr();
         f1.times_i();
         f2.mul(&self.b);
         f1.sub(&f2);
         f1.norm();
 
-        f2.copy(&self.b);
+        f2 = self.getb();
         f2.sqr();
-        f3.copy(&self.a);
+        let mut f3 = self.geta();
         f3.mul(&self.c);
         f2.sub(&f3);
         f2.norm();
 
-        f3.copy(&self.b);
+        f3 = self.getb();
         f3.mul(&f2);
         f3.times_i();
         self.a.mul(&f0);
@@ -764,19 +729,19 @@ impl FP48 {
         f3.add(&self.c);
         f3.norm();
         f3.inverse();
-        self.a.copy(&f0);
+        self.a = f0;
         self.a.mul(&f3);
-        self.b.copy(&f1);
+        self.b = f1;
         self.b.mul(&f3);
-        self.c.copy(&f2);
+        self.c = f2;
         self.c.mul(&f3);
         self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
     pub fn frob(&mut self, f: &FP2, n: isize) {
-        let mut f2 = FP2::new_copy(f);
-        let mut f3 = FP2::new_copy(f);
+        let mut f2 = f.clone();
+        let mut f3 = f.clone();
 
         f2.sqr();
         f3.mul(&f2);
@@ -802,16 +767,15 @@ impl FP48 {
         self.stype = DENSE;
     }
 
-    /* trace function */
+    /// Trace function
     pub fn trace(&mut self) -> FP16 {
-        let mut t = FP16::new();
-        t.copy(&self.a);
+        let mut t = self.geta();
         t.imul(3);
         t.reduce();
-        return t;
+        t
     }
 
-    /* convert from byte array to FP48 */
+    /// Convert from byte array to FP48
     pub fn frombytes(w: &[u8]) -> FP48 {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
@@ -819,290 +783,288 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = Big::frombytes(&t);
+        let 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);
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 2 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 3 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        let mut d = FP2::new_bigs(&a, &b);
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let mut ea = FP4::new_fp2s(&c, &d);
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 5 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 6 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 7 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        let mut eb = FP4::new_fp2s(&c, &d);
+        let eb = FP4::new_fp2s(c, d);
 
-        let mut ea8 = FP8::new_fp4s(&ea, &eb);
+        let ea8 = FP8::new_fp4s(ea, eb);
 
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        let mut a = Big::frombytes(&t);
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        let mut b = Big::frombytes(&t);
-        let mut c = FP2::new_bigs(&a, &b);
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 10 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 11 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        let mut d = FP2::new_bigs(&a, &b);
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 12 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 13 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 14 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 15 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        let mut eb8 = FP8::new_fp4s(&ea, &eb);
+        let eb8 = FP8::new_fp4s(ea, eb);
 
-        let e = FP16::new_fp8s(&ea8, &eb8);
+        let e = FP16::new_fp8s(ea8, eb8);
 
         for i in 0..mb {
             t[i] = w[i + 16 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 17 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 18 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 19 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 20 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 21 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 22 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 23 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        ea8.copy(&FP8::new_fp4s(&ea, &eb));
+        let ea8 = FP8::new_fp4s(ea, eb);
 
         for i in 0..mb {
             t[i] = w[i + 24 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 25 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 26 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 27 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 28 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 29 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 30 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 31 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        eb8.copy(&FP8::new_fp4s(&ea, &eb));
+        let eb8 = FP8::new_fp4s(ea, eb);
 
-        let f = FP16::new_fp8s(&ea8, &eb8);
+        let f = FP16::new_fp8s(ea8, eb8);
 
         for i in 0..mb {
             t[i] = w[i + 32 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 33 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 34 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 35 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 36 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 37 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-
-        c.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 38 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 39 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        ea8.copy(&FP8::new_fp4s(&ea, &eb));
+        let ea8 = FP8::new_fp4s(ea, eb);
 
         for i in 0..mb {
             t[i] = w[i + 40 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 41 * mb]
         }
-        b.copy(&Big::frombytes(&t));
+        let b = Big::frombytes(&t);
 
-        c.copy(&FP2::new_bigs(&a, &b));
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 42 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 43 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        ea.copy(&FP4::new_fp2s(&c, &d));
+        let ea = FP4::new_fp2s(c, d);
 
         for i in 0..mb {
             t[i] = w[i + 44 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 45 * mb]
         }
-        b.copy(&Big::frombytes(&t));
+        let b = Big::frombytes(&t);
 
-        c.copy(&FP2::new_bigs(&a, &b));
+        let c = FP2::new_bigs(a, b);
 
         for i in 0..mb {
             t[i] = w[i + 46 * mb]
         }
-        a.copy(&Big::frombytes(&t));
+        let a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 47 * mb]
         }
-        b.copy(&Big::frombytes(&t));
-        d.copy(&FP2::new_bigs(&a, &b));
+        let b = Big::frombytes(&t);
+        let d = FP2::new_bigs(a, b);
 
-        eb.copy(&FP4::new_fp2s(&c, &d));
+        let eb = FP4::new_fp2s(c, d);
 
-        eb8.copy(&FP8::new_fp4s(&ea, &eb));
+        let eb8 = FP8::new_fp4s(ea, eb);
 
-        let g = FP16::new_fp8s(&ea8, &eb8);
+        let g = FP16::new_fp8s(ea8, eb8);
 
-        return FP48::new_fp16s(&e, &f, &g);
+        return FP48::new_fp16s(e, f, g);
     }
 
     /* convert this to byte array */
@@ -1327,14 +1289,14 @@ impl FP48 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP48 {
-        let mut r = FP48::new_copy(self);
+        let mut r = self.clone();
         r.norm();
-        let mut e1 = Big::new_copy(e);
+        let mut e1 = e.clone();
         e1.norm();
-        let mut e3 = Big::new_copy(&e1);
+        let mut e3 = e1.clone();
         e3.pmul(3);
         e3.norm();
-        let mut w = FP48::new_copy(&r);
+        let mut w = r.clone();
 
         let nb = e3.nbits();
         for i in (1..nb - 1).rev() {
@@ -1354,34 +1316,33 @@ impl FP48 {
         return w;
     }
 
-    /* constant time powering by small integer of max length bts */
+    /// Constant time powering by small integer of max length bts
     pub fn pinpow(&mut self, e: i32, bts: i32) {
-        let mut r: [FP48; 2] = [FP48::new_int(1), FP48::new_copy(self)];
-        let mut t = FP48::new();
+        let mut r: [FP48; 2] = [FP48::new_int(1), self.clone()];
 
         for i in (0..bts).rev() {
             let b: usize = ((e >> i) & 1) as usize;
-            t.copy(&r[b]);
+            let t = r[b].clone();
             r[1 - b].mul(&t);
             r[b].usqr();
         }
-        self.copy(&r[0]);
+        *self = r[0].clone();
     }
 
     pub fn compow(&mut self, e: &Big, r: &Big) -> FP16 {
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         let q = Big::new_ints(&rom::MODULUS);
 
-        let mut g1 = FP48::new_copy(self);
-        let mut g2 = FP48::new_copy(self);
+        let mut g1 = self.clone();
+        let mut g2 = self.clone();
 
-        let mut m = Big::new_copy(&q);
+        let mut m = q.clone();
         m.rmod(&r);
 
-        let mut a = Big::new_copy(&e);
+        let mut a = e.clone();
         a.rmod(&mut m);
 
-        let mut b = Big::new_copy(&e);
+        let mut b = e.clone();
         b.div(&mut m);
 
         let mut c = g1.trace();
@@ -1450,7 +1411,6 @@ impl FP48 {
             FP48::new(),
         ];
 
-        let mut r = FP48::new();
         let mut p = FP48::new();
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
         let mut w1: [i8; CT] = [0; CT];
@@ -1464,22 +1424,22 @@ impl FP48 {
 
         let mut mt = Big::new();
         let mut t: [Big; 16] = [
-            Big::new_copy(&u[0]),
-            Big::new_copy(&u[1]),
-            Big::new_copy(&u[2]),
-            Big::new_copy(&u[3]),
-            Big::new_copy(&u[4]),
-            Big::new_copy(&u[5]),
-            Big::new_copy(&u[6]),
-            Big::new_copy(&u[7]),
-            Big::new_copy(&u[8]),
-            Big::new_copy(&u[9]),
-            Big::new_copy(&u[10]),
-            Big::new_copy(&u[11]),
-            Big::new_copy(&u[12]),
-            Big::new_copy(&u[13]),
-            Big::new_copy(&u[14]),
-            Big::new_copy(&u[15]),
+            u[0].clone(),
+            u[1].clone(),
+            u[2].clone(),
+            u[3].clone(),
+            u[4].clone(),
+            u[5].clone(),
+            u[6].clone(),
+            u[7].clone(),
+            u[8].clone(),
+            u[9].clone(),
+            u[10].clone(),
+            u[11].clone(),
+            u[12].clone(),
+            u[13].clone(),
+            u[14].clone(),
+            u[15].clone(),
         ];
 
         for i in 0..16 {
@@ -1487,36 +1447,36 @@ impl FP48 {
         }
 
         // precomputation
-        g1[0].copy(&q[0]);
-        r.copy(&g1[0]);
-        g1[1].copy(&r);
+        g1[0] = q[0].clone();
+        let mut r = g1[0].clone();
+        g1[1] = r.clone();
         g1[1].mul(&q[1]); // q[0].q[1]
-        g1[2].copy(&r);
+        g1[2] = r.clone();
         g1[2].mul(&q[2]);
-        r.copy(&g1[1]); // q[0].q[2]
-        g1[3].copy(&r);
+        r = g1[1].clone(); // q[0].q[2]
+        g1[3] = r.clone();
         g1[3].mul(&q[2]);
-        r.copy(&g1[0]); // q[0].q[1].q[2]
-        g1[4].copy(&r);
+        r = g1[0].clone(); // q[0].q[1].q[2]
+        g1[4] = r.clone();
         g1[4].mul(&q[3]);
-        r.copy(&g1[1]); // q[0].q[3]
-        g1[5].copy(&r);
+        r = g1[1].clone(); // q[0].q[3]
+        g1[5] = r.clone();
         g1[5].mul(&q[3]);
-        r.copy(&g1[2]); // q[0].q[1].q[3]
-        g1[6].copy(&r);
+        r = g1[2].clone(); // q[0].q[1].q[3]
+        g1[6] = r.clone();
         g1[6].mul(&q[3]);
-        r.copy(&g1[3]); // q[0].q[2].q[3]
-        g1[7].copy(&r);
+        r = g1[3].clone(); // q[0].q[2].q[3]
+        g1[7] = r.clone();
         g1[7].mul(&q[3]); // q[0].q[1].q[2].q[3]
 
         // Use Frobenius
-        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
         for i in 0..8 {
-            g2[i].copy(&g1[i]);
+            g2[i] = g1[i].clone();
             g2[i].frob(&f, 4);
-            g3[i].copy(&g2[i]);
+            g3[i] = g2[i].clone();
             g3[i].frob(&f, 4);
-            g4[i].copy(&g3[i]);
+            g4[i] = g3[i].clone();
             g4[i].frob(&f, 4);
         }
 
@@ -1630,22 +1590,22 @@ impl FP48 {
         }
 
         // apply correction
-        r.copy(&q[0]);
+        r = q[0].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb1);
 
-        r.copy(&q[4]);
+        r = q[4].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb2);
 
-        r.copy(&q[8]);
+        r = q[8].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb3);
 
-        r.copy(&q[12]);
+        r = q[12].clone();
         r.conj();
         r.mul(&p);
         p.cmove(&r, pb4);
diff --git a/src/fp8.rs b/src/fp8.rs
index ab4bedf..b8cac70 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -23,7 +23,7 @@ use super::fp2::FP2;
 use super::fp4::FP4;
 //use std::str::SplitWhitespace;
 
-#[derive(Copy, Clone)]
+#[derive(Clone)]
 pub struct FP8 {
     a: FP4,
     b: FP4,
@@ -38,45 +38,32 @@ impl FP8 {
     }
 
     pub fn new_int(a: isize) -> FP8 {
-        let mut f = FP8::new();
-        f.a.copy(&FP4::new_int(a));
-        f.b.zero();
-        return f;
-    }
-
-    pub fn new_copy(x: &FP8) -> FP8 {
-        let mut f = FP8::new();
-        f.a.copy(&x.a);
-        f.b.copy(&x.b);
-        return f;
+        FP8 {
+            a: FP4::new_int(a),
+            b: FP4::new(),
+        }
     }
 
-    pub fn new_fp4s(c: &FP4, d: &FP4) -> FP8 {
-        let mut f = FP8::new();
-        f.a.copy(c);
-        f.b.copy(d);
-        return f;
+    pub fn new_fp4s(a: FP4, b: FP4) -> FP8 {
+        FP8 { a, b }
     }
 
-    pub fn new_fp4(c: &FP4) -> FP8 {
-        let mut f = FP8::new();
-        f.a.copy(c);
-        f.b.zero();
-        return f;
+    pub fn new_fp4(a: FP4) -> FP8 {
+        FP8 { a, b: FP4::new() }
     }
 
     pub fn set_fp4s(&mut self, c: &FP4, d: &FP4) {
-        self.a.copy(&c);
-        self.b.copy(&d);
+        self.a = c.clone();
+        self.b = d.clone();
     }
 
     pub fn set_fp4(&mut self, c: &FP4) {
-        self.a.copy(&c);
+        self.a = c.clone();
         self.b.zero();
     }
 
     pub fn set_fp4h(&mut self, c: &FP4) {
-        self.b.copy(&c);
+        self.b = c.clone();
         self.a.zero();
     }
 
@@ -114,31 +101,22 @@ impl FP8 {
     }
     /* extract real part a */
     pub fn real(&self) -> FP4 {
-        let f = FP4::new_copy(&self.a);
-        return f;
+        self.geta()
     }
 
     pub fn geta(&self) -> FP4 {
-        return self.a;
-        //        let f = FP4::new_copy(&self.a);
-        //        return f;
+        self.a.clone()
     }
+
     /* extract imaginary part b */
     pub fn getb(&self) -> FP4 {
-        return self.b;
-        //        let f = FP4::new_copy(&self.b);
-        //        return f;
+        self.b.clone()
     }
 
     /* test self=x */
     pub fn equals(&self, x: &FP8) -> bool {
         return self.a.equals(&x.a) && self.b.equals(&x.b);
     }
-    /* copy self=x */
-    pub fn copy(&mut self, x: &FP8) {
-        self.a.copy(&x.a);
-        self.b.copy(&x.b);
-    }
 
     /* set self=0 */
     pub fn zero(&mut self) {
@@ -155,17 +133,16 @@ impl FP8 {
     /* negate self mod Modulus */
     pub fn neg(&mut self) {
         self.norm();
-        let mut m = FP4::new_copy(&self.a);
-        let mut t = FP4::new();
+        let mut m = self.geta();
 
         m.add(&self.b);
         m.neg();
 
-        t.copy(&m);
+        let mut t = m.clone();
         t.add(&self.b);
-        self.b.copy(&m);
+        self.b = m.clone();
         self.b.add(&self.a);
-        self.a.copy(&t);
+        self.a = t.clone();
         self.norm();
     }
 
@@ -198,7 +175,7 @@ impl FP8 {
 
     /* self-=a */
     pub fn sub(&mut self, x: &FP8) {
-        let mut m = FP8::new_copy(x);
+        let mut m = x.clone();
         m.neg();
         self.add(&m);
     }
@@ -236,9 +213,9 @@ impl FP8 {
     /* self*=self */
 
     pub fn sqr(&mut self) {
-        let mut t1 = FP4::new_copy(&self.a);
-        let mut t2 = FP4::new_copy(&self.b);
-        let mut t3 = FP4::new_copy(&self.a);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = self.geta();
 
         t3.mul(&self.b);
         t1.add(&self.b);
@@ -249,11 +226,11 @@ impl FP8 {
         t1.norm();
         t2.norm();
 
-        self.a.copy(&t1);
+        self.a = t1.clone();
 
         self.a.mul(&t2);
 
-        t2.copy(&t3);
+        t2 = t3.clone();
         t2.times_i();
         t2.add(&t3);
         t2.norm();
@@ -261,7 +238,7 @@ impl FP8 {
         self.a.add(&t2);
 
         t3.dbl();
-        self.b.copy(&t3);
+        self.b = t3.clone();
 
         self.norm();
     }
@@ -270,14 +247,13 @@ impl FP8 {
     pub fn mul(&mut self, y: &FP8) {
         //self.norm();
 
-        let mut t1 = FP4::new_copy(&self.a);
-        let mut t2 = FP4::new_copy(&self.b);
-        let mut t3 = FP4::new();
-        let mut t4 = FP4::new_copy(&self.b);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
+        let mut t3 = y.getb();
+        let mut t4 = self.getb();
 
         t1.mul(&y.a);
         t2.mul(&y.b);
-        t3.copy(&y.b);
         t3.add(&y.a);
         t4.add(&self.a);
 
@@ -286,18 +262,18 @@ impl FP8 {
 
         t4.mul(&t3);
 
-        t3.copy(&t1);
+        t3 = t1.clone();
         t3.neg();
         t4.add(&t3);
         t4.norm();
 
-        t3.copy(&t2);
+        t3 = t2.clone();
         t3.neg();
-        self.b.copy(&t4);
+        self.b = t4.clone();
         self.b.add(&t3);
 
         t2.times_i();
-        self.a.copy(&t2);
+        self.a = t2.clone();
         self.a.add(&t1);
 
         self.norm();
@@ -312,8 +288,8 @@ impl FP8 {
     pub fn inverse(&mut self) {
         //self.norm();
 
-        let mut t1 = FP4::new_copy(&self.a);
-        let mut t2 = FP4::new_copy(&self.b);
+        let mut t1 = self.geta();
+        let mut t2 = self.getb();
 
         t1.sqr();
         t2.sqr();
@@ -330,11 +306,11 @@ impl FP8 {
 
     /* self*=i where i = sqrt(-1+sqrt(-1)) */
     pub fn times_i(&mut self) {
-        let mut s = FP4::new_copy(&self.b);
-        let t = FP4::new_copy(&self.a);
+        let mut s = self.getb();
+        let t = self.geta();
         s.times_i();
-        self.a.copy(&s);
-        self.b.copy(&t);
+        self.a = s.clone();
+        self.b = t.clone();
 
         self.norm();
     }
@@ -346,7 +322,7 @@ impl FP8 {
 
     /* self=self^p using Frobenius */
     pub fn frob(&mut self, f: &FP2) {
-        let mut ff = FP2::new_copy(f);
+        let mut ff = f.clone();
         ff.sqr();
         ff.mul_ip();
         ff.norm();
@@ -358,9 +334,9 @@ impl FP8 {
 
     /* self=self^e */
     pub fn pow(&self, e: &Big) -> FP8 {
-        let mut w = FP8::new_copy(self);
+        let mut w = self.clone();
         w.norm();
-        let mut z = Big::new_copy(&e);
+        let mut z = e.clone();
         let mut r = FP8::new_int(1);
         z.norm();
         loop {
@@ -380,8 +356,8 @@ impl FP8 {
 
     /* XTR xtr_a function */
     pub fn xtr_a(&mut self, w: &FP8, y: &FP8, z: &FP8) {
-        let mut r = FP8::new_copy(w);
-        let mut t = FP8::new_copy(w);
+        let mut r = w.clone();
+        let mut t = w.clone();
 
         r.sub(y);
         r.norm();
@@ -391,7 +367,7 @@ impl FP8 {
         t.pmul(&self.b);
         t.times_i();
 
-        self.copy(&r);
+        *self = r.clone();
         self.add(&t);
         self.add(z);
 
@@ -400,7 +376,7 @@ impl FP8 {
 
     /* XTR xtr_d function */
     pub fn xtr_d(&mut self) {
-        let mut w = FP8::new_copy(self);
+        let mut w = self.clone();
         self.sqr();
         w.conj();
         w.dbl();
@@ -411,17 +387,15 @@ impl FP8 {
 
     /* r=x^n using XTR method on traces of FP24s */
     pub fn xtr_pow(&self, n: &Big) -> FP8 {
-        let mut sf = FP8::new_copy(self);
+        let mut sf = self.clone();
         sf.norm();
         let mut a = FP8::new_int(3);
-        let mut b = FP8::new_copy(&sf);
-        let mut c = FP8::new_copy(&b);
+        let mut b = sf.clone();
+        let mut c = b.clone();
         c.xtr_d();
-        let mut t = FP8::new();
-        let mut r = FP8::new();
 
         let par = n.parity();
-        let mut v = Big::new_copy(n);
+        let mut v = n.clone();
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -432,46 +406,39 @@ impl FP8 {
         let nb = v.nbits();
         for i in (0..nb).rev() {
             if v.bit(i) != 1 {
-                t.copy(&b);
+                let t = b.clone();
                 sf.conj();
                 c.conj();
                 b.xtr_a(&a, &sf, &c);
                 sf.conj();
-                c.copy(&t);
+                c = t.clone();
                 c.xtr_d();
                 a.xtr_d();
             } else {
-                t.copy(&a);
+                let mut t = a.clone();
                 t.conj();
-                a.copy(&b);
+                a = b.clone();
                 a.xtr_d();
                 b.xtr_a(&c, &sf, &t);
                 c.xtr_d();
             }
         }
-        if par == 0 {
-            r.copy(&c)
-        } else {
-            r.copy(&b)
-        }
+        let mut r = if par == 0 { c.clone() } else { b.clone() };
         r.reduce();
-        return r;
+        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: &FP8, ckml: &FP8, ckm2l: &FP8, a: &Big, b: &Big) -> FP8 {
-        let mut e = Big::new_copy(a);
-        let mut d = Big::new_copy(b);
-        let mut w = Big::new();
+        let mut e = a.clone();
+        let mut d = b.clone();
         e.norm();
         d.norm();
 
-        let mut cu = FP8::new_copy(ck); // can probably be passed in w/o copying
-        let mut cv = FP8::new_copy(self);
-        let mut cumv = FP8::new_copy(ckml);
-        let mut cum2v = FP8::new_copy(ckm2l);
-        let mut r = FP8::new();
-        let mut t = FP8::new();
+        let mut cu = ck.clone(); // can probably be passed in w/o copying
+        let mut cv = self.clone();
+        let mut cumv = ckml.clone();
+        let mut cum2v = ckm2l.clone();
 
         let mut f2: usize = 0;
         while d.parity() == 0 && e.parity() == 0 {
@@ -482,125 +449,125 @@ impl FP8 {
 
         while Big::comp(&d, &e) != 0 {
             if Big::comp(&d, &e) > 0 {
-                w.copy(&e);
+                let mut w = e.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&d, &w) <= 0 {
-                    w.copy(&d);
-                    d.copy(&e);
+                    w = d.clone();
+                    d = e.clone();
                     e.rsub(&w);
                     e.norm();
 
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
+                    cum2v = cumv.clone();
                     cum2v.conj();
-                    cumv.copy(&cv);
-                    cv.copy(&cu);
-                    cu.copy(&t);
+                    cumv = cv.clone();
+                    cv = cu.clone();
+                    cu = t.clone();
                 } else {
                     if d.parity() == 0 {
                         d.fshr(1);
-                        r.copy(&cum2v);
+                        let mut r = cum2v.clone();
                         r.conj();
-                        t.copy(&cumv);
+                        let mut t = cumv.clone();
                         t.xtr_a(&cu, &cv, &r);
-                        cum2v.copy(&cumv);
+                        cum2v = cumv.clone();
                         cum2v.xtr_d();
-                        cumv.copy(&t);
+                        cumv = t.clone();
                         cu.xtr_d();
                     } else {
                         if e.parity() == 1 {
                             d.sub(&e);
                             d.norm();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cu.xtr_d();
-                            cum2v.copy(&cv);
+                            cum2v = cv.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cv.copy(&t);
+                            cv = t.clone();
                         } else {
-                            w.copy(&d);
-                            d.copy(&e);
+                            w = d.clone();
+                            d = e.clone();
                             d.fshr(1);
-                            e.copy(&w);
-                            t.copy(&cumv);
+                            e = w.clone();
+                            let mut t = cumv.clone();
                             t.xtr_d();
-                            cumv.copy(&cum2v);
+                            cumv = cum2v.clone();
                             cumv.conj();
-                            cum2v.copy(&t);
+                            cum2v = t.clone();
                             cum2v.conj();
-                            t.copy(&cv);
+                            t = cv.clone();
                             t.xtr_d();
-                            cv.copy(&cu);
-                            cu.copy(&t);
+                            cv = cu.clone();
+                            cu = t.clone();
                         }
                     }
                 }
             }
             if Big::comp(&d, &e) < 0 {
-                w.copy(&d);
+                let mut w = d.clone();
                 w.imul(4);
                 w.norm();
                 if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
-                    t.copy(&cv);
+                    let mut t = cv.clone();
                     t.xtr_a(&cu, &cumv, &cum2v);
-                    cum2v.copy(&cumv);
-                    cumv.copy(&cu);
-                    cu.copy(&t);
+                    cum2v = cumv.clone();
+                    cumv = cu.clone();
+                    cu = t.clone();
                 } else {
                     if e.parity() == 0 {
-                        w.copy(&d);
-                        d.copy(&e);
+                        w = d.clone();
+                        d = e.clone();
                         d.fshr(1);
-                        e.copy(&w);
-                        t.copy(&cumv);
+                        e = w.clone();
+                        let mut t = cumv.clone();
                         t.xtr_d();
-                        cumv.copy(&cum2v);
+                        cumv = cum2v.clone();
                         cumv.conj();
-                        cum2v.copy(&t);
+                        cum2v = t.clone();
                         cum2v.conj();
-                        t.copy(&cv);
+                        t = cv.clone();
                         t.xtr_d();
-                        cv.copy(&cu);
-                        cu.copy(&t);
+                        cv = cu.clone();
+                        cu = t.clone();
                     } else {
                         if d.parity() == 1 {
-                            w.copy(&e);
-                            e.copy(&d);
+                            w = e.clone();
+                            e = d.clone();
                             w.sub(&d);
                             w.norm();
-                            d.copy(&w);
+                            d = w.clone();
                             d.fshr(1);
-                            t.copy(&cv);
+                            let mut t = cv.clone();
                             t.xtr_a(&cu, &cumv, &cum2v);
                             cumv.conj();
-                            cum2v.copy(&cu);
+                            cum2v = cu.clone();
                             cum2v.xtr_d();
                             cum2v.conj();
-                            cu.copy(&cv);
+                            cu = cv.clone();
                             cu.xtr_d();
-                            cv.copy(&t);
+                            cv = t.clone();
                         } else {
                             d.fshr(1);
-                            r.copy(&cum2v);
+                            let mut r = cum2v.clone();
                             r.conj();
-                            t.copy(&cumv);
+                            let mut t = cumv.clone();
                             t.xtr_a(&cu, &cv, &r);
-                            cum2v.copy(&cumv);
+                            cum2v = cumv.clone();
                             cum2v.xtr_d();
-                            cumv.copy(&t);
+                            cumv = t.clone();
                             cu.xtr_d();
                         }
                     }
                 }
             }
         }
-        r.copy(&cv);
+        let mut r = cv.clone();
         r.xtr_a(&cu, &cumv, &cum2v);
         for _ in 0..f2 {
             r.xtr_d()
@@ -616,11 +583,11 @@ impl FP8 {
     }
 
     pub fn div_i(&mut self) {
-        let mut u = FP4::new_copy(&self.a);
-        let v = FP4::new_copy(&self.b);
+        let mut u = self.geta();
+        let v = self.getb();
         u.div_i();
-        self.a.copy(&v);
-        self.b.copy(&u);
+        self.a = v.clone();
+        self.b = u.clone();
     }
 
     pub fn div_i2(&mut self) {
@@ -629,13 +596,13 @@ impl FP8 {
     }
 
     pub fn div_2i(&mut self) {
-        let mut u = FP4::new_copy(&self.a);
-        let mut v = FP4::new_copy(&self.b);
+        let mut u = self.geta();
+        let mut v = self.getb();
         u.div_2i();
         v.dbl();
         v.norm();
-        self.a.copy(&v);
-        self.b.copy(&u);
+        self.a = v.clone();
+        self.b = u.clone();
     }
 
     /* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
@@ -645,18 +612,18 @@ impl FP8 {
             return true;
         }
 
-        let mut a = FP4::new_copy(&self.a);
-        let mut s = FP4::new_copy(&self.b);
-        let mut t = FP4::new_copy(&self.a);
+        let mut a = self.geta();
+        let mut s = self.getb();
+        let mut t = self.geta();
 
         if s.iszilch() {
             if t.sqrt() {
-                self.a.copy(&t);
+                self.a = t.clone();
                 self.b.zero();
             } else {
                 t.div_i();
                 t.sqrt();
-                self.b.copy(&t);
+                self.b = t.clone();
                 self.a.zero();
             }
             return true;
@@ -667,18 +634,18 @@ impl FP8 {
         s.norm();
         a.sub(&s);
 
-        s.copy(&a);
+        s = a.clone();
         if !s.sqrt() {
             return false;
         }
 
-        a.copy(&t);
+        a = t.clone();
         a.add(&s);
         a.norm();
         a.div2();
 
         if !a.sqrt() {
-            a.copy(&t);
+            a = t.clone();
             a.sub(&s);
             a.norm();
             a.div2();
@@ -686,14 +653,14 @@ impl FP8 {
                 return false;
             }
         }
-        t.copy(&self.b);
-        s.copy(&a);
+        t = self.getb();
+        s = a.clone();
         s.add(&a);
         s.inverse();
 
         t.mul(&s);
-        self.a.copy(&a);
-        self.b.copy(&t);
+        self.a = a;
+        self.b = t;
 
         return true;
     }
diff --git a/src/mpin.rs b/src/mpin.rs
index 23b46a2..5d5a3da 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -191,7 +191,7 @@ pub fn today() -> usize {
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = Big::new_copy(u);
+    let mut x = u.clone();
     let p = Big::new_ints(&rom::MODULUS);
     x.rmod(&p);
     loop {
@@ -212,7 +212,7 @@ fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let mut R: ECP;
     let mut r = 0;
     let x = P.getx();
-    u.copy(&x);
+    *u = x.clone();
     loop {
         u.dec(1);
         u.norm();
@@ -739,13 +739,13 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP12::frombytes(e);
     let mut gf = FP12::frombytes(f);
     let mut distance: [isize; TS] = [0; TS];
-    let mut t = FP12::new_copy(&gf);
+    let mut t = gf.clone();
 
-    let mut table: [FP12; TS] = [FP12::new(); TS];
+    let mut table: Vec<FP12> = Vec::with_capacity(TS);
     let mut s: isize = 1;
     for m in 0..TS {
         distance[m] = s;
-        table[m] = FP12::new_copy(&t);
+        table.push(t.clone());
         s *= 2;
         t.usqr();
     }
@@ -757,7 +757,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
         t.mul(&table[i]);
         dn += distance[i];
     }
-    gf.copy(&t);
+    gf = t.clone();
     gf.conj();
     let mut steps: usize = 0;
     let mut dm: isize = 0;
@@ -910,12 +910,11 @@ pub fn server_key(
         return INVALID_POINT;
     }
 
-    let mut U = ECP::new();
-    if let Some(rxcid) = xcid {
-        U.copy(&ECP::frombytes(&rxcid));
+    let mut U = if let Some(rxcid) = xcid {
+        ECP::frombytes(&rxcid)
     } else {
-        U.copy(&ECP::frombytes(&xid));
-    }
+        ECP::frombytes(&xid)
+    };
 
     if U.is_infinity() {
         return INVALID_POINT;
@@ -934,7 +933,7 @@ pub fn server_key(
 
     hash(sha, &mut c, &mut U, sk);
 
-    return 0;
+    0
 }
 
 #[cfg(test)]
diff --git a/src/mpin192.rs b/src/mpin192.rs
index a8a40b0..43758a7 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -207,7 +207,7 @@ pub fn today() -> usize {
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = Big::new_copy(u);
+    let mut x = u.clone();
     let mut p = Big::new_ints(&rom::MODULUS);
     x.rmod(&mut p);
     loop {
@@ -228,7 +228,7 @@ fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let mut R: ECP;
     let mut r = 0;
     let x = P.getx();
-    u.copy(&x);
+    *u = x.clone();
     loop {
         u.dec(1);
         u.norm();
@@ -754,13 +754,13 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP24::frombytes(e);
     let mut gf = FP24::frombytes(f);
     let mut distance: [isize; TS] = [0; TS];
-    let mut t = FP24::new_copy(&gf);
+    let mut t = gf.clone();
 
-    let mut table: [FP24; TS] = [FP24::new(); TS];
+    let mut table: Vec<FP24> = Vec::with_capacity(TS);
     let mut s: isize = 1;
     for m in 0..TS {
         distance[m] = s;
-        table[m] = FP24::new_copy(&t);
+        table.push(t.clone());
         s *= 2;
         t.usqr();
     }
@@ -772,7 +772,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
         t.mul(&mut table[i]);
         dn += distance[i];
     }
-    gf.copy(&t);
+    gf = t.clone();
     gf.conj();
     let mut steps: usize = 0;
     let mut dm: isize = 0;
@@ -925,12 +925,11 @@ pub fn server_key(
         return INVALID_POINT;
     }
 
-    let mut U = ECP::new();
-    if let Some(rxcid) = xcid {
-        U.copy(&ECP::frombytes(&rxcid));
+    let mut U = if let Some(rxcid) = xcid {
+        ECP::frombytes(&rxcid)
     } else {
-        U.copy(&ECP::frombytes(&xid));
-    }
+        ECP::frombytes(&xid)
+    };
 
     if U.is_infinity() {
         return INVALID_POINT;
diff --git a/src/mpin256.rs b/src/mpin256.rs
index 22db48e..0e5e960 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -240,7 +240,7 @@ pub fn today() -> usize {
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = Big::new_copy(u);
+    let mut x = u.clone();
     let mut p = Big::new_ints(&rom::MODULUS);
     x.rmod(&mut p);
     loop {
@@ -261,7 +261,7 @@ fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let mut R: ECP;
     let mut r = 0;
     let x = P.getx();
-    u.copy(&x);
+    *u = x.clone();
     loop {
         u.dec(1);
         u.norm();
@@ -788,13 +788,13 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP48::frombytes(e);
     let mut gf = FP48::frombytes(f);
     let mut distance: [isize; TS] = [0; TS];
-    let mut t = FP48::new_copy(&gf);
+    let mut t = gf.clone();
 
-    let mut table: [FP48; TS] = [FP48::new(); TS];
... 1950 lines suppressed ...


[incubator-milagro-crypto-rust] 08/44: Merge in branch develop

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 86263503d1faaabc42b578e7b050ee8359b2cafc
Merge: fcc4c3a 176c3f5
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Thu Aug 8 15:14:06 2019 +1000

    Merge in branch develop
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>



[incubator-milagro-crypto-rust] 30/44: Fix comments and tests and bug in nist521

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 4a058c38b803c85e961b16f327bc92fa8d8de05d
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Mar 31 11:36:43 2020 +1100

    Fix comments and tests and bug in nist521
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/bls.rs     |   1 -
 src/bls192.rs  |   1 -
 src/bls256.rs  |   3 +-
 src/ecdh.rs    |  28 ++++++------
 src/mpin.rs    | 134 ++++++++++++++++++++++++++------------------------------
 src/mpin192.rs | 135 ++++++++++++++++++++++++++-------------------------------
 src/mpin256.rs | 135 ++++++++++++++++++++++++++-------------------------------
 7 files changed, 198 insertions(+), 239 deletions(-)

diff --git a/src/bls.rs b/src/bls.rs
index 98c9a8b..1bc71cb 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -20,7 +20,6 @@ under the License.
 use super::ecp::ECP;
 use super::ecp2::ECP2;
 use std::str;
-//use super::fp12::FP12;
 use super::big;
 use super::big::Big;
 use super::pair;
diff --git a/src/bls192.rs b/src/bls192.rs
index 1f262a7..3381106 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -38,7 +38,6 @@ pub const BLS_OK: isize = 0;
 pub const BLS_FAIL: isize = -1;
 
 // hash a message to an ECP point, using SHA3
-
 #[allow(non_snake_case)]
 fn bls_hashit(m: &str) -> ECP {
     let mut sh = SHA3::new(SHAKE256);
diff --git a/src/bls256.rs b/src/bls256.rs
index adad0da..11fb5a1 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -20,7 +20,6 @@ under the License.
 use super::ecp::ECP;
 use super::ecp8::ECP8;
 use std::str;
-//use super::fp48::FP48;
 use super::big;
 use super::big::Big;
 use super::pair256;
@@ -60,7 +59,7 @@ pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isiz
     BLS_OK
 }
 
-// Sign message m using private key s to produce signature sig
+/// Sign message m using private key s to produce signature sig
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
     let mut sc = Big::frombytes(&s);
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 7a84d6b..934ea82 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -215,7 +215,7 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
             }
         }
         for j in 0..EFS {
-            if kp < olen {
+            if kp < olen && kp < f.len() {
                 k[kp] = f[j]
             }
             kp += 1
@@ -225,10 +225,10 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
 
 /// 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 */
+    // 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];
 
     if olen < 4 {
@@ -270,9 +270,9 @@ pub fn hmac(sha: usize, m: &[u8], k: &[u8], olen: usize, tag: &mut [u8]) -> bool
 
 /// 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 */
+    // 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();
@@ -304,7 +304,7 @@ pub fn cbc_iv0_encrypt(k: &[u8], m: &[u8]) -> Vec<u8> {
         }
     }
 
-    /* last block, filled up to i-th index */
+    // last block, filled up to i-th index
 
     let padlen = 16 - i;
     for j in i..16 {
@@ -322,7 +322,7 @@ pub fn cbc_iv0_encrypt(k: &[u8], m: &[u8]) -> Vec<u8> {
 
 /// Returns plaintext if all consistent, else returns null string
 pub fn cbc_iv0_decrypt(k: &[u8], c: &[u8]) -> Option<Vec<u8>> {
-    /* padding is removed */
+    // padding is removed
     let mut a = AES::new();
     let mut fin = false;
     let mut m: Vec<u8> = Vec::new();
@@ -500,7 +500,7 @@ pub fn ecpsp_dsa(
 
     let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let sc = Big::frombytes(s); /* s or &s? */
+    let sc = Big::frombytes(s); // s or &s?
     let fb = Big::frombytes(&b);
 
     let mut cb = Big::new();
@@ -510,7 +510,7 @@ pub fn ecpsp_dsa(
 
     while db.iszilch() {
         let mut u = Big::randomnum(&r, rng);
-        let w = Big::randomnum(&r, rng); /* side channel masking */
+        let w = Big::randomnum(&r, rng); // side channel masking
 
         V.copy(&G);
         V = V.mul(&u);
@@ -559,8 +559,8 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
 
     let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let cb = Big::frombytes(c); /* c or &c ? */
-    let mut db = Big::frombytes(d); /* d or &d ? */
+    let 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();
 
diff --git a/src/mpin.rs b/src/mpin.rs
index 795fc50..23b46a2 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -35,10 +35,9 @@ use hash384::HASH384;
 use hash512::HASH512;
 use rand::RAND;
 
-/* MPIN API Functions */
-
-/* Configure mode of operation */
+// MPIN API Functions
 
+// Configure mode of operation
 pub const EFS: usize = big::MODBYTES as usize;
 pub const EGS: usize = big::MODBYTES as usize;
 pub const BAD_PARAMS: isize = -11;
@@ -49,12 +48,11 @@ pub const SHA256: usize = 32;
 pub const SHA384: usize = 48;
 pub const SHA512: usize = 64;
 
-/* Configure your PIN here */
-
-pub const MAXPIN: i32 = 10000; /* PIN less than this */
-pub const PBLEN: i32 = 14; /* Number of bits in PIN */
-pub const TS: usize = 10; /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
-pub const TRAP: usize = 200; /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+// Configure your PIN here
+pub const MAXPIN: i32 = 10000; // PIN less than this
+pub const PBLEN: i32 = 14; // Number of bits in PIN
+pub const TS: usize = 10; // 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN)
+pub const TRAP: usize = 200; // 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN)
 
 #[allow(non_snake_case)]
 fn hash(sha: usize, c: &mut FP4, U: &mut ECP, r: &mut [u8]) -> bool {
@@ -117,8 +115,7 @@ fn hash(sha: usize, c: &mut FP4, U: &mut ECP, r: &mut [u8]) -> bool {
     return false;
 }
 
-/* Hash number (optional) and string to point on curve */
-
+/// Hash number (optional) and string to point on curve
 fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     let mut r: [u8; 64] = [0; 64];
     let mut didit = false;
@@ -180,7 +177,7 @@ fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     return true;
 }
 
-/* return time in slots since epoch */
+/// Return time in slots since epoch
 pub fn today() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -189,8 +186,8 @@ pub fn today() -> usize {
         / (60 * 1440)) as usize;
 }
 
-/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* maps a random u to a point on the curve */
+// these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043
+/// Maps a random u to a point on the curve
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
@@ -208,7 +205,7 @@ fn emap(u: &Big, cb: isize) -> ECP {
     return P;
 }
 
-/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+/// Returns u derived from P. Random value in range 1 to return value should then be added to u
 #[allow(non_snake_case)]
 fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
@@ -232,9 +229,9 @@ pub fn hash_id(sha: usize, id: &[u8], w: &mut [u8]) -> bool {
     return hashit(sha, 0, id, w);
 }
 
-/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
-/* Note that u and v are indistinguisible from random strings */
+// These next two functions implement elligator squared - http://eprint.iacr.org/2014/043
+// Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v}
+// Note that u and v are indistinguisible from random strings
 #[allow(non_snake_case)]
 pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     let mut t: [u8; EFS] = [0; EFS];
@@ -316,7 +313,7 @@ pub fn decoding(d: &mut [u8]) -> isize {
     return 0;
 }
 
-/* R=R1+R2 in group G1 */
+/// R=R1+R2 in group G1
 #[allow(non_snake_case)]
 pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     let mut P = ECP::frombytes(&r1);
@@ -332,7 +329,7 @@ pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     return 0;
 }
 
-/* W=W1+W2 in group G2 */
+/// W=W1+W2 in group G2
 #[allow(non_snake_case)]
 pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     let mut P = ECP2::frombytes(&w1);
@@ -348,7 +345,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     return 0;
 }
 
-/* create random secret S */
+/// create random secret S
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
     let sc = Big::randomnum(&r, rng);
@@ -356,7 +353,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     return 0;
 }
 
-/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+/// Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret
 #[allow(non_snake_case)]
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP2::generator();
@@ -367,12 +364,10 @@ pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     return 0;
 }
 
-/*
- W=x*H(G);
- if RNG == NULL then X is passed in
- if RNG != NULL the X is passed out
- if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
-*/
+/// W=x*H(G);
+/// if RNG == NULL then X is passed in
+/// if RNG != NULL the X is passed out
+/// if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
 #[allow(non_snake_case)]
 pub fn get_g1_multiple(
     rng: Option<&mut RAND>,
@@ -405,19 +400,19 @@ pub fn get_g1_multiple(
     return 0;
 }
 
-/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
-/* CID is hashed externally */
+/// Client secret CST=S*H(CID) where CID is client ID and S is master secret
+/// CID is hashed externally
 pub fn get_client_secret(s: &mut [u8], cid: &[u8], cst: &mut [u8]) -> isize {
     return get_g1_multiple(None, 1, s, cid, cst);
 }
 
-/* Extract PIN from TOKEN for identity CID */
+/// Extract PIN from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_pin(sha: usize, cid: &[u8], pin: i32, token: &mut [u8]) -> isize {
     return extract_factor(sha, cid, pin % MAXPIN, PBLEN, token);
 }
 
-/* Extract factor from TOKEN for identity CID */
+/// Extract factor from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_factor(
     sha: usize,
@@ -443,7 +438,7 @@ pub fn extract_factor(
     return 0;
 }
 
-/* Restore factor to TOKEN for identity CID */
+/// Restore factor to TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn restore_factor(
     sha: usize,
@@ -469,7 +464,7 @@ pub fn restore_factor(
     return 0;
 }
 
-/* Functions to support M-Pin Full */
+/// Functions to support M-Pin Full
 #[allow(non_snake_case)]
 pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isize {
     let T = ECP::frombytes(&token);
@@ -492,7 +487,7 @@ pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isi
     return 0;
 }
 
-/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+/// Time Permit CTT=S*(date|H(CID)) where S is master secret
 #[allow(non_snake_case)]
 pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mut [u8]) -> isize {
     const RM: usize = big::MODBYTES as usize;
@@ -505,7 +500,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     return 0;
 }
 
-/* Implement step 1 on client side of MPin protocol */
+/// Implement step 1 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_1(
     sha: usize,
@@ -578,7 +573,7 @@ pub fn client_1(
     return 0;
 }
 
-/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+/// Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID
 #[allow(non_snake_case)]
 pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Option<&mut [u8]>) {
     const RM: usize = big::MODBYTES as usize;
@@ -600,7 +595,7 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
     }
 }
 
-/* Implement step 2 on client side of MPin protocol */
+/// Implement step 2 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
@@ -621,7 +616,7 @@ pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     return 0;
 }
 
-/* return time since epoch */
+/// return time since epoch
 pub fn get_time() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -629,7 +624,7 @@ pub fn get_time() -> usize {
         .as_secs()) as usize;
 }
 
-/* Generate Y = H(epoch, xCID/xID) */
+/// Generate Y = H(epoch, xCID/xID)
 pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     const RM: usize = big::MODBYTES as usize;
     let mut h: [u8; RM] = [0; RM];
@@ -642,7 +637,7 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     sy.tobytes(y);
 }
 
-/* Implement step 2 of MPin protocol on server side */
+/// Implement step 2 of MPin protocol on server side
 #[allow(non_snake_case)]
 pub fn server_2(
     date: usize,
@@ -739,7 +734,7 @@ pub fn server_2(
     return 0;
 }
 
-/* Pollards kangaroos used to return PIN error */
+/// Pollards kangaroos used to return PIN error
 pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP12::frombytes(e);
     let mut gf = FP12::frombytes(f);
@@ -790,8 +785,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     return res;
 }
 
-/* Hash the M-Pin transcript - new */
-
+/// Hash the M-Pin transcript - new
 pub fn hash_all(
     sha: usize,
     hid: &[u8],
@@ -847,8 +841,8 @@ pub fn hash_all(
     return hashit(sha, 0, &t, h);
 }
 
-/* calculate common key on client side */
-/* wCID = w.(A+AT) */
+/// Calculate common key on client side
+/// wCID = w.(A+AT)
 #[allow(non_snake_case)]
 pub fn client_key(
     sha: usize,
@@ -889,8 +883,8 @@ pub fn client_key(
     return 0;
 }
 
-/* calculate common key on server side */
-/* Z=r.A - no time permits involved */
+/// calculate common key on server side
+/// Z=r.A - no time permits involved
 #[allow(non_snake_case)]
 pub fn server_key(
     sha: usize,
@@ -947,10 +941,9 @@ pub fn server_key(
 mod tests {
     use super::*;
     use crate::test_utils::*;
-    use std::io;
 
     #[test]
-    fn test_mpin() {
+    fn test_mpin_valid() {
         let mut rng = create_rng();
 
         pub const PERMITS: bool = true;
@@ -962,8 +955,8 @@ mod tests {
         let mut hcid: [u8; RM] = [0; RM];
         let mut hsid: [u8; RM] = [0; RM];
 
-        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-        const G2S: usize = 4 * EFS; /* Group 2 Size */
+        const G1S: usize = 2 * EFS + 1; // Group 1 Size
+        const G2S: usize = 4 * EFS; // Group 2 Size
         const EAS: usize = ecp::AESKEY;
 
         let mut sst: [u8; G2S] = [0; G2S];
@@ -992,22 +985,22 @@ mod tests {
         let sha = ecp::HASH_TYPE;
 
         println!("\nTesting MPIN - PIN is 1234");
-        /* Trusted Authority set-up */
+        // Trusted Authority set-up
 
         random_generate(&mut rng, &mut s);
         print!("Master Secret s: 0x");
         printbinary(&s);
 
-        /* Create Client Identity */
+        // Create Client Identity
         let name = "testUser@miracl.com";
         let client_id = name.as_bytes();
 
         print!("Client ID= ");
         printbinary(&client_id);
 
-        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+        hash_id(sha, &client_id, &mut hcid); // Either Client or TA calculates Hash(ID) - you decide!
 
-        /* Client and Server are issued secrets by DTA */
+        // Client and Server are issued secrets by DTA
         get_server_secret(&s, &mut sst);
         print!("Server Secret SS: 0x");
         printbinary(&sst);
@@ -1016,7 +1009,7 @@ mod tests {
         print!("Client Secret CS: 0x");
         printbinary(&token);
 
-        /* Client extracts PIN from secret to create Token */
+        // Client extracts PIN from secret to create Token
         let pin: i32 = 1234;
         println!("Client extracts PIN= {}", pin);
         let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
@@ -1034,13 +1027,13 @@ mod tests {
         let mut date = 0;
         if PERMITS {
             date = today();
-            /* Client gets "Time Token" permit from DTA */
+            // Client gets "Time Token" permit from DTA
 
             get_client_permit(sha, date, &s, &hcid, &mut permit);
             print!("Time Permit TP: 0x");
             printbinary(&permit);
 
-            /* This encoding makes Time permit look random - Elligator squared */
+            // This encoding makes Time permit look random - Elligator squared
             encoding(&mut rng, &mut permit);
             print!("Encoded Time Permit TP: 0x");
             printbinary(&permit);
@@ -1049,15 +1042,10 @@ mod tests {
             printbinary(&permit);
         }
 
-        print!("\nPIN= ");
-        let _ = io::Write::flush(&mut io::stdout());
-        let mut input_text = String::new();
-        let _ = io::stdin().read_line(&mut input_text);
-
-        let pin = input_text.trim().parse::<usize>().unwrap();
+        let pin = 1234;
 
         println!("MPIN Multi Pass");
-        /* Send U=x.ID to server, and recreate secret from token and pin */
+        // Send U=x.ID to server, and recreate secret from token and pin
         rtn = client_1(
             sha,
             date,
@@ -1077,10 +1065,10 @@ mod tests {
 
         if FULL {
             hash_id(sha, &client_id, &mut hcid);
-            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); // Also Send Z=r.ID to Server, remember random r
         }
 
-        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+        // Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp.
 
         server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
 
@@ -1090,22 +1078,22 @@ mod tests {
             rhid.clone_from_slice(&hid[..]);
         }
 
-        /* Server generates Random number Y and sends it to Client */
+        // Server generates Random number Y and sends it to Client
         random_generate(&mut rng, &mut y);
 
         if FULL {
             hash_id(sha, &client_id, &mut hsid);
-            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); // Also send T=w.ID to client, remember random w
         }
 
-        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC
         rtn = client_2(&x, &y, &mut sec);
         if rtn != 0 {
             println!("FAILURE: CLIENT_2 rtn: {}", rtn);
         }
 
-        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-        /* If PIN error not required, set E and F = null */
+        // Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error.
+        // If PIN error not required, set E and F = null
 
         if !PINERROR {
             rtn = server_2(
diff --git a/src/mpin192.rs b/src/mpin192.rs
index d2ed7b9..a8a40b0 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -35,10 +35,9 @@ use hash384::HASH384;
 use hash512::HASH512;
 use rand::RAND;
 
-/* MPIN API Functions */
-
-/* Configure mode of operation */
+// MPIN API Functions
 
+// Configure mode of operation
 pub const EFS: usize = big::MODBYTES as usize;
 pub const EGS: usize = big::MODBYTES as usize;
 pub const BAD_PARAMS: isize = -11;
@@ -49,12 +48,11 @@ pub const SHA256: usize = 32;
 pub const SHA384: usize = 48;
 pub const SHA512: usize = 64;
 
-/* Configure your PIN here */
-
-pub const MAXPIN: i32 = 10000; /* PIN less than this */
-pub const PBLEN: i32 = 14; /* Number of bits in PIN */
-pub const TS: usize = 10; /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
-pub const TRAP: usize = 200; /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+// Configure your PIN here
+pub const MAXPIN: i32 = 10000; // PIN less than this
+pub const PBLEN: i32 = 14; // Number of bits in PIN
+pub const TS: usize = 10; // 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN)
+pub const TRAP: usize = 200; // 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN)
 
 #[allow(non_snake_case)]
 fn hash(sha: usize, c: &mut FP8, U: &mut ECP, r: &mut [u8]) -> bool {
@@ -133,8 +131,7 @@ fn hash(sha: usize, c: &mut FP8, U: &mut ECP, r: &mut [u8]) -> bool {
     return false;
 }
 
-/* Hash number (optional) and string to point on curve */
-
+/// Hash number (optional) and string to point on curve
 fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     let mut r: [u8; 64] = [0; 64];
     let mut didit = false;
@@ -196,7 +193,7 @@ fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     return true;
 }
 
-/* return time in slots since epoch */
+/// return time in slots since epoch
 pub fn today() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -205,8 +202,8 @@ pub fn today() -> usize {
         / (60 * 1440)) as usize;
 }
 
-/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* maps a random u to a point on the curve */
+// these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043
+/// Maps a random u to a point on the curve
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
@@ -224,7 +221,7 @@ fn emap(u: &Big, cb: isize) -> ECP {
     return P;
 }
 
-/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+/// Returns u derived from P. Random value in range 1 to return value should then be added to u
 #[allow(non_snake_case)]
 fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
@@ -248,9 +245,9 @@ pub fn hash_id(sha: usize, id: &[u8], w: &mut [u8]) -> bool {
     return hashit(sha, 0, id, w);
 }
 
-/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
-/* Note that u and v are indistinguisible from random strings */
+// these next two functions implement elligator squared - http://eprint.iacr.org/2014/043
+// Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v}
+// Note that u and v are indistinguisible from random strings
 #[allow(non_snake_case)]
 pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     let mut t: [u8; EFS] = [0; EFS];
@@ -332,7 +329,7 @@ pub fn decoding(d: &mut [u8]) -> isize {
     return 0;
 }
 
-/* R=R1+R2 in group G1 */
+/// R=R1+R2 in group G1
 #[allow(non_snake_case)]
 pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     let mut P = ECP::frombytes(&r1);
@@ -348,7 +345,7 @@ pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     return 0;
 }
 
-/* W=W1+W2 in group G2 */
+/// W=W1+W2 in group G2
 #[allow(non_snake_case)]
 pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     let mut P = ECP4::frombytes(&w1);
@@ -364,7 +361,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     return 0;
 }
 
-/* create random secret S */
+/// Create random secret S
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
     let sc = Big::randomnum(&r, rng);
@@ -372,7 +369,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     return 0;
 }
 
-/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+/// Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret
 #[allow(non_snake_case)]
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP4::generator();
@@ -382,12 +379,10 @@ pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     return 0;
 }
 
-/*
- W=x*H(G);
- if RNG == NULL then X is passed in
- if RNG != NULL the X is passed out
- if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
-*/
+/// W=x*H(G);
+/// if RNG == NULL then X is passed in
+/// if RNG != NULL the X is passed out
+/// if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
 #[allow(non_snake_case)]
 pub fn get_g1_multiple(
     rng: Option<&mut RAND>,
@@ -420,19 +415,19 @@ pub fn get_g1_multiple(
     return 0;
 }
 
-/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
-/* CID is hashed externally */
+/// Client secret CST=S*H(CID) where CID is client ID and S is master secret
+/// CID is hashed externally
 pub fn get_client_secret(s: &mut [u8], cid: &[u8], cst: &mut [u8]) -> isize {
     return get_g1_multiple(None, 1, s, cid, cst);
 }
 
-/* Extract PIN from TOKEN for identity CID */
+/// Extract PIN from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_pin(sha: usize, cid: &[u8], pin: i32, token: &mut [u8]) -> isize {
     return extract_factor(sha, cid, pin % MAXPIN, PBLEN, token);
 }
 
-/* Extract factor from TOKEN for identity CID */
+/// Extract factor from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_factor(
     sha: usize,
@@ -458,7 +453,7 @@ pub fn extract_factor(
     return 0;
 }
 
-/* Restore factor to TOKEN for identity CID */
+/// Restore factor to TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn restore_factor(
     sha: usize,
@@ -484,7 +479,7 @@ pub fn restore_factor(
     return 0;
 }
 
-/* Functions to support M-Pin Full */
+/// Functions to support M-Pin Full
 #[allow(non_snake_case)]
 pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isize {
     let T = ECP::frombytes(&token);
@@ -507,7 +502,7 @@ pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isi
     return 0;
 }
 
-/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+/// Time Permit CTT=S*(date|H(CID)) where S is master secret
 #[allow(non_snake_case)]
 pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mut [u8]) -> isize {
     const RM: usize = big::MODBYTES as usize;
@@ -520,7 +515,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     return 0;
 }
 
-/* Implement step 1 on client side of MPin protocol */
+/// Implement step 1 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_1(
     sha: usize,
@@ -593,7 +588,7 @@ pub fn client_1(
     return 0;
 }
 
-/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+/// Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID
 #[allow(non_snake_case)]
 pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Option<&mut [u8]>) {
     const RM: usize = big::MODBYTES as usize;
@@ -615,7 +610,7 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
     }
 }
 
-/* Implement step 2 on client side of MPin protocol */
+/// Implement step 2 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     let mut r = Big::new_ints(&rom::CURVE_ORDER);
@@ -636,7 +631,7 @@ pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     return 0;
 }
 
-/* return time since epoch */
+/// return time since epoch
 pub fn get_time() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -644,7 +639,7 @@ pub fn get_time() -> usize {
         .as_secs()) as usize;
 }
 
-/* Generate Y = H(epoch, xCID/xID) */
+/// Generate Y = H(epoch, xCID/xID)
 pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     const RM: usize = big::MODBYTES as usize;
     let mut h: [u8; RM] = [0; RM];
@@ -657,7 +652,7 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     sy.tobytes(y);
 }
 
-/* Implement step 2 of MPin protocol on server side */
+/// Implement step 2 of MPin protocol on server side
 #[allow(non_snake_case)]
 pub fn server_2(
     date: usize,
@@ -754,7 +749,7 @@ pub fn server_2(
     return 0;
 }
 
-/* Pollards kangaroos used to return PIN error */
+/// Pollards kangaroos used to return PIN error
 pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP24::frombytes(e);
     let mut gf = FP24::frombytes(f);
@@ -805,8 +800,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     return res;
 }
 
-/* Hash the M-Pin transcript - new */
-
+/// Hash the M-Pin transcript - new
 pub fn hash_all(
     sha: usize,
     hid: &[u8],
@@ -862,8 +856,8 @@ pub fn hash_all(
     return hashit(sha, 0, &t, h);
 }
 
-/* calculate common key on client side */
-/* wCID = w.(A+AT) */
+/// calculate common key on client side
+/// wCID = w.(A+AT)
 #[allow(non_snake_case)]
 pub fn client_key(
     sha: usize,
@@ -904,8 +898,8 @@ pub fn client_key(
     return 0;
 }
 
-/* calculate common key on server side */
-/* Z=r.A - no time permits involved */
+/// Calculate common key on server side
+/// Z=r.A - no time permits involved
 #[allow(non_snake_case)]
 pub fn server_key(
     sha: usize,
@@ -962,24 +956,22 @@ pub fn server_key(
 mod tests {
     use super::*;
     use crate::test_utils::*;
-    use std::io;
 
     #[test]
-    fn test_mpin192() {
+    fn test_mpin192_valid() {
         let mut rng = create_rng();
 
         pub const PERMITS: bool = true;
         pub const PINERROR: bool = true;
         pub const FULL: bool = true;
-        //pub const SINGLE_PASS:bool=false;
 
         let mut s: [u8; EGS] = [0; EGS];
         const RM: usize = EFS as usize;
         let mut hcid: [u8; RM] = [0; RM];
         let mut hsid: [u8; RM] = [0; RM];
 
-        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-        const G2S: usize = 16 * EFS; /* Group 2 Size */
+        const G1S: usize = 2 * EFS + 1; // Group 1 Size
+        const G2S: usize = 16 * EFS; // Group 2 Size
         const EAS: usize = ecp::AESKEY;
 
         let mut sst: [u8; G2S] = [0; G2S];
@@ -1008,22 +1000,22 @@ mod tests {
         let sha = ecp::HASH_TYPE;
 
         println!("\nTesting MPIN - PIN is 1234");
-        /* Trusted Authority set-up */
+        // Trusted Authority set-up
 
         random_generate(&mut rng, &mut s);
         print!("Master Secret s: 0x");
         printbinary(&s);
 
-        /* Create Client Identity */
+        // Create Client Identity
         let name = "testUser@miracl.com";
         let client_id = name.as_bytes();
 
         print!("Client ID= ");
         printbinary(&client_id);
 
-        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+        hash_id(sha, &client_id, &mut hcid); // Either Client or TA calculates Hash(ID) - you decide!
 
-        /* Client and Server are issued secrets by DTA */
+        // Client and Server are issued secrets by DTA
         get_server_secret(&s, &mut sst);
         print!("Server Secret SS: 0x");
         printbinary(&sst);
@@ -1032,7 +1024,7 @@ mod tests {
         print!("Client Secret CS: 0x");
         printbinary(&token);
 
-        /* Client extracts PIN from secret to create Token */
+        // Client extracts PIN from secret to create Token
         let pin: i32 = 1234;
         println!("Client extracts PIN= {}", pin);
         let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
@@ -1050,13 +1042,13 @@ mod tests {
         let mut date = 0;
         if PERMITS {
             date = today();
-            /* Client gets "Time Token" permit from DTA */
+            // Client gets "Time Token" permit from DTA
 
             get_client_permit(sha, date, &s, &hcid, &mut permit);
             print!("Time Permit TP: 0x");
             printbinary(&permit);
 
-            /* This encoding makes Time permit look random - Elligator squared */
+            // This encoding makes Time permit look random - Elligator squared
             encoding(&mut rng, &mut permit);
             print!("Encoded Time Permit TP: 0x");
             printbinary(&permit);
@@ -1065,15 +1057,10 @@ mod tests {
             printbinary(&permit);
         }
 
-        print!("\nPIN= ");
-        let _ = io::Write::flush(&mut io::stdout());
-        let mut input_text = String::new();
-        let _ = io::stdin().read_line(&mut input_text);
-
-        let pin = input_text.trim().parse::<usize>().unwrap();
+        let pin = 1234;
 
         println!("MPIN Multi Pass");
-        /* Send U=x.ID to server, and recreate secret from token and pin */
+        // Send U=x.ID to server, and recreate secret from token and pin
         rtn = client_1(
             sha,
             date,
@@ -1093,10 +1080,10 @@ mod tests {
 
         if FULL {
             hash_id(sha, &client_id, &mut hcid);
-            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); // Also Send Z=r.ID to Server, remember random r
         }
 
-        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+        // Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp.
 
         server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
 
@@ -1106,22 +1093,22 @@ mod tests {
             rhid.clone_from_slice(&hid[..]);
         }
 
-        /* Server generates Random number Y and sends it to Client */
+        // Server generates Random number Y and sends it to Client
         random_generate(&mut rng, &mut y);
 
         if FULL {
             hash_id(sha, &client_id, &mut hsid);
-            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); // Also send T=w.ID to client, remember random w
         }
 
-        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC
         rtn = client_2(&x, &y, &mut sec);
         if rtn != 0 {
             println!("FAILURE: CLIENT_2 rtn: {}", rtn);
         }
 
-        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-        /* If PIN error not required, set E and F = null */
+        // Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error.
+        // If PIN error not required, set E and F = null
 
         if !PINERROR {
             rtn = server_2(
diff --git a/src/mpin256.rs b/src/mpin256.rs
index 65a06d9..22db48e 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -35,10 +35,9 @@ use hash384::HASH384;
 use hash512::HASH512;
 use rand::RAND;
 
-/* MPIN API Functions */
-
-/* Configure mode of operation */
+// MPIN API Functions
 
+// Configure mode of operation
 pub const EFS: usize = big::MODBYTES as usize;
 pub const EGS: usize = big::MODBYTES as usize;
 pub const BAD_PARAMS: isize = -11;
@@ -49,12 +48,11 @@ pub const SHA256: usize = 32;
 pub const SHA384: usize = 48;
 pub const SHA512: usize = 64;
 
-/* Configure your PIN here */
-
-pub const MAXPIN: i32 = 10000; /* PIN less than this */
-pub const PBLEN: i32 = 14; /* Number of bits in PIN */
-pub const TS: usize = 10; /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
-pub const TRAP: usize = 200; /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+// Configure your PIN here
+pub const MAXPIN: i32 = 10000; // PIN less than this
+pub const PBLEN: i32 = 14; // Number of bits in PIN
+pub const TS: usize = 10; // 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN)
+pub const TRAP: usize = 200; // 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN)
 
 #[allow(non_snake_case)]
 fn hash(sha: usize, c: &mut FP16, U: &mut ECP, r: &mut [u8]) -> bool {
@@ -166,8 +164,7 @@ fn hash(sha: usize, c: &mut FP16, U: &mut ECP, r: &mut [u8]) -> bool {
     return false;
 }
 
-/* Hash number (optional) and string to point on curve */
-
+/// Hash number (optional) and string to point on curve
 fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     let mut r: [u8; 64] = [0; 64];
     let mut didit = false;
@@ -229,7 +226,7 @@ fn hashit(sha: usize, n: usize, id: &[u8], w: &mut [u8]) -> bool {
     return true;
 }
 
-/* return time in slots since epoch */
+/// Return time in slots since epoch
 pub fn today() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -238,8 +235,8 @@ pub fn today() -> usize {
         / (60 * 1440)) as usize;
 }
 
-/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* maps a random u to a point on the curve */
+/// these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043
+/// maps a random u to a point on the curve
 #[allow(non_snake_case)]
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
@@ -257,7 +254,7 @@ fn emap(u: &Big, cb: isize) -> ECP {
     return P;
 }
 
-/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+/// returns u derived from P. Random value in range 1 to return value should then be added to u
 #[allow(non_snake_case)]
 fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
@@ -281,9 +278,9 @@ pub fn hash_id(sha: usize, id: &[u8], w: &mut [u8]) -> bool {
     return hashit(sha, 0, id, w);
 }
 
-/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
-/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
-/* Note that u and v are indistinguisible from random strings */
+// these next two functions implement elligator squared - http://eprint.iacr.org/2014/043
+// Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v}
+// Note that u and v are indistinguisible from random strings
 #[allow(non_snake_case)]
 pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     let mut t: [u8; EFS] = [0; EFS];
@@ -365,7 +362,7 @@ pub fn decoding(d: &mut [u8]) -> isize {
     return 0;
 }
 
-/* R=R1+R2 in group G1 */
+/// R=R1+R2 in group G1
 #[allow(non_snake_case)]
 pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     let mut P = ECP::frombytes(&r1);
@@ -381,7 +378,7 @@ pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     return 0;
 }
 
-/* W=W1+W2 in group G2 */
+/// W=W1+W2 in group G2
 #[allow(non_snake_case)]
 pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     let mut P = ECP8::frombytes(&w1);
@@ -397,7 +394,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     return 0;
 }
 
-/* create random secret S */
+/// Create random secret S
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
     let sc = Big::randomnum(&r, rng);
@@ -405,7 +402,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     return 0;
 }
 
-/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+/// Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret
 #[allow(non_snake_case)]
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP8::generator();
@@ -416,12 +413,10 @@ pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     return 0;
 }
 
-/*
- W=x*H(G);
- if RNG == NULL then X is passed in
- if RNG != NULL the X is passed out
- if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
-*/
+/// W=x*H(G);
+/// if RNG == NULL then X is passed in
+/// if RNG != NULL the X is passed out
+// if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
 #[allow(non_snake_case)]
 pub fn get_g1_multiple(
     rng: Option<&mut RAND>,
@@ -454,19 +449,19 @@ pub fn get_g1_multiple(
     return 0;
 }
 
-/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
-/* CID is hashed externally */
+/// Client secret CST=S*H(CID) where CID is client ID and S is master secret
+/// CID is hashed externally
 pub fn get_client_secret(s: &mut [u8], cid: &[u8], cst: &mut [u8]) -> isize {
     return get_g1_multiple(None, 1, s, cid, cst);
 }
 
-/* Extract PIN from TOKEN for identity CID */
+/// Extract PIN from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_pin(sha: usize, cid: &[u8], pin: i32, token: &mut [u8]) -> isize {
     return extract_factor(sha, cid, pin % MAXPIN, PBLEN, token);
 }
 
-/* Extract factor from TOKEN for identity CID */
+/// Extract factor from TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn extract_factor(
     sha: usize,
@@ -492,7 +487,7 @@ pub fn extract_factor(
     return 0;
 }
 
-/* Restore factor to TOKEN for identity CID */
+/// Restore factor to TOKEN for identity CID
 #[allow(non_snake_case)]
 pub fn restore_factor(
     sha: usize,
@@ -518,7 +513,7 @@ pub fn restore_factor(
     return 0;
 }
 
-/* Functions to support M-Pin Full */
+/// Functions to support M-Pin Full
 #[allow(non_snake_case)]
 pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isize {
     let T = ECP::frombytes(&token);
@@ -541,7 +536,7 @@ pub fn precompute(token: &[u8], cid: &[u8], g1: &mut [u8], g2: &mut [u8]) -> isi
     return 0;
 }
 
-/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+/// Time Permit CTT=S*(date|H(CID)) where S is master secret
 #[allow(non_snake_case)]
 pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mut [u8]) -> isize {
     const RM: usize = big::MODBYTES as usize;
@@ -554,7 +549,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     return 0;
 }
 
-/* Implement step 1 on client side of MPin protocol */
+/// Implement step 1 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_1(
     sha: usize,
@@ -627,7 +622,7 @@ pub fn client_1(
     return 0;
 }
 
-/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+/// Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID
 #[allow(non_snake_case)]
 pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Option<&mut [u8]>) {
     const RM: usize = big::MODBYTES as usize;
@@ -649,7 +644,7 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
     }
 }
 
-/* Implement step 2 on client side of MPin protocol */
+/// Implement step 2 on client side of MPin protocol
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     let mut r = Big::new_ints(&rom::CURVE_ORDER);
@@ -670,7 +665,7 @@ pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     return 0;
 }
 
-/* return time since epoch */
+/// Return time since epoch
 pub fn get_time() -> usize {
     return (SystemTime::now()
         .duration_since(UNIX_EPOCH)
@@ -678,7 +673,7 @@ pub fn get_time() -> usize {
         .as_secs()) as usize;
 }
 
-/* Generate Y = H(epoch, xCID/xID) */
+/// Generate Y = H(epoch, xCID/xID)
 pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     const RM: usize = big::MODBYTES as usize;
     let mut h: [u8; RM] = [0; RM];
@@ -691,7 +686,7 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     sy.tobytes(y);
 }
 
-/* Implement step 2 of MPin protocol on server side */
+/// Implement step 2 of MPin protocol on server side
 #[allow(non_snake_case)]
 pub fn server_2(
     date: usize,
@@ -788,7 +783,7 @@ pub fn server_2(
     return 0;
 }
 
-/* Pollards kangaroos used to return PIN error */
+/// Pollards kangaroos used to return PIN error
 pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut ge = FP48::frombytes(e);
     let mut gf = FP48::frombytes(f);
@@ -839,8 +834,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     return res;
 }
 
-/* Hash the M-Pin transcript - new */
-
+/// Hash the M-Pin transcript - new
 pub fn hash_all(
     sha: usize,
     hid: &[u8],
@@ -896,8 +890,8 @@ pub fn hash_all(
     return hashit(sha, 0, &t, h);
 }
 
-/* calculate common key on client side */
-/* wCID = w.(A+AT) */
+/// Calculate common key on client side
+/// wCID = w.(A+AT)
 #[allow(non_snake_case)]
 pub fn client_key(
     sha: usize,
@@ -938,8 +932,8 @@ pub fn client_key(
     return 0;
 }
 
-/* calculate common key on server side */
-/* Z=r.A - no time permits involved */
+/// Calculate common key on server side
+/// Z=r.A - no time permits involved
 #[allow(non_snake_case)]
 pub fn server_key(
     sha: usize,
@@ -996,24 +990,22 @@ pub fn server_key(
 mod tests {
     use super::*;
     use crate::test_utils::*;
-    use std::io;
 
     #[test]
-    fn test_mpin256() {
+    fn test_mpin256_valid() {
         let mut rng = create_rng();
 
         pub const PERMITS: bool = true;
         pub const PINERROR: bool = true;
         pub const FULL: bool = true;
-        //pub const SINGLE_PASS:bool=false;
 
         let mut s: [u8; EGS] = [0; EGS];
         const RM: usize = EFS as usize;
         let mut hcid: [u8; RM] = [0; RM];
         let mut hsid: [u8; RM] = [0; RM];
 
-        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-        const G2S: usize = 16 * EFS; /* Group 2 Size */
+        const G1S: usize = 2 * EFS + 1; // Group 1 Size
+        const G2S: usize = 16 * EFS; // Group 2 Size
         const EAS: usize = ecp::AESKEY;
 
         let mut sst: [u8; G2S] = [0; G2S];
@@ -1042,22 +1034,22 @@ mod tests {
         let sha = ecp::HASH_TYPE;
 
         println!("\nTesting MPIN - PIN is 1234");
-        /* Trusted Authority set-up */
+        // Trusted Authority set-up
 
         random_generate(&mut rng, &mut s);
         print!("Master Secret s: 0x");
         printbinary(&s);
 
-        /* Create Client Identity */
+        // Create Client Identity
         let name = "testUser@miracl.com";
         let client_id = name.as_bytes();
 
         print!("Client ID= ");
         printbinary(&client_id);
 
-        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+        hash_id(sha, &client_id, &mut hcid); // Either Client or TA calculates Hash(ID) - you decide!
 
-        /* Client and Server are issued secrets by DTA */
+        // Client and Server are issued secrets by DTA
         get_server_secret(&s, &mut sst);
         print!("Server Secret SS: 0x");
         printbinary(&sst);
@@ -1066,7 +1058,7 @@ mod tests {
         print!("Client Secret CS: 0x");
         printbinary(&token);
 
-        /* Client extracts PIN from secret to create Token */
+        // Client extracts PIN from secret to create Token
         let pin: i32 = 1234;
         println!("Client extracts PIN= {}", pin);
         let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
@@ -1084,13 +1076,13 @@ mod tests {
         let mut date = 0;
         if PERMITS {
             date = today();
-            /* Client gets "Time Token" permit from DTA */
+            // Client gets "Time Token" permit from DTA
 
             get_client_permit(sha, date, &s, &hcid, &mut permit);
             print!("Time Permit TP: 0x");
             printbinary(&permit);
 
-            /* This encoding makes Time permit look random - Elligator squared */
+            // This encoding makes Time permit look random - Elligator squared
             encoding(&mut rng, &mut permit);
             print!("Encoded Time Permit TP: 0x");
             printbinary(&permit);
@@ -1099,15 +1091,10 @@ mod tests {
             printbinary(&permit);
         }
 
-        print!("\nPIN= ");
-        let _ = io::Write::flush(&mut io::stdout());
-        let mut input_text = String::new();
-        let _ = io::stdin().read_line(&mut input_text);
-
-        let pin = input_text.trim().parse::<usize>().unwrap();
+        let pin = 1234;
 
         println!("MPIN Multi Pass");
-        /* Send U=x.ID to server, and recreate secret from token and pin */
+        // Send U=x.ID to server, and recreate secret from token and pin
         rtn = client_1(
             sha,
             date,
@@ -1127,10 +1114,10 @@ mod tests {
 
         if FULL {
             hash_id(sha, &client_id, &mut hcid);
-            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); // Also Send Z=r.ID to Server, remember random r
         }
 
-        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+        // Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp.
 
         server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
 
@@ -1140,22 +1127,22 @@ mod tests {
             rhid.clone_from_slice(&hid[..]);
         }
 
-        /* Server generates Random number Y and sends it to Client */
+        // Server generates Random number Y and sends it to Client
         random_generate(&mut rng, &mut y);
 
         if FULL {
             hash_id(sha, &client_id, &mut hsid);
-            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); // Also send T=w.ID to client, remember random w
         }
 
-        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC
         rtn = client_2(&x, &y, &mut sec);
         if rtn != 0 {
             println!("FAILURE: CLIENT_2 rtn: {}", rtn);
         }
 
-        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-        /* If PIN error not required, set E and F = null */
+        // Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error.
+        // If PIN error not required, set E and F = null
 
         if !PINERROR {
             rtn = server_2(


[incubator-milagro-crypto-rust] 16/44: Merge pull request #6 from sigp/monty-documentation

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 881a6699258276ae7adf3fa19ef456cb127fddf8
Merge: d358b74 f3fff8d
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Fri Dec 13 09:10:11 2019 +0000

    Merge pull request #6 from sigp/monty-documentation
    
    Documentation

 src/big.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 47 insertions(+), 15 deletions(-)


[incubator-milagro-crypto-rust] 14/44: Update .gitignore to exclude test and bench binaries

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 6c0f1982e1f248997c4fa5940f74d2e6ec733629
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Dec 13 16:05:23 2019 +1100

    Update .gitignore to exclude test and bench binaries
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 .gitignore | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2c96eb1..962da4e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,6 @@
 target/
 Cargo.lock
+TestALL
+TestBLS
+TestNHS
+BenchtestALL


[incubator-milagro-crypto-rust] 06/44: Massive reformatting and style changes

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit ddb0937f5d182b72a70ae01b2c6bd02bf12cb718
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Thu Aug 8 14:32:49 2019 +1000

    Massive reformatting and style changes
---
 BenchtestALL.rs               |  16 +-
 readme.md                     |  37 ++--
 src/aes.rs                    |  79 +++++----
 src/big.rs                    | 182 +++++++++-----------
 src/bls.rs                    |  28 +--
 src/bls192.rs                 |  26 +--
 src/bls256.rs                 |  24 +--
 src/dbig.rs                   |  57 ++++---
 src/ecdh.rs                   | 121 ++++++-------
 src/ecp.rs                    | 129 +++++++-------
 src/ecp2.rs                   | 111 ++++++------
 src/ecp4.rs                   |  28 +--
 src/ecp8.rs                   |  38 ++---
 src/ff.rs                     |   4 +-
 src/fp.rs                     | 144 ++++++++--------
 src/fp12.rs                   | 385 ++++++++++++++++++++++++------------------
 src/fp16.rs                   |  24 +--
 src/fp2.rs                    |  30 ++--
 src/fp24.rs                   | 350 ++++++++++++++++++++++----------------
 src/fp4.rs                    |  34 ++--
 src/fp48.rs                   | 352 ++++++++++++++++++++++----------------
 src/fp8.rs                    |  25 ++-
 src/hash256.rs                |  16 +-
 src/lib.rs                    | 182 ++++++++++----------
 src/mpin.rs                   | 109 ++++++------
 src/mpin192.rs                |   9 +-
 src/mpin256.rs                |   6 +-
 src/nhs.rs                    |  10 +-
 src/pair.rs                   | 197 +++++++++++----------
 src/pair192.rs                |  95 ++++++-----
 src/pair256.rs                | 117 +++++++------
 src/rand.rs                   |   2 +-
 src/roms/rom_anssi_32.rs      |  14 +-
 src/roms/rom_anssi_64.rs      |  14 +-
 src/roms/rom_bls24_32.rs      |  14 +-
 src/roms/rom_bls24_64.rs      |  14 +-
 src/roms/rom_bls381_32.rs     |  14 +-
 src/roms/rom_bls381_64.rs     |  14 +-
 src/roms/rom_bls383_32.rs     |  14 +-
 src/roms/rom_bls383_64.rs     |  14 +-
 src/roms/rom_bls461_32.rs     |  14 +-
 src/roms/rom_bls461_64.rs     |  14 +-
 src/roms/rom_bls48_32.rs      |  14 +-
 src/roms/rom_bls48_64.rs      |  14 +-
 src/roms/rom_bn254CX_32.rs    |  14 +-
 src/roms/rom_bn254CX_64.rs    |  15 +-
 src/roms/rom_bn254_32.rs      |  14 +-
 src/roms/rom_bn254_64.rs      |  16 +-
 src/roms/rom_brainpool_32.rs  |  14 +-
 src/roms/rom_brainpool_64.rs  |  14 +-
 src/roms/rom_c25519_32.rs     |  14 +-
 src/roms/rom_c25519_64.rs     |  14 +-
 src/roms/rom_c41417_32.rs     |  14 +-
 src/roms/rom_c41417_64.rs     |  14 +-
 src/roms/rom_ed25519_32.rs    |  14 +-
 src/roms/rom_ed25519_64.rs    |  14 +-
 src/roms/rom_fp256bn_32.rs    |  15 +-
 src/roms/rom_fp256bn_64.rs    |  14 +-
 src/roms/rom_fp512bn_32.rs    |  14 +-
 src/roms/rom_fp512bn_64.rs    |  14 +-
 src/roms/rom_goldilocks_32.rs |  14 +-
 src/roms/rom_goldilocks_64.rs |  14 +-
 src/roms/rom_hifive_32.rs     |  14 +-
 src/roms/rom_hifive_64.rs     |  14 +-
 src/roms/rom_nist256_32.rs    |  17 +-
 src/roms/rom_nist256_64.rs    |  14 +-
 src/roms/rom_nist384_32.rs    |  14 +-
 src/roms/rom_nist384_64.rs    |  15 +-
 src/roms/rom_nist521_32.rs    |  14 +-
 src/roms/rom_nist521_64.rs    |  14 +-
 src/roms/rom_nums256e_32.rs   |  15 +-
 src/roms/rom_nums256e_64.rs   |  15 +-
 src/roms/rom_nums256w_32.rs   |  14 +-
 src/roms/rom_nums256w_64.rs   |  14 +-
 src/roms/rom_nums384e_32.rs   |  15 +-
 src/roms/rom_nums384e_64.rs   |  15 +-
 src/roms/rom_nums384w_32.rs   |  15 +-
 src/roms/rom_nums384w_64.rs   |  15 +-
 src/roms/rom_nums512e_32.rs   |  14 +-
 src/roms/rom_nums512e_64.rs   |  14 +-
 src/roms/rom_nums512w_32.rs   |  14 +-
 src/roms/rom_nums512w_64.rs   |  14 +-
 src/roms/rom_rsa2048_32.rs    |   2 +-
 src/roms/rom_rsa2048_64.rs    |   2 +-
 src/roms/rom_rsa3072_32.rs    |   2 +-
 src/roms/rom_rsa3072_64.rs    |   2 +-
 src/roms/rom_rsa4096_32.rs    |   2 +-
 src/roms/rom_rsa4096_64.rs    |   2 +-
 src/roms/rom_secp256k1_32.rs  |  14 +-
 src/roms/rom_secp256k1_64.rs  |  14 +-
 src/sha3.rs                   |   2 +-
 src/types.rs                  |  39 +++--
 92 files changed, 1955 insertions(+), 1807 deletions(-)

diff --git a/BenchtestALL.rs b/BenchtestALL.rs
index 55961be..ff8fb92 100644
--- a/BenchtestALL.rs
+++ b/BenchtestALL.rs
@@ -231,10 +231,10 @@ fn bn254(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing BN254 Pairings");
 
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
 		println!("BN Pairing-Friendly Curve");
 	}
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
 		println!("BLS Pairing-Friendly Curve");
 	}
 
@@ -391,10 +391,10 @@ fn bls383(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing BLS383 Pairings");
 
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
 		println!("BN Pairing-Friendly Curve");
 	}
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
 		println!("BLS Pairing-Friendly Curve");
 	}
 
@@ -551,10 +551,10 @@ fn bls24(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing BLS24 Pairings");
 
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
 		println!("BN Pairing-Friendly Curve");
 	}
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
 		println!("BLS24 Pairing-Friendly Curve");
 	}
 
@@ -711,10 +711,10 @@ fn bls48(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing BLS48 Pairings");
 
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
 		println!("BN Pairing-Friendly Curve");
 	}
-	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
 		println!("BLS48 Pairing-Friendly Curve");
 	}
 
diff --git a/readme.md b/readme.md
index da805e0..98f7d20 100644
--- a/readme.md
+++ b/readme.md
@@ -1,26 +1,28 @@
+# Apache Milagro Crypto Library - Rust Version
+
 NOTE: Updated to Rust 2018
 
-NOTE: This version of the library requires Version 1.31+ of Rust for 64-bit 
-integer support and for Rust 2018. 
+NOTE: This version of the library requires Version 1.31+ of Rust for 64-bit
+integer support and for Rust 2018.
 
 Now AMCL version 3 is distributed as a cargo crate.
 
 Namespaces are used to separate different curves.
 
-To build the library and see it in action, copy all of the files in this 
-directory and its subdirectories to a fresh root directory. 
+To build the library and see it in action, copy all of the files in this
+directory and its subdirectories to a fresh root directory.
 
 Then for example execute
-
+```
 cargo rustc  --release --features "bn254 bls383 bls24 bls48 ed25519 nist256 goldilocks rsa2048"
-
-This will create a build of the library for the current default target (be it 32 or 64 bits). 
+```
+This will create a build of the library for the current default target (be it 32 or 64 bits).
 
 (To test a 32-bit environment you can follow the Web Assembly (wasm) readme instructions for rust)
 
-Next copy the library from target/release/libamcl.rlib into the root 
+Next copy the library from `target/release/libamcl.rlib` into the root
 directory and execute
-
+```
 rustc TestALL.rs --extern amcl=libamcl.rlib
 
 rustc TestBLS.rs --extern amcl=libamcl.rlib
@@ -28,23 +30,29 @@ rustc TestBLS.rs --extern amcl=libamcl.rlib
 rustc BenchtestALL.rs --extern amcl=libamcl.rlib
 
 rustc TestNHS.rs --extern amcl=libamcl.rlib
+```
 
 Finally execute these programs.
 
-To add amcl functionality to your own programs, add a dependency to your 
-Cargo.toml file. For example to use the curve bls48, add this dependency
+To add amcl functionality to your own programs, add a dependency to your
+`Cargo.toml` file. For example to use the curve bls48, add this dependency
 
+```
 [dependencies]
-
 amcl = { version = "0.2.0",  optional = true, default-features = false, features = ["bls48"]}
+```
 
-if published to crates.io, or 
+If published to crates.io, or
 
+```
 amcl = { version = "0.2.0",  optional = true, default-features = false, features = ["bls48"], path="your_amcl_location" }
+```
 
 And to use primitives of the needed curve in your source code:
 
-use amcl::bls48::{ECP, ECP8}; //any primitive you need
+```
+use amcl::bls48::{ECP, ECP8}; // any primitive you need
+```
 
 Full list of features:
 
@@ -76,7 +84,6 @@ Full list of features:
   * bls461
   * bls24
   * bls48
-  
 * RSA
   * rsa2048
   * rsa3072
diff --git a/src/aes.rs b/src/aes.rs
index 32a0f86..265cdec 100644
--- a/src/aes.rs
+++ b/src/aes.rs
@@ -184,34 +184,33 @@ pub struct AES {
 
 impl AES {
     fn rotl8(x: u32) -> u32 {
-        return ((x) << 8) | ((x) >> 24);
+        ((x) << 8) | ((x) >> 24)
     }
 
     fn rotl16(x: u32) -> u32 {
-        return ((x) << 16) | ((x) >> 16);
+        ((x) << 16) | ((x) >> 16)
     }
 
     fn rotl24(x: u32) -> u32 {
-        return ((x) << 24) | ((x) >> 8);
+        ((x) << 24) | ((x) >> 8)
     }
 
     fn pack(b: [u8; 4]) -> u32 {
         // pack bytes into a 32-bit Word
-        return ((((b[3]) & 0xff) as u32) << 24)
+        ((((b[3]) & 0xff) as u32) << 24)
             | ((((b[2]) & 0xff) as u32) << 16)
             | ((((b[1]) & 0xff) as u32) << 8)
-            | (((b[0]) & 0xff) as u32);
+            | (((b[0]) & 0xff) as u32)
     }
 
     fn unpack(a: u32) -> [u8; 4] {
         // unpack bytes from a word
-        let b: [u8; 4] = [
+        [
             (a & 0xff) as u8,
             ((a >> 8) & 0xff) as u8,
             ((a >> 16) & 0xff) as u8,
             ((a >> 24) & 0xff) as u8,
-        ];
-        return b;
+        ]
     }
 
     fn bmul(x: u8, y: u8) -> u8 {
@@ -234,7 +233,7 @@ impl AES {
         b[1] = FBSUB[b[1] as usize];
         b[2] = FBSUB[b[2] as usize];
         b[3] = FBSUB[b[3] as usize];
-        return AES::pack(b);
+        AES::pack(b)
     }
 
     fn product(x: u32, y: u32) -> u8 {
@@ -242,10 +241,10 @@ impl AES {
         let xb = AES::unpack(x);
         let yb = AES::unpack(y);
 
-        return AES::bmul(xb[0], yb[0])
+        AES::bmul(xb[0], yb[0])
             ^ AES::bmul(xb[1], yb[1])
             ^ AES::bmul(xb[2], yb[2])
-            ^ AES::bmul(xb[3], yb[3]);
+            ^ AES::bmul(xb[3], yb[3])
     }
 
     fn invmixcol(x: u32) -> u32 {
@@ -260,7 +259,7 @@ impl AES {
         m = AES::rotl24(m);
         b[0] = AES::product(m, x);
         let y = AES::pack(b);
-        return y;
+        y
     }
 
     fn increment(f: &mut [u8; 16]) {
@@ -283,7 +282,7 @@ impl AES {
         }
     }
 
-    // reset cipher
+    /// Reset cipher.
     pub fn reset(&mut self, m: usize, iv: Option<[u8; 16]>) {
         // reset mode, or reset iv
         self.mode = m;
@@ -331,31 +330,31 @@ impl AES {
         while j < n {
             self.fkey[j] =
                 self.fkey[j - nk] ^ AES::subbyte(AES::rotl24(self.fkey[j - 1])) ^ (RCO[k] as u32);
-            if nk<=6 {
-		for i in 1..nk {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}
-	    } else {
-		for i in 1..4  {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}
-
-		if (j + 4) < n {
-			self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
-		}
-		for i in 5..nk {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}
-	    }
+            if nk <= 6 {
+                for i in 1..nk {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+            } else {
+                for i in 1..4 {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+
+                if (j + 4) < n {
+                    self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
+                }
+                for i in 5..nk {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+            }
             j += nk;
             k += 1;
         }
@@ -376,7 +375,7 @@ impl AES {
         for j in n - 4..n {
             self.rkey[j + 4 - n] = self.fkey[j]
         }
-        return true;
+        true
     }
 
     pub fn getreg(&mut self) -> [u8; 16] {
@@ -384,7 +383,7 @@ impl AES {
         for i in 0..16 {
             ir[i] = self.f[i]
         }
-        return ir;
+        ir
     }
 
     // Encrypt a single block
diff --git a/src/big.rs b/src/big.rs
index 99342f4..a5424b2 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -25,8 +25,8 @@ use super::super::arch::DChunk;
 use super::dbig::DBig;
 use rand::RAND;
 
-pub use super::rom::MODBYTES;
 pub use super::rom::BASEBITS;
+pub use super::rom::MODBYTES;
 use std::cmp::Ordering;
 use std::fmt;
 
@@ -44,30 +44,26 @@ pub struct Big {
 }
 
 impl Clone for Big {
-    fn clone(&self) -> Big { *self }
+    fn clone(&self) -> Big {
+        *self
+    }
 }
 
 impl fmt::Display for Big {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let mut big = self.clone();
-        write!(f, "Big: [ {} ]", big.tostring())
+        write!(f, "Big: [ {} ]", self.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())
+        write!(f, "Big: [ {} ]", self.tostring())
     }
 }
 
 impl PartialEq for Big {
     fn eq(&self, other: &Big) -> bool {
-        if Big::comp(self,other)==0 {
-            return true;
-        } else {
-            return false;
-        }
+        Big::comp(self, other) == 0
     }
 }
 
@@ -80,11 +76,11 @@ impl Ord for Big {
         if r < 0 {
             return Ordering::Less;
         }
-        return Ordering::Equal;
+        Ordering::Equal
     }
 }
 
-impl Eq for Big { }
+impl Eq for Big {}
 
 impl PartialOrd for Big {
     fn partial_cmp(&self, other: &Big) -> Option<Ordering> {
@@ -97,34 +93,29 @@ impl Big {
         Big { w: [0; NLEN] }
     }
 
+    /// Convert a integer to a Big
     pub fn new_int(x: isize) -> Big {
         let mut s = Big::new();
         s.w[0] = x as Chunk;
-        return s;
+        s
     }
 
+    /// Takes an array of integers and converts to a Big
     pub fn new_ints(a: &[Chunk]) -> Big {
         let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = a[i]
         }
-        return s;
+        s
     }
 
+    /// Creates a copy of the Big
     pub fn new_copy(y: &Big) -> Big {
         let mut s = Big::new();
         for i in 0..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..NLEN {
-            s.w[i] = y.w[i]
-        }
-        return s;
+        s
     }
 
     pub fn new_dcopy(y: &DBig) -> Big {
@@ -132,11 +123,11 @@ impl Big {
         for i in 0..NLEN {
             s.w[i] = y.w[i]
         }
-        return s;
+        s
     }
 
     pub fn get(&self, i: usize) -> Chunk {
-        return self.w[i];
+        self.w[i]
     }
 
     pub fn set(&mut self, i: usize, x: Chunk) {
@@ -151,24 +142,24 @@ impl Big {
         self.w[NLEN - 1] |= x;
     }
 
-    // test for zero
+    /// test for zero
     pub fn iszilch(&self) -> bool {
         for i in 0..NLEN {
             if self.w[i] != 0 {
                 return false;
             }
         }
-        return true;
+        true
     }
 
-    // set to zero
+    /// set to zero
     pub fn zero(&mut self) {
         for i in 0..NLEN {
             self.w[i] = 0
         }
     }
 
-    // Test for equal to one
+    /// Test for equal to one
     pub fn isunity(&self) -> bool {
         for i in 1..NLEN {
             if self.w[i] != 0 {
@@ -178,7 +169,7 @@ impl Big {
         if self.w[0] != 1 {
             return false;
         }
-        return true;
+        true
     }
 
     /// Set to one
@@ -208,7 +199,7 @@ impl Big {
         let prod: DChunk = (a as DChunk) * (b as DChunk) + (c as DChunk) + (r as DChunk);
         let bot = (prod & (BMASK as DChunk)) as Chunk;
         let top = (prod >> BASEBITS) as Chunk;
-        return (top, bot);
+        (top, bot)
     }
 
     /// normalise Big - force all digits < 2^BASEBITS
@@ -220,7 +211,7 @@ impl Big {
             carry = d >> BASEBITS;
         }
         self.w[NLEN - 1] += carry;
-        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as Chunk;
+        (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as Chunk
     }
 
     /// Conditional swap of two bigs depending on d using XOR - no branches
@@ -273,10 +264,11 @@ impl Big {
             self.w[i] = ((self.w[i] << k) & BMASK) | (self.w[i - 1] >> (BASEBITS - n));
         }
         self.w[0] = (self.w[0] << n) & BMASK;
-        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as isize; // return excess - only used in ff.c
+        // return excess - only used in ff.c
+        (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as isize
     }
 
-    /// general shift left
+    /// General shift left
     pub fn shl(&mut self, k: usize) {
         let n = k % BASEBITS;
         let m = k / BASEBITS;
@@ -294,7 +286,7 @@ impl Big {
         }
     }
 
-    // return number of bits
+    /// Return number of bits
     pub fn nbits(&self) -> usize {
         let mut k = NLEN - 1;
         let mut s = Big::new_copy(&self);
@@ -311,11 +303,11 @@ impl Big {
             c /= 2;
             bts += 1;
         }
-        return bts;
+        bts
     }
 
     // Convert to Hex String
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         let mut s = String::new();
         let mut len = self.nbits();
 
@@ -335,9 +327,10 @@ impl Big {
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
-        return s;
+        s
     }
 
+    /// From Hex String
     pub fn fromstring(val: String) -> Big {
         let mut res = Big::new();
         let len = val.len();
@@ -346,63 +339,59 @@ impl Big {
         res.w[0] += n as Chunk;
         for i in 1..len {
             res.shl(4);
-            let op = &val[i..i+1];
+            let op = &val[i..=i];
             let n = u8::from_str_radix(op, 16).unwrap();
             res.w[0] += n as Chunk;
         }
-        return res;
-    }
-
-    pub fn from_hex(val: String) -> Big {
-        Big::fromstring(val)
-    }
-
-    pub fn to_hex(&mut self) -> String {
-        self.tostring()
+        res
     }
 
+    // Self += r
     pub fn add(&mut self, r: &Big) {
         for i in 0..NLEN {
             self.w[i] += r.w[i]
         }
     }
 
+    //? Bitwise OR
     pub fn or(&mut self, r: &Big) {
         for i in 0..NLEN {
             self.w[i] |= r.w[i]
         }
     }
 
+    /// Self * 2
     pub fn dbl(&mut self) {
         for i in 0..NLEN {
             self.w[i] += self.w[i]
         }
     }
 
-    // return this+x
+    /// Return self + x
     pub fn plus(&self, x: &Big) -> Big {
         let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = self.w[i] + x.w[i];
         }
-        return s;
+        s
     }
 
+    /// Return self + 1
     pub fn inc(&mut self, x: isize) {
         self.norm();
         self.w[0] += x as Chunk;
     }
 
-    // return self-x
+    ///  Return self - x
     pub fn minus(&self, x: &Big) -> Big {
         let mut d = Big::new();
         for i in 0..NLEN {
             d.w[i] = self.w[i] - x.w[i];
         }
-        return d;
+        d
     }
 
-    // self-=x
+    // self -= x
     pub fn sub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] -= x.w[i];
@@ -410,7 +399,6 @@ impl Big {
     }
 
     // reverse subtract this=x-this
-
     pub fn rsub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] = x.w[i] - self.w[i]
@@ -448,7 +436,7 @@ impl Big {
             m.fshl(8);
             m.w[0] += (b[i + n] & 0xff) as Chunk;
         }
-        return m;
+        m
     }
 
     pub fn tobytes(&mut self, b: &mut [u8]) {
@@ -456,7 +444,7 @@ impl Big {
     }
 
     pub fn frombytes(b: &[u8]) -> Big {
-        return Big::frombytearray(b, 0);
+        Big::frombytearray(b, 0)
     }
 
     // self*=x, where x is >NEXCESS
@@ -468,7 +456,7 @@ impl Big {
             carry = tuple.0;
             self.w[i] = tuple.1;
         }
-        return carry;
+        carry
     }
 
     // self*=c and catch overflow in DBig
@@ -481,7 +469,7 @@ impl Big {
             m.w[j] = tuple.1;
         }
         m.w[NLEN] = carry;
-        return m;
+        m
     }
 
     // divide by 3
@@ -494,7 +482,7 @@ impl Big {
             self.w[i] = ak / 3;
             carry = ak % 3;
         }
-        return carry;
+        carry
     }
 
     // return a*b where result fits in a Big
@@ -510,7 +498,7 @@ impl Big {
                 }
             }
         }
-        return c;
+        c
     }
 
     // Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised
@@ -525,7 +513,7 @@ impl Big {
                 return -1;
             }
         }
-        return 0;
+        0
     }
 
     // set x = x mod 2^m
@@ -575,31 +563,30 @@ impl Big {
         t1 <<= 4;
         u += t1;
 
-        return u;
+        u
     }
 
-    // return parity
+    /// Return parity
     pub fn parity(&self) -> isize {
-        return (self.w[0] % 2) as isize;
+        (self.w[0] % 2) as isize
     }
 
-    // return n-th bit
+    // Return n-th bit
     pub fn bit(&self, n: usize) -> isize {
         if (self.w[n / (BASEBITS as usize)] & (1 << (n % BASEBITS))) > 0 {
             return 1;
-        } else {
-            return 0;
         }
+        0
     }
 
-    // return n last bits
+    /// 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;
+        (self.w[0] & msk) as isize
     }
 
-    // a=1/a mod 2^256. This is very fast!
+    /// 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();
@@ -639,7 +626,7 @@ impl Big {
         self.norm();
     }
 
-    // reduce self mod m
+    /// reduce self mod m
     pub fn rmod(&mut self, n: &Big) {
         let mut k = 0;
         let mut m = Big::new_copy(n);
@@ -670,7 +657,7 @@ impl Big {
         }
     }
 
-    // divide self by m
+    /// Divide self by m
     pub fn div(&mut self, n: &Big) {
         let mut k = 0;
         self.norm();
@@ -703,7 +690,7 @@ impl Big {
         }
     }
 
-    // get 8*MODBYTES size random number
+    /// Get 8*MODBYTES size random number
     pub fn random(rng: &mut RAND) -> Big {
         let mut m = Big::new();
         let mut j = 0;
@@ -723,10 +710,10 @@ impl Big {
             j += 1;
             j &= 7;
         }
-        return m;
+        m
     }
 
-    // Create random Big in portable way, one bit at a time
+    /// 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;
@@ -746,10 +733,10 @@ impl Big {
             j &= 7;
         }
         let m = d.dmod(q);
-        return m;
+        m
     }
 
-    // Jacobi Symbol (this/p). Returns 0, 1 or -1
+    /// 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();
@@ -788,12 +775,11 @@ impl Big {
         }
         if m == 0 {
             return 1;
-        } else {
-            return -1;
         }
+        -1
     }
 
-    // self=1/self mod p. Binary method
+    /// self = 1/self mod p. Binary method
     pub fn invmodp(&mut self, p: &Big) {
         self.rmod(p);
         let mut u = Big::new_copy(self);
@@ -851,8 +837,7 @@ impl Big {
         }
     }
 
-    // return a*b as DBig
-
+    /// return a*b as DBig
     pub fn mul(a: &Big, b: &Big) -> DBig {
         let mut c = DBig::new();
         let rm = BMASK as DChunk;
@@ -869,7 +854,7 @@ impl Big {
         for k in 1..NLEN {
             s += d[k];
             t = co + s;
-            for i in 1 + k / 2..k + 1 {
+            for i in 1 + k / 2..=k {
                 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;
@@ -888,10 +873,10 @@ impl Big {
             co = t >> rb;
         }
         c.w[2 * NLEN - 1] = co as Chunk;
-        return c;
+        c
     }
 
-    // return a^2 as DBig
+    /// return a^2 as DBig
     pub fn sqr(a: &Big) -> DBig {
         let mut c = DBig::new();
         let rm = BMASK as DChunk;
@@ -958,9 +943,10 @@ impl Big {
         co = t >> rb;
         c.w[DNLEN - 1] = co as Chunk;
 
-        return c;
+        c
     }
 
+    /// Montegomery Reduction
     pub fn monty(md: &Big, mc: Chunk, d: &mut DBig) -> Big {
         let mut b = Big::new();
         let rm = BMASK as DChunk;
@@ -1002,7 +988,7 @@ impl Big {
             s -= dd[k + 1 - NLEN];
         }
         b.w[NLEN - 1] = (c & rm) as Chunk;
-        return b;
+        b
     }
 
     pub fn ssn(r: &mut Big, a: &Big, m: &mut Big) -> isize {
@@ -1019,35 +1005,35 @@ impl Big {
         }
         m.w[n] >>= 1;
         r.w[n] = a.w[n] - m.w[n] + carry;
-        return ((r.w[n] >> (arch::CHUNK - 1)) & 1) as isize;
+        ((r.w[n] >> (arch::CHUNK - 1)) & 1) as isize
     }
 
-    // return a*b mod m
+    /// return a*b mod m
     pub fn modmul(a1: &Big, b1: &Big, m: &Big) -> Big {
         let mut a = Big::new_copy(a1);
         let mut b = Big::new_copy(b1);
         a.rmod(m);
         b.rmod(m);
         let mut d = Big::mul(&a, &b);
-        return d.dmod(m);
+        d.dmod(m)
     }
 
-    // return a^2 mod m
+    /// return a^2 mod m
     pub fn modsqr(a1: &Big, m: &Big) -> Big {
         let mut a = Big::new_copy(a1);
         a.rmod(m);
         let mut d = Big::sqr(&a);
-        return d.dmod(m);
+        d.dmod(m)
     }
 
-    // return -a mod m
+    /// return -a mod m
     pub fn modneg(a1: &Big, m: &Big) -> Big {
         let mut a = Big::new_copy(a1);
         a.rmod(m);
-        return m.minus(&a);
+        m.minus(&a)
     }
 
-    // return this^e mod m
+    /// return this^e mod m
     pub fn powmod(&mut self, e1: &Big, m: &Big) -> Big {
         self.norm();
         let mut e = Big::new_copy(e1);
@@ -1064,8 +1050,8 @@ impl Big {
             if z.iszilch() {
                 break;
             }
-            s = Big::modsqr(&mut s, m);
+            s = Big::modsqr(&s, m);
         }
-        return a;
+        a
     }
 }
diff --git a/src/bls.rs b/src/bls.rs
index 2ef80a4..07b8353 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use std::str;
 use super::ecp::ECP;
 use super::ecp2::ECP2;
+use std::str;
 //use super::fp12::FP12;
+use super::big;
 use super::big::Big;
 use super::pair;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -47,28 +47,28 @@ fn bls_hashit(m: &str) -> ECP {
     }
     sh.shake(&mut hm, BFS);
     let P = ECP::mapit(&hm);
-    return P;
+    P
 }
 
-// generate key pair, private key s, public key w
+/// Generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
     let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP2::generator();
     let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
-    pair::g2mul(&g, &mut sc).tobytes(w);
-    return BLS_OK;
+    pair::g2mul(&g, &sc).tobytes(w);
+    BLS_OK
 }
 
-// Sign message m using private key s to produce signature sig
+/// Sign message m using private key s to produce signature sig.
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
     let mut sc = Big::frombytes(&s);
     pair::g1mul(&d, &mut sc).tobytes(sig, true);
-    return BLS_OK;
+    BLS_OK
 }
 
-// Verify signature given message m, the signature sig, and the public key w
+/// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -77,10 +77,10 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     d.neg();
 
     // Use new multi-pairing mechanism
-    let mut r=pair::initmp();
-    pair::another(&mut r,&g,&d);
-    pair::another(&mut r,&pk,&hm);
-    let mut v=pair::miller(&r);
+    let mut r = pair::initmp();
+    pair::another(&mut r, &g, &d);
+    pair::another(&mut r, &pk, &hm);
+    let mut v = pair::miller(&r);
 
     //.. or alternatively
     //    let mut v = pair::ate2(&g, &d, &pk, &hm);
@@ -89,5 +89,5 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     if v.isunity() {
         return BLS_OK;
     }
-    return BLS_FAIL;
+    BLS_FAIL
 }
diff --git a/src/bls192.rs b/src/bls192.rs
index b2c7e97..3654452 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use std::str;
 use super::ecp::ECP;
 use super::ecp4::ECP4;
+use std::str;
 //use super::fp24::FP24;
+use super::big;
 use super::big::Big;
 use super::pair192;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -49,28 +49,28 @@ fn bls_hashit(m: &str) -> ECP {
     }
     sh.shake(&mut hm, BFS);
     let P = ECP::mapit(&hm);
-    return P;
+    P
 }
 
-// generate key pair, private key s, public key w
+/// Generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
     let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP4::generator();
     let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair192::g2mul(&g, &mut sc).tobytes(w);
-    return BLS_OK;
+    BLS_OK
 }
 
-// Sign message m using private key s to produce signature sig
+/// Sign message m using private key s to produce signature sig
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
     let mut sc = Big::frombytes(&s);
     pair192::g1mul(&d, &mut sc).tobytes(sig, true);
-    return BLS_OK;
+    BLS_OK
 }
 
-// Verify signature given message m, the signature sig, and the public key w
+/// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -79,10 +79,10 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     d.neg();
 
     // Use new multi-pairing mechanism
-    let mut r=pair192::initmp();
-    pair192::another(&mut r,&g,&d);
-    pair192::another(&mut r,&pk,&hm);
-    let mut v=pair192::miller(&r);
+    let mut r = pair192::initmp();
+    pair192::another(&mut r, &g, &d);
+    pair192::another(&mut r, &pk, &hm);
+    let mut v = pair192::miller(&r);
 
     //.. or alternatively
     //    let mut v = pair192::ate2(&g, &d, &pk, &hm);
@@ -91,5 +91,5 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     if v.isunity() {
         return BLS_OK;
     }
-    return BLS_FAIL;
+    BLS_FAIL
 }
diff --git a/src/bls256.rs b/src/bls256.rs
index a0ac094..c3722f3 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use std::str;
 use super::ecp::ECP;
 use super::ecp8::ECP8;
+use std::str;
 //use super::fp48::FP48;
+use super::big;
 use super::big::Big;
 use super::pair256;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -47,17 +47,17 @@ fn bls_hashit(m: &str) -> ECP {
     }
     sh.shake(&mut hm, BFS);
     let P = ECP::mapit(&hm);
-    return P;
+    P
 }
 
-// generate key pair, private key s, public key w
+/// Generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
     let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP8::generator();
     let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair256::g2mul(&g, &mut sc).tobytes(w);
-    return BLS_OK;
+    BLS_OK
 }
 
 // Sign message m using private key s to produce signature sig
@@ -65,10 +65,10 @@ pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
     let mut sc = Big::frombytes(&s);
     pair256::g1mul(&d, &mut sc).tobytes(sig, true);
-    return BLS_OK;
+    BLS_OK
 }
 
-// Verify signature given message m, the signature sig, and the public key w
+/// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -77,10 +77,10 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     d.neg();
 
     // Use new multi-pairing mechanism
-    let mut r=pair256::initmp();
-    pair256::another(&mut r,&g,&d);
-    pair256::another(&mut r,&pk,&hm);
-    let mut v=pair256::miller(&r);
+    let mut r = pair256::initmp();
+    pair256::another(&mut r, &g, &d);
+    pair256::another(&mut r, &pk, &hm);
+    let mut v = pair256::miller(&r);
 
     //.. or alternatively
     //    let mut v = pair256::ate2(&g, &d, &pk, &hm);
@@ -89,5 +89,5 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     if v.isunity() {
         return BLS_OK;
     }
-    return BLS_FAIL;
+    BLS_FAIL
 }
diff --git a/src/dbig.rs b/src/dbig.rs
index 31cf402..2479637 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -18,9 +18,9 @@ under the License.
 */
 
 use super::super::arch;
+use super::super::arch::Chunk;
 use super::big;
 use super::big::Big;
-use super::super::arch::Chunk;
 
 #[derive(Copy)]
 pub struct DBig {
@@ -28,7 +28,9 @@ pub struct DBig {
 }
 
 impl Clone for DBig {
-    fn clone(&self) -> DBig { *self }
+    fn clone(&self) -> DBig {
+        *self
+    }
 }
 
 impl DBig {
@@ -43,7 +45,7 @@ impl DBig {
         for i in 0..big::DNLEN {
             s.w[i] = y.w[i]
         }
-        return s;
+        s
     }
 
     pub fn new_scopy(x: &Big) -> DBig {
@@ -51,16 +53,16 @@ impl DBig {
         for i in 0..big::NLEN {
             b.w[i] = x.w[i];
         }
-        b.w[big::NLEN - 1] = x.get(big::NLEN - 1) & big::BMASK; /* top word normalized */
+        b.w[big::NLEN - 1] = x.get(big::NLEN - 1) & big::BMASK; // top word normalized
         b.w[big::NLEN] = x.get(big::NLEN - 1) >> big::BASEBITS;
 
         for i in big::NLEN + 1..big::DNLEN {
             b.w[i] = 0
         }
-        return b;
+        b
     }
 
-    /* split DBig at position n, return higher half, keep lower half */
+    /// 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 % big::BASEBITS;
@@ -72,10 +74,10 @@ impl DBig {
             t.set(i + 1 - big::NLEN, nw);
         }
         self.w[big::NLEN - 1] &= ((1 as Chunk) << m) - 1;
-        return t;
+        t
     }
 
-    /* general shift left */
+    /// General shift left
     pub fn shl(&mut self, k: usize) {
         let n = k % big::BASEBITS;
         let m = k / big::BASEBITS;
@@ -92,7 +94,7 @@ impl DBig {
         }
     }
 
-    /* general shift right */
+    /// General shift right
     pub fn shr(&mut self, k: usize) {
         let n = k % big::BASEBITS;
         let m = k / big::BASEBITS;
@@ -106,13 +108,14 @@ impl DBig {
         }
     }
 
-    /* Copy from another DBig */
+    /// Copy from another DBig
     pub fn copy(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] = x.w[i];
         }
     }
 
+    /// Copy from a Big
     pub fn ucopy(&mut self, x: &Big) {
         for i in 0..big::NLEN {
             self.w[i] = 0;
@@ -129,28 +132,28 @@ impl DBig {
         }
     }
 
-    /* self+=x */
+    /// self += x
     pub fn add(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] += x.w[i];
         }
     }
 
-    /* self-=x */
+    /// self -= x
     pub fn sub(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] -= x.w[i];
         }
     }
 
-    /* self=x-self */
+    /// self = x - self
     pub fn rsub(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] = x.w[i] - self.w[i];
         }
     }
 
-    /* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+    /// 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..big::DNLEN).rev() {
             if a.w[i] == b.w[i] {
@@ -162,10 +165,10 @@ impl DBig {
                 return -1;
             }
         }
-        return 0;
+        0
     }
 
-    /* normalise Big - force all digits < 2^big::BASEBITS */
+    /// Normalise Big - force all digits < 2^big::BASEBITS
     pub fn norm(&mut self) {
         let mut carry = 0 as Chunk;
         for i in 0..big::DNLEN - 1 {
@@ -176,7 +179,7 @@ impl DBig {
         self.w[big::DNLEN - 1] += carry
     }
 
-    /* reduces self DBig mod a Big, and returns the Big */
+    /// Reduces self DBig mod a Big, and returns the Big
     pub fn dmod(&mut self, c: &Big) -> Big {
         let mut k = 0;
         self.norm();
@@ -210,10 +213,10 @@ impl DBig {
             k -= 1;
         }
         let r = Big::new_dcopy(self);
-        return r;
+        r
     }
 
-    /* return this/c */
+    /// return self / c
     pub fn div(&mut self, c: &Big) -> Big {
         let mut k = 0;
         let mut m = DBig::new_scopy(c);
@@ -245,10 +248,10 @@ impl DBig {
 
             k -= 1;
         }
-        return a;
+        a
     }
 
-    /* set x = x mod 2^m */
+    /// set x = x mod 2^m
     pub fn mod2m(&mut self, m: usize) {
         let wd = m / big::BASEBITS;
         let bt = m % big::BASEBITS;
@@ -259,8 +262,8 @@ impl DBig {
         }
     }
 
-    /* return number of bits */
-    pub fn nbits(&mut self) -> usize {
+    /// Return number of bits
+    pub fn nbits(&self) -> usize {
         let mut k = big::DNLEN - 1;
         let mut s = DBig::new_copy(&self);
         s.norm();
@@ -276,11 +279,11 @@ impl DBig {
             c /= 2;
             bts += 1;
         }
-        return bts;
+        bts
     }
 
-    /* Convert to Hex String */
-    pub fn to_string(&mut self) -> String {
+    /// Convert to Hex String
+    pub fn to_string(&self) -> String {
         let mut s = String::new();
         let mut len = self.nbits();
 
@@ -296,6 +299,6 @@ impl DBig {
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
-        return s;
+        s
     }
 }
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 1df8446..12aa34e 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big;
+use super::big::Big;
 use super::ecp;
 use super::ecp::ECP;
-use super::big::Big;
 use super::rom;
-use super::big;
 
-use rand::RAND;
+use aes;
+use aes::AES;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-use aes;
-use aes::AES;
-
+use rand::RAND;
 
 pub const INVALID_PUBLIC_KEY: isize = -2;
 pub const ERROR: isize = -3;
@@ -52,6 +51,7 @@ fn inttobytes(n: usize, b: &mut [u8]) {
     }
 }
 
+/// Hash to curve function using Hash and Test on SHA256, 384 or 512
 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 {
@@ -117,11 +117,11 @@ fn hashit(sha: usize, a: &[u8], n: usize, b: Option<&[u8]>, pad: usize, w: &mut
     }
 }
 
-/* Key Derivation Functions */
-/* Input octet Z */
-/* Output key of length olen */
+// Key Derivation Function 1
+// 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 */
+    // NOTE: the parameter olen is the length of the output K in bytes
     let hlen = sha;
     let mut lk = 0;
 
@@ -147,8 +147,11 @@ pub fn kdf1(sha: usize, z: &[u8], olen: usize, k: &mut [u8]) {
     }
 }
 
+// Key Derivation Function 2
+// Input octet Z
+// Output key of length olen
 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 */
+    // NOTE: the parameter olen is the length of the output K in bytes
     let hlen = sha;
     let mut lk = 0;
 
@@ -157,7 +160,7 @@ pub fn kdf2(sha: usize, z: &[u8], p: Option<&[u8]>, olen: usize, k: &mut [u8]) {
         cthreshold += 1
     }
 
-    for counter in 1..cthreshold + 1 {
+    for counter in 1..=cthreshold {
         let mut b: [u8; 64] = [0; 64];
         hashit(sha, z, counter, p, 0, &mut b);
         if lk + hlen > olen {
@@ -174,9 +177,9 @@ pub fn kdf2(sha: usize, z: &[u8], p: Option<&[u8]>, olen: usize, k: &mut [u8]) {
     }
 }
 
-/* Password based Key Derivation Function */
-/* Input password p, salt s, and repeat count */
-/* Output key of length olen */
+/// 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 {
@@ -205,7 +208,7 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
             u[j] = f[j]
         }
         for _ in 1..rep {
-            hmac(sha, &mut u, pass, sha, &mut ku);
+            hmac(sha, &u, pass, sha, &mut ku);
             for k in 0..sha {
                 u[k] = ku[k];
                 f[k] ^= u[k]
@@ -220,7 +223,7 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
     }
 }
 
-/* Calculate HMAC of m using key k. HMAC is tag of length olen (which is length of tag) */
+/// 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  *
@@ -255,17 +258,17 @@ pub fn hmac(sha: usize, m: &[u8], k: &[u8], olen: usize, tag: &mut [u8]) -> bool
     for i in 0..lb {
         k0[i] ^= 0x36
     }
-    hashit(sha, &mut k0[0..lb], 0, Some(m), 0, &mut b);
+    hashit(sha, &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);
+    hashit(sha, &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 */
+/// 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 */
@@ -314,10 +317,10 @@ pub fn cbc_iv0_encrypt(k: &[u8], m: &[u8]) -> Vec<u8> {
         c.push(buff[j]);
     }
     a.end();
-    return c;
+    c
 }
 
-/* returns plaintext if all consistent, else returns null string */
+/// 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();
@@ -382,14 +385,14 @@ pub fn cbc_iv0_decrypt(k: &[u8], c: &[u8]) -> Option<Vec<u8>> {
     if bad {
         return None;
     }
-    return Some(m);
+    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 */
+/// 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;
@@ -407,14 +410,14 @@ pub fn key_pair_generate(rng: Option<&mut RAND>, s: &mut [u8], w: &mut [u8]) ->
 
     sc.tobytes(s);
 
-    let WP = G.mul(&mut sc);
+    let WP = G.mul(&sc);
 
     WP.tobytes(w, false); // To use point compression on public keys, change to true
 
-    return res;
+    res
 }
 
-/* validate public key */
+/// Validate public key
 #[allow(non_snake_case)]
 pub fn public_key_validate(w: &[u8]) -> isize {
     let mut WP = ECP::frombytes(w);
@@ -440,16 +443,16 @@ pub fn public_key_validate(w: &[u8]) -> isize {
         }
 
         if !k.isunity() {
-            WP = WP.mul(&mut k)
+            WP = WP.mul(&k)
         }
         if WP.is_infinity() {
             res = INVALID_PUBLIC_KEY
         }
     }
-    return res;
+    res
 }
 
-/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+/// 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;
@@ -465,7 +468,7 @@ pub fn ecpsvdp_dh(s: &[u8], wd: &[u8], z: &mut [u8]) -> isize {
     if res == 0 {
         let r = Big::new_ints(&rom::CURVE_ORDER);
         sc.rmod(&r);
-        W = W.mul(&mut sc);
+        W = W.mul(&sc);
         if W.is_infinity() {
             res = ERROR;
         } else {
@@ -475,10 +478,10 @@ pub fn ecpsvdp_dh(s: &[u8], wd: &[u8], z: &mut [u8]) -> isize {
             }
         }
     }
-    return res;
+    res
 }
 
-/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+/// IEEE ECDSA Signature, C and D are signature on F using private key S
 #[allow(non_snake_case)]
 pub fn ecpsp_dsa(
     sha: usize,
@@ -497,7 +500,7 @@ pub fn ecpsp_dsa(
 
     let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut sc = Big::frombytes(s); /* s or &s? */
+    let sc = Big::frombytes(s); /* s or &s? */
     let fb = Big::frombytes(&b);
 
     let mut cb = Big::new();
@@ -507,10 +510,10 @@ pub fn ecpsp_dsa(
 
     while db.iszilch() {
         let mut u = Big::randomnum(&r, rng);
-        let mut w = Big::randomnum(&r, rng); /* side channel masking */
+        let w = Big::randomnum(&r, rng); /* side channel masking */
 
         V.copy(&G);
-        V = V.mul(&mut u);
+        V = V.mul(&u);
         let vx = V.getx();
         cb.copy(&vx);
         cb.rmod(&r);
@@ -518,17 +521,17 @@ pub fn ecpsp_dsa(
             continue;
         }
 
-        tb.copy(&Big::modmul(&mut u, &mut w, &r));
+        tb.copy(&Big::modmul(&u, &w, &r));
         u.copy(&tb);
 
         u.invmodp(&r);
-        db.copy(&Big::modmul(&mut sc, &mut cb, &r));
+        db.copy(&Big::modmul(&sc, &cb, &r));
         db.add(&fb);
 
-        tb.copy(&Big::modmul(&mut db, &mut w, &r));
+        tb.copy(&Big::modmul(&db, &w, &r));
         db.copy(&tb);
 
-        tb.copy(&Big::modmul(&mut u, &mut db, &r));
+        tb.copy(&Big::modmul(&u, &db, &r));
         db.copy(&tb);
     }
 
@@ -540,10 +543,10 @@ pub fn ecpsp_dsa(
     for i in 0..EFS {
         d[i] = t[i]
     }
-    return 0;
+    0
 }
 
-/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+/// 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;
@@ -552,11 +555,11 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
 
     hashit(sha, f, 0, None, big::MODBYTES as usize, &mut b);
 
-    let mut G = ECP::generator();
+    let G = ECP::generator();
 
     let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut cb = Big::frombytes(c); /* c or &c ? */
+    let 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();
@@ -567,9 +570,9 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
 
     if res == 0 {
         db.invmodp(&r);
-        tb.copy(&Big::modmul(&mut fb, &mut db, &r));
+        tb.copy(&Big::modmul(&fb, &db, &r));
         fb.copy(&tb);
-        let h2 = Big::modmul(&mut cb, &mut db, &r);
+        let h2 = Big::modmul(&cb, &db, &r);
 
         let WP = ECP::frombytes(&w);
         if WP.is_infinity() {
@@ -578,7 +581,7 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
             let mut P = ECP::new();
             P.copy(&WP);
 
-            P = P.mul2(&h2, &mut G, &fb);
+            P = P.mul2(&h2, &G, &fb);
 
             if P.is_infinity() {
                 res = INVALID;
@@ -593,10 +596,10 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
         }
     }
 
-    return res;
+    res
 }
 
-/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+/// 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,
@@ -622,7 +625,7 @@ pub fn ecies_encrypt(
         return None;
     }
 
-    for i in 0..2 * EFS + 1 {
+    for i in 0..=2 * EFS {
         vz[i] = v[i]
     }
     for i in 0..EFS {
@@ -656,10 +659,10 @@ pub fn ecies_encrypt(
         c.pop();
     }
 
-    return Some(c);
+    Some(c)
 }
 
-/* constant time n-byte compare */
+/// constant time n-byte compare
 fn ncomp(t1: &[u8], t2: &[u8], n: usize) -> bool {
     let mut res = 0;
     for i in 0..n {
@@ -668,10 +671,10 @@ fn ncomp(t1: &[u8], t2: &[u8], n: usize) -> bool {
     if res == 0 {
         return true;
     }
-    return false;
+    false
 }
 
-/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+/// 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,
@@ -740,5 +743,5 @@ pub fn ecies_decrypt(
         return None;
     }
 
-    return m;
+    m
 }
diff --git a/src/ecp.rs b/src/ecp.rs
index 0e27f32..b779e2d 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -17,15 +17,15 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::fp::FP;
-use super::big::Big;
 use super::big;
+use super::big::Big;
+use super::fp::FP;
 use super::rom;
 
-pub use super::rom::{CURVETYPE, CURVE_PAIRING_TYPE, SEXTIC_TWIST, SIGN_OF_X, HASH_TYPE, AESKEY};
-pub use types::CurveType;
-use std::str::SplitWhitespace;
+pub use super::rom::{AESKEY, CURVETYPE, CURVE_PAIRING_TYPE, HASH_TYPE, SEXTIC_TWIST, SIGN_OF_X};
 use std::fmt;
+use std::str::SplitWhitespace;
+pub use types::CurveType;
 
 #[derive(Copy, Clone)]
 pub struct ECP {
@@ -41,15 +41,15 @@ impl PartialEq for ECP {
 }
 
 impl fmt::Display for ECP {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 impl fmt::Debug for ECP {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 #[allow(non_snake_case)]
@@ -64,7 +64,7 @@ impl ECP {
 
     pub fn new() -> ECP {
         let mut E = ECP::pnew();
-        if CURVETYPE == CurveType::EDWARDS {
+        if CURVETYPE == CurveType::Edwards {
             E.z.one();
         }
         return E;
@@ -78,14 +78,14 @@ impl ECP {
         E.z.one();
         E.x.norm();
         let mut rhs = ECP::rhs(&E.x);
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             if rhs.jacobi() != 1 {
                 E.inf();
             }
         } else {
             let mut y2 = FP::new_copy(&E.y);
             y2.sqr();
-            if !y2.equals(&mut rhs) {
+            if !y2.equals(&rhs) {
                 E.inf();
             }
         }
@@ -122,7 +122,7 @@ impl ECP {
         E.z.one();
         let mut rhs = ECP::rhs(&E.x);
         if rhs.jacobi() == 1 {
-            if CURVETYPE != CurveType::MONTGOMERY {
+            if CURVETYPE != CurveType::Montgomery {
                 E.y.copy(&rhs.sqrt())
             }
         } else {
@@ -134,10 +134,10 @@ impl ECP {
     /* set this=O */
     pub fn inf(&mut self) {
         self.x.zero();
-        if CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             self.y.one();
         }
-        if CURVETYPE != CurveType::EDWARDS {
+        if CURVETYPE != CurveType::Edwards {
             self.z.zero();
         } else {
             self.z.one()
@@ -149,7 +149,7 @@ impl ECP {
         let mut r = FP::new_copy(x);
         r.sqr();
 
-        if CURVETYPE == CurveType::WEIERSTRASS {
+        if CURVETYPE == CurveType::Weierstrass {
             // x^3+Ax+B
             let b = FP::new_big(&Big::new_ints(&rom::CURVE_B));
             r.mul(x);
@@ -162,7 +162,7 @@ impl ECP {
             }
             r.add(&b);
         }
-        if CURVETYPE == CurveType::EDWARDS {
+        if CURVETYPE == CurveType::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);
@@ -177,7 +177,7 @@ impl ECP {
             b.inverse();
             r.mul(&b);
         }
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             // x^3+Ax^2+x
             let mut x3 = FP::new();
             x3.copy(&r);
@@ -193,16 +193,16 @@ impl ECP {
     /* test for O point-at-infinity */
     pub fn is_infinity(&self) -> bool {
         match CURVETYPE {
-            CurveType::EDWARDS=> self.x.iszilch() && self.y.equals(&self.z),
-            CurveType::WEIERSTRASS => self.x.iszilch() && self.z.iszilch(),
-            CurveType::MONTGOMERY => self.z.iszilch(),
+            CurveType::Edwards => self.x.iszilch() && self.y.equals(&self.z),
+            CurveType::Weierstrass => self.x.iszilch() && self.z.iszilch(),
+            CurveType::Montgomery => self.z.iszilch(),
         }
     }
 
     /* 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 CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             self.y.cswap(&mut Q.y, d)
         }
         self.z.cswap(&mut Q.z, d);
@@ -211,7 +211,7 @@ impl ECP {
     /* 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 CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             self.y.cmove(&Q.y, d)
         }
         self.z.cmove(&Q.z, d);
@@ -227,7 +227,7 @@ impl ECP {
     /* this=P */
     pub fn copy(&mut self, P: &ECP) {
         self.x.copy(&P.x);
-        if CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             self.y.copy(&P.y)
         }
         self.z.copy(&P.z);
@@ -235,11 +235,11 @@ impl ECP {
 
     /* this=-this */
     pub fn neg(&mut self) {
-        if CURVETYPE == CurveType::WEIERSTRASS {
+        if CURVETYPE == CurveType::Weierstrass {
             self.y.neg();
             self.y.norm();
         }
-        if CURVETYPE == CurveType::EDWARDS {
+        if CURVETYPE == CurveType::Edwards {
             self.x.neg();
             self.x.norm();
         }
@@ -281,15 +281,15 @@ impl ECP {
         a.mul(&Q.z);
         b.copy(&Q.x);
         b.mul(&self.z);
-        if !a.equals(&mut b) {
+        if !a.equals(&b) {
             return false;
         }
-        if CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             a.copy(&self.y);
             a.mul(&Q.z);
             b.copy(&Q.y);
             b.mul(&self.z);
-            if !a.equals(&mut b) {
+            if !a.equals(&b) {
                 return false;
             }
         }
@@ -301,15 +301,15 @@ impl ECP {
         if self.is_infinity() {
             return;
         }
-        let mut one = FP::new_int(1);
-        if self.z.equals(&mut one) {
+        let one = FP::new_int(1);
+        if self.z.equals(&one) {
             return;
         }
         self.z.inverse();
 
         self.x.mul(&self.z);
         self.x.reduce();
-        if CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             self.y.mul(&self.z);
             self.y.reduce();
         }
@@ -368,7 +368,7 @@ impl ECP {
             b[i + 1] = t[i]
         }
 
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             b[0] = 0x06;
             return;
         }
@@ -403,7 +403,7 @@ impl ECP {
             return ECP::new();
         }
 
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             return ECP::new_big(&px);
         }
 
@@ -432,7 +432,7 @@ impl ECP {
         if W.is_infinity() {
             return String::from("infinity");
         }
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             return format!("({})", W.x.redc().tostring());
         } else {
             return format!("({},{})", W.x.redc().tostring(), W.y.redc().tostring());
@@ -440,7 +440,12 @@ impl ECP {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+        format!(
+            "{} {} {}",
+            self.x.to_hex(),
+            self.y.to_hex(),
+            self.z.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP {
@@ -458,7 +463,7 @@ impl ECP {
 
     /* this*=2 */
     pub fn dbl(&mut self) {
-        if CURVETYPE == CurveType::WEIERSTRASS {
+        if CURVETYPE == CurveType::Weierstrass {
             if rom::CURVE_A == 0 {
                 let mut t0 = FP::new_copy(&self.y);
                 t0.sqr();
@@ -590,7 +595,7 @@ impl ECP {
                 self.z.norm();
             }
         }
-        if CURVETYPE == CurveType::EDWARDS {
+        if CURVETYPE == CurveType::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);
@@ -619,7 +624,7 @@ impl ECP {
             self.y.mul(&c);
             self.z.mul(&j);
         }
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             let mut a = FP::new_copy(&self.x);
             let mut b = FP::new_copy(&self.x);
             let mut aa = FP::new();
@@ -654,7 +659,7 @@ impl ECP {
 
     /* self+=Q */
     pub fn add(&mut self, Q: &ECP) {
-        if CURVETYPE == CurveType::WEIERSTRASS {
+        if CURVETYPE == CurveType::Weierstrass {
             if rom::CURVE_A == 0 {
                 let b = 3 * rom::CURVE_B_I;
                 let mut t0 = FP::new_copy(&self.x);
@@ -847,7 +852,7 @@ impl ECP {
                 self.z.norm();
             }
         }
-        if CURVETYPE == CurveType::EDWARDS {
+        if CURVETYPE == CurveType::Edwards {
             let bb = FP::new_big(&Big::new_ints(&rom::CURVE_B));
             let mut a = FP::new_copy(&self.z);
             let mut b = FP::new();
@@ -959,7 +964,7 @@ impl ECP {
 
     /* constant time multiply by small integer of length bts - use ladder */
     pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             return self.mul(&mut Big::new_int(e as isize));
         } else {
             let mut P = ECP::new();
@@ -970,7 +975,7 @@ impl ECP {
             for i in (0..bts).rev() {
                 let b = ((e >> i) & 1) as isize;
                 P.copy(&R1);
-                P.add(&mut R0);
+                P.add(&R0);
                 R0.cswap(&mut R1, b);
                 R1.copy(&P);
                 R0.dbl();
@@ -989,7 +994,7 @@ impl ECP {
             return ECP::new();
         }
         let mut P = ECP::new();
-        if CURVETYPE == CurveType::MONTGOMERY {
+        if CURVETYPE == CurveType::Montgomery {
             /* use Ladder */
             let mut D = ECP::new();
             let mut R0 = ECP::new();
@@ -1040,7 +1045,7 @@ impl ECP {
             for i in 1..8 {
                 C.copy(&W[i - 1]);
                 W[i].copy(&C);
-                W[i].add(&mut Q);
+                W[i].add(&Q);
             }
 
             // make exponent odd - add 2P if even, P if odd
@@ -1074,9 +1079,9 @@ impl ECP {
                 P.dbl();
                 P.dbl();
                 P.dbl();
-                P.add(&mut Q);
+                P.add(&Q);
             }
-            P.sub(&mut C); /* apply correction */
+            P.sub(&C); /* apply correction */
         }
         P.affine();
         return P;
@@ -1119,24 +1124,24 @@ impl ECP {
         S.dbl();
         C.copy(&W[1]);
         W[0].copy(&C);
-        W[0].sub(&mut S); // copy to C is stupid Rust thing..
+        W[0].sub(&S); // copy to C is stupid Rust thing..
         C.copy(&W[2]);
         W[3].copy(&C);
-        W[3].add(&mut S);
+        W[3].add(&S);
         T.copy(&self);
         T.dbl();
         C.copy(&W[1]);
         W[5].copy(&C);
-        W[5].add(&mut T);
+        W[5].add(&T);
         C.copy(&W[2]);
         W[6].copy(&C);
-        W[6].add(&mut T);
+        W[6].add(&T);
         C.copy(&W[5]);
         W[4].copy(&C);
-        W[4].sub(&mut S);
+        W[4].sub(&S);
         C.copy(&W[6]);
         W[7].copy(&C);
-        W[7].add(&mut S);
+        W[7].add(&S);
 
         // if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction
 
@@ -1160,7 +1165,7 @@ impl ECP {
         mt.norm();
         tf.cmove(&mt, s);
         S.cmove(&Q, ns);
-        C.add(&mut S);
+        C.add(&S);
 
         mt.copy(&te);
         mt.add(&tf);
@@ -1186,9 +1191,9 @@ impl ECP {
             T.selector(&W, w[i] as i32);
             S.dbl();
             S.dbl();
-            S.add(&mut T);
+            S.add(&T);
         }
-        S.sub(&mut C); /* apply correction */
+        S.sub(&C); /* apply correction */
         S.affine();
         return S;
     }
@@ -1218,14 +1223,14 @@ impl ECP {
     // Map a given byte slice to a point on the curve. The byte slice should be atleast the size of the modulus
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP {
-        let mut q = Big::new_ints(&rom::MODULUS);
+        let q = Big::new_ints(&rom::MODULUS);
         let mut x = Big::frombytes(h);
-        x.rmod(&mut q);
+        x.rmod(&q);
         let mut P: ECP;
 
         loop {
             loop {
-                if CURVETYPE != CurveType::MONTGOMERY {
+                if CURVETYPE != CurveType::Montgomery {
                     P = ECP::new_bigint(&x, 0);
                 } else {
                     P = ECP::new_big(&x);
@@ -1250,7 +1255,7 @@ impl ECP {
 
         let gx = Big::new_ints(&rom::CURVE_GX);
 
-        if CURVETYPE != CurveType::MONTGOMERY {
+        if CURVETYPE != CurveType::Montgomery {
             let gy = Big::new_ints(&rom::CURVE_GY);
             G = ECP::new_bigs(&gx, &gy);
         } else {
diff --git a/src/ecp2.rs b/src/ecp2.rs
index c705863..b0892e4 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -17,14 +17,14 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::Big;
 use super::ecp;
 use super::fp2::FP2;
-use super::big::Big;
-use types::{SexticTwist, CurvePairingType, SignOfX};
-use std::str::SplitWhitespace;
+use super::rom;
 use std::fmt;
+use std::str::SplitWhitespace;
+use types::{CurvePairingType, SexticTwist, SignOfX};
 
 #[derive(Copy, Clone)]
 pub struct ECP2 {
@@ -34,21 +34,21 @@ pub struct ECP2 {
 }
 
 impl PartialEq for ECP2 {
-	fn eq(&self, other: &ECP2) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &ECP2) -> bool {
+        self.equals(other)
+    }
 }
 
 impl fmt::Display for ECP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 impl fmt::Debug for ECP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 #[allow(non_snake_case)]
@@ -69,10 +69,10 @@ impl ECP2 {
         E.z.one();
         E.x.norm();
 
-        let mut rhs = ECP2::rhs(&E.x);
+        let rhs = ECP2::rhs(&E.x);
         let mut y2 = FP2::new_copy(&E.y);
         y2.sqr();
-        if !y2.equals(&mut rhs) {
+        if !y2.equals(&rhs) {
             E.inf();
         }
         return E;
@@ -163,14 +163,14 @@ impl ECP2 {
 
         a.mul(&Q.z);
         b.mul(&self.z);
-        if !a.equals(&mut b) {
+        if !a.equals(&b) {
             return false;
         }
         a.copy(&self.y);
         a.mul(&Q.z);
         b.copy(&Q.y);
         b.mul(&self.z);
-        if !a.equals(&mut b) {
+        if !a.equals(&b) {
             return false;
         }
 
@@ -182,8 +182,8 @@ impl ECP2 {
         if self.is_infinity() {
             return;
         }
-        let mut one = FP2::new_int(1);
-        if self.z.equals(&mut one) {
+        let one = FP2::new_int(1);
+        if self.z.equals(&one) {
             return;
         }
         self.z.inverse();
@@ -291,14 +291,19 @@ impl ECP2 {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+        format!(
+            "{} {} {}",
+            self.x.to_hex(),
+            self.y.to_hex(),
+            self.z.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP2 {
         ECP2 {
             x: FP2::from_hex_iter(iter),
             y: FP2::from_hex_iter(iter),
-            z: FP2::from_hex_iter(iter)
+            z: FP2::from_hex_iter(iter),
         }
     }
 
@@ -312,10 +317,10 @@ impl ECP2 {
         let mut r = FP2::new_copy(x);
         r.sqr();
         let mut b = FP2::new_big(&Big::new_ints(&rom::CURVE_B));
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_ip();
         }
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             b.norm();
             b.mul_ip();
             b.norm();
@@ -331,14 +336,14 @@ impl ECP2 {
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
         let mut iy = FP2::new_copy(&self.y);
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.mul_ip();
             iy.norm();
         }
 
         let mut t0 = FP2::new_copy(&self.y); //***** Change
         t0.sqr();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.mul_ip();
         }
         let mut t1 = FP2::new_copy(&iy);
@@ -354,7 +359,7 @@ impl ECP2 {
         self.z.norm();
 
         t2.imul(3 * rom::CURVE_B_I);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.mul_ip();
             t2.norm();
         }
@@ -410,7 +415,7 @@ impl ECP2 {
 
         t3.sub(&t4);
         t3.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t3.mul_ip();
             t3.norm(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
@@ -427,7 +432,7 @@ impl ECP2 {
 
         t4.sub(&x3);
         t4.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t4.mul_ip();
             t4.norm(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
@@ -443,7 +448,7 @@ impl ECP2 {
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
 
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.mul_ip();
             t0.norm(); // x.Q.x
             t1.mul_ip();
@@ -454,7 +459,7 @@ impl ECP2 {
         t0.add(&x3);
         t0.norm();
         t2.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.mul_ip();
             t2.norm();
         }
@@ -464,7 +469,7 @@ impl ECP2 {
         t1.sub(&t2);
         t1.norm();
         y3.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             y3.mul_ip();
             y3.norm();
         }
@@ -548,7 +553,7 @@ impl ECP2 {
         for i in 1..8 {
             C.copy(&W[i - 1]);
             W[i].copy(&C);
-            W[i].add(&mut Q);
+            W[i].add(&Q);
         }
 
         /* make exponent odd - add 2P if even, P if odd */
@@ -582,9 +587,9 @@ impl ECP2 {
             P.dbl();
             P.dbl();
             P.dbl();
-            P.add(&mut Q);
+            P.add(&Q);
         }
-        P.sub(&mut C);
+        P.sub(&C);
         P.affine();
         return P;
     }
@@ -629,24 +634,24 @@ impl ECP2 {
         T[0].copy(&Q[0]);
         W.copy(&T[0]);
         T[1].copy(&W);
-        T[1].add(&mut Q[1]); // Q[0]+Q[1]
+        T[1].add(&Q[1]); // Q[0]+Q[1]
         T[2].copy(&W);
-        T[2].add(&mut Q[2]);
+        T[2].add(&Q[2]);
         W.copy(&T[1]); // Q[0]+Q[2]
         T[3].copy(&W);
-        T[3].add(&mut Q[2]);
+        T[3].add(&Q[2]);
         W.copy(&T[0]); // Q[0]+Q[1]+Q[2]
         T[4].copy(&W);
-        T[4].add(&mut Q[3]);
+        T[4].add(&Q[3]);
         W.copy(&T[1]); // Q[0]+Q[3]
         T[5].copy(&W);
-        T[5].add(&mut Q[3]);
+        T[5].add(&Q[3]);
         W.copy(&T[2]); // Q[0]+Q[1]+Q[3]
         T[6].copy(&W);
-        T[6].add(&mut Q[3]);
+        T[6].add(&Q[3]);
         W.copy(&T[3]); // Q[0]+Q[2]+Q[3]
         T[7].copy(&W);
-        T[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
+        T[7].add(&Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
 
         // Make it odd
         let pb = 1 - t[0].parity();
@@ -688,12 +693,12 @@ impl ECP2 {
         for i in (0..nb - 1).rev() {
             P.dbl();
             W.selector(&T, (2 * w[i] + s[i]) as i32);
-            P.add(&mut W);
+            P.add(&W);
         }
 
         // apply correction
         W.copy(&P);
-        W.sub(&mut Q[0]);
+        W.sub(&Q[0]);
         P.cmove(&W, pb);
         P.affine();
 
@@ -702,9 +707,9 @@ impl ECP2 {
 
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP2 {
-        let mut q = Big::new_ints(&rom::MODULUS);
+        let q = Big::new_ints(&rom::MODULUS);
         let mut x = Big::frombytes(h);
-        x.rmod(&mut q);
+        x.rmod(&q);
         let mut Q: ECP2;
         let one = Big::new_int(1);
 
@@ -718,15 +723,15 @@ impl ECP2 {
             x.norm();
         }
         let mut X = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             X.inverse();
             X.norm();
         }
         x = Big::new_ints(&rom::CURVE_BNX);
 
-        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-            let mut T = Q.mul(&mut x);
-            if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+            let mut T = Q.mul(&x);
+            if ecp::SIGN_OF_X == SignOfX::NegativeX {
                 T.neg();
             }
             let mut K = ECP2::new();
@@ -744,11 +749,11 @@ impl ECP2 {
             T.frob(&X);
             Q.add(&T);
         }
-        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
-            let mut xQ = Q.mul(&mut x);
-            let mut x2Q = xQ.mul(&mut x);
+        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
+            let mut xQ = Q.mul(&x);
+            let mut x2Q = xQ.mul(&x);
 
-            if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+            if ecp::SIGN_OF_X == SignOfX::NegativeX {
                 xQ.neg();
             }
             x2Q.sub(&xQ);
diff --git a/src/ecp4.rs b/src/ecp4.rs
index b29b05d..e0dc5dc 100644
--- a/src/ecp4.rs
+++ b/src/ecp4.rs
@@ -17,12 +17,12 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::Big;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::Big;
+use super::rom;
 use types::{SexticTwist, SignOfX};
 //use std::str::SplitWhitespace;
 
@@ -328,10 +328,10 @@ impl ECP4 {
         let mut r = FP4::new_copy(x);
         r.sqr();
         let mut b = FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B)));
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_i();
         }
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             b.times_i();
         }
 
@@ -345,13 +345,13 @@ impl ECP4 {
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
         let mut iy = FP4::new_copy(&self.y);
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.times_i(); //iy.norm();
         }
 
         let mut t0 = FP4::new_copy(&self.y);
         t0.sqr();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i();
         }
         let mut t1 = FP4::new_copy(&iy);
@@ -367,7 +367,7 @@ impl ECP4 {
         self.z.norm();
 
         t2.imul(3 * rom::CURVE_B_I);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
         let mut x3 = FP4::new_copy(&t2);
@@ -422,7 +422,7 @@ impl ECP4 {
 
         t3.sub(&t4);
         t3.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
         t4.copy(&self.y);
@@ -438,7 +438,7 @@ impl ECP4 {
 
         t4.sub(&x3);
         t4.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
         x3.copy(&self.x);
@@ -453,7 +453,7 @@ impl ECP4 {
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
 
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i(); // x.Q.x
             t1.times_i(); // y.Q.y
         }
@@ -462,7 +462,7 @@ impl ECP4 {
         t0.add(&x3);
         t0.norm();
         t2.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
         let mut z3 = FP4::new_copy(&t1);
@@ -471,7 +471,7 @@ impl ECP4 {
         t1.sub(&t2);
         t1.norm();
         y3.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             y3.times_i();
         }
         x3.copy(&y3);
@@ -517,7 +517,7 @@ impl ECP4 {
         f1.sqr();
         f2.mul(&f1);
         f1.copy(&f);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f1.mul_ip();
             f1.inverse();
             f0.copy(&f1);
@@ -835,7 +835,7 @@ impl ECP4 {
         let mut x3Q = x2Q.mul(&mut x);
         let mut x4Q = x3Q.mul(&mut x);
 
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             xQ.neg();
             x3Q.neg();
         }
diff --git a/src/ecp8.rs b/src/ecp8.rs
index 18c8a30..3998c2c 100644
--- a/src/ecp8.rs
+++ b/src/ecp8.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::Big;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::Big;
+use super::rom;
 use types::{SexticTwist, SignOfX};
 
 pub struct ECP8 {
@@ -414,10 +414,10 @@ impl ECP8 {
         let mut r = FP8::new_copy(x);
         r.sqr();
         let mut b = FP8::new_fp4(&FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B))));
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             b.div_i();
         }
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             b.times_i();
         }
 
@@ -431,13 +431,13 @@ impl ECP8 {
     /* self+=self */
     pub fn dbl(&mut self) -> isize {
         let mut iy = FP8::new_copy(&self.y);
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             iy.times_i(); //iy.norm();
         }
 
         let mut t0 = FP8::new_copy(&self.y);
         t0.sqr();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i();
         }
         let mut t1 = FP8::new_copy(&iy);
@@ -453,7 +453,7 @@ impl ECP8 {
         self.z.norm();
 
         t2.imul(3 * rom::CURVE_B_I);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
         let mut x3 = FP8::new_copy(&t2);
@@ -508,7 +508,7 @@ impl ECP8 {
 
         t3.sub(&t4);
         t3.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
         }
         t4.copy(&self.y);
@@ -524,7 +524,7 @@ impl ECP8 {
 
         t4.sub(&x3);
         t4.norm();
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
         }
         x3.copy(&self.x);
@@ -539,7 +539,7 @@ impl ECP8 {
         y3.rsub(&x3);
         y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
 
-        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
             t0.times_i(); // x.Q.x
             t1.times_i(); // y.Q.y
         }
@@ -548,7 +548,7 @@ impl ECP8 {
         t0.add(&x3);
         t0.norm();
         t2.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             t2.times_i();
         }
         let mut z3 = FP8::new_copy(&t1);
@@ -557,7 +557,7 @@ impl ECP8 {
         t1.sub(&t2);
         t1.norm();
         y3.imul(b);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             y3.times_i();
         }
         x3.copy(&y3);
@@ -607,7 +607,7 @@ impl ECP8 {
         f2.norm();
 
         f1.copy(&f);
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f1.mul_ip();
             f1.inverse();
             f0.copy(&f1);
@@ -626,18 +626,18 @@ impl ECP8 {
         for _i in 0..n {
             self.x.frob(&f[2]);
             self.x.qmul(&f[0]);
-            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 self.x.div_i2();
             }
-            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 self.x.times_i2();
             }
             self.y.frob(&f[2]);
             self.y.qmul(&f[1]);
-            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 self.y.div_i();
             }
-            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
                 self.y.times_i2();
                 self.y.times_i2();
                 self.y.times_i();
@@ -914,7 +914,7 @@ impl ECP8 {
         // Number of bits
         mt.zero();
         for i in 0..16 {
-	    t[i].norm();
+            t[i].norm();
             mt.or(&t[i]);
         }
 
@@ -1105,7 +1105,7 @@ impl ECP8 {
         let mut x7Q = x6Q.mul(&mut x);
         let mut x8Q = x7Q.mul(&mut x);
 
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             xQ.neg();
             x3Q.neg();
             x5Q.neg();
diff --git a/src/ff.rs b/src/ff.rs
index 5855d88..54e7a32 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::super::arch::Chunk;
 use super::big;
-use super::dbig::DBig;
 use super::big::Big;
-use super::super::arch::Chunk;
+use super::dbig::DBig;
 use rand::RAND;
 
 use super::super::arch::DChunk;
diff --git a/src/fp.rs b/src/fp.rs
index 205d8d6..72b7390 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -17,14 +17,14 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::super::arch;
+use super::super::arch::Chunk;
 use super::big;
 use super::big::Big;
 use super::dbig::DBig;
 use super::rom;
-use super::super::arch::Chunk;
-use super::super::arch;
-use types::ModType;
 use std::str::FromStr;
+use types::ModType;
 
 #[derive(Copy, Clone)]
 pub struct FP {
@@ -50,17 +50,17 @@ impl fmt::Debug for FP {
     }
 }
 
-pub use super::rom::{MODBITS, MOD8, MODTYPE, SH};
-use std::str::SplitWhitespace;
+pub use super::rom::{MOD8, MODBITS, MODTYPE, SH};
 use std::fmt;
+use std::str::SplitWhitespace;
 
-pub const FEXCESS:i32 = (((1 as i32)<<SH)-1);
-pub const OMASK:Chunk = (-1)<<(MODBITS%big::BASEBITS);
-pub const TBITS:usize=MODBITS%big::BASEBITS; // Number of active bits in top word
-pub const TMASK:Chunk=(1<<TBITS)-1;
+pub const FEXCESS: i32 = (((1 as i32) << SH) - 1);
+pub const OMASK: Chunk = (-1) << (MODBITS % big::BASEBITS);
+pub const TBITS: usize = MODBITS % big::BASEBITS; // Number of active bits in top word
+pub const TMASK: Chunk = (1 << TBITS) - 1;
 
 impl FP {
-    /* Constructors */
+    // Constructors
     pub fn new() -> FP {
         FP {
             x: Big::new(),
@@ -90,9 +90,9 @@ impl FP {
     }
 
     pub fn nres(&mut self) {
-        if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let r=Big::new_ints(&rom::R2MODP);
-            let mut d=Big::mul(&(self.x),&r);
+        if MODTYPE != ModType::PseudoMersenne && MODTYPE != ModType::GeneralisedMersenne {
+            let r = Big::new_ints(&rom::R2MODP);
+            let mut d = Big::mul(&(self.x), &r);
             self.x.copy(&FP::modulo(&mut d));
             self.xes = 2;
         } else {
@@ -104,8 +104,8 @@ impl FP {
         let xes = i32::from_str(iter.next().unwrap()).unwrap();
         let x = iter.next().unwrap();
         FP {
-            x: Big::from_hex(x.to_string()),
-            xes
+            x: Big::fromstring(x.to_string()),
+            xes,
         }
     }
 
@@ -115,28 +115,26 @@ impl FP {
     }
 
     pub fn to_hex(&self) -> String {
-        let mut x = self.x;
-        let big = x.to_hex();
+        let x = self.x;
+        let big = x.tostring();
         format!("{} {}", self.xes, big)
     }
 
-/* convert back to regular form */
+    // convert back to regular form
     pub fn redc(&mut self) -> Big {
-        if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let mut d=DBig::new_scopy(&(self.x));
+        if MODTYPE != ModType::PseudoMersenne && MODTYPE != ModType::GeneralisedMersenne {
+            let mut d = DBig::new_scopy(&(self.x));
             return FP::modulo(&mut d);
-        } else {
-            let r = Big::new_copy(&(self.x));
-            return r;
         }
+        Big::new_copy(&(self.x))
     }
 
-    /* reduce a DBig to a Big using the appropriate form of the modulus */
-    /* dd */
+    // reduce a DBig to a Big using the appropriate form of the modulus
+    // dd
     pub fn modulo(d: &mut DBig) -> Big {
-        if MODTYPE==ModType::PSEUDO_MERSENNE {
-            let mut b=Big::new();
-            let mut t=d.split(MODBITS);
+        if MODTYPE == ModType::PseudoMersenne {
+            let mut b = Big::new();
+            let mut t = d.split(MODBITS);
             b.dcopy(&d);
             let v = t.pmul(rom::MCONST as isize);
 
@@ -150,7 +148,7 @@ impl FP {
             return t;
         }
 
-        if MODTYPE==ModType::MONTGOMERY_FRIENDLY {
+        if MODTYPE == ModType::MontgomeryFriendly {
             let mut b = Big::new();
             for i in 0..big::NLEN {
                 let x = d.w[i];
@@ -169,7 +167,7 @@ impl FP {
             return b;
         }
 
-        if MODTYPE == ModType::GENERALISED_MERSENNE {
+        if MODTYPE == ModType::GeneralisedMersenne {
             // GoldiLocks Only
             let mut b = Big::new();
             let t = d.split(MODBITS);
@@ -195,20 +193,19 @@ impl FP {
             b.norm();
             return b;
         }
-        if MODTYPE == ModType::NOT_SPECIAL {
+        if MODTYPE == ModType::NotSpecial {
             let m = Big::new_ints(&rom::MODULUS);
             return Big::monty(&m, rom::MCONST, d);
         }
-        return Big::new();
+        Big::new()
     }
 
-    /* convert to string */
+    // convert to string
     pub fn tostring(&mut self) -> String {
-        let s = self.redc().tostring();
-        return s;
+        self.redc().tostring()
     }
 
-    /* reduce this mod Modulus */
+    // reduce this mod Modulus
     pub fn reduce(&mut self) {
         let mut m = Big::new_ints(&rom::MODULUS);
         let mut r = Big::new_copy(&m);
@@ -229,48 +226,48 @@ impl FP {
         while sb > 0 {
             let sr = Big::ssn(&mut r, &self.x, &mut m);
             self.x.cmove(&r, 1 - sr);
-            sb = sb - 1;
+            sb -= 1;
         }
 
         self.xes = 1;
     }
 
-    /* test this=0? */
+    // test this=0?
     pub fn iszilch(&self) -> bool {
         let mut a = FP::new_copy(self);
         a.reduce();
-        return a.x.iszilch();
+        a.x.iszilch()
     }
 
-    /* copy from FP b */
+    // copy from FP b
     pub fn copy(&mut self, b: &FP) {
         self.x.copy(&(b.x));
         self.xes = b.xes;
     }
 
-    /* copy from Big b */
+    // copy from Big b
     pub fn bcopy(&mut self, b: &Big) {
         self.x.copy(&b);
         self.nres();
     }
 
-    /* set this=0 */
+    // set this=0
     pub fn zero(&mut self) {
         self.x.zero();
         self.xes = 1;
     }
 
-    /* set this=1 */
+    // set this=1
     pub fn one(&mut self) {
         self.x.one();
         self.nres()
     }
 
-    /* normalise this */
+    // normalise this
     pub fn norm(&mut self) {
         self.x.norm();
     }
-    /* swap FPs depending on d */
+    // swap FPs depending on d
     pub fn cswap(&mut self, b: &mut FP, d: isize) {
         self.x.cswap(&mut (b.x), d);
         let mut c = d as i32;
@@ -280,16 +277,16 @@ impl FP {
         b.xes ^= t;
     }
 
-    /* copy FPs depending on d */
+    // copy FPs depending on d
     pub fn cmove(&mut self, b: &FP, d: isize) {
         self.x.cmove(&(b.x), d);
         let c = d as i32;
         self.xes ^= (self.xes ^ b.xes) & (-c);
     }
 
-    /* this*=b mod Modulus */
+    // this*=b mod Modulus
     pub fn mul(&mut self, b: &FP) {
-        if (self.xes as i64) * (b.xes as i64) > FEXCESS as i64 {
+        if i64::from(self.xes) * i64::from(b.xes) > i64::from(FEXCESS) {
             self.reduce()
         }
 
@@ -308,8 +305,7 @@ impl FP {
 
         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;
+        ((((v + (v >> 4)) & 0xF0F0F0F).wrapping_mul(0x1010101)) >> 24) as usize
     }
 
     // find approximation to quotient of a/m
@@ -330,7 +326,7 @@ impl FP {
         }
     }
 
-    /* this = -this mod Modulus */
+    // this = -this mod Modulus
     pub fn neg(&mut self) {
         let mut p = Big::new_ints(&rom::MODULUS);
         let sb = FP::logb2((self.xes - 1) as u32);
@@ -343,7 +339,7 @@ impl FP {
         }
     }
 
-    /* this*=c mod Modulus, where c is a small int */
+    // this*=c mod Modulus, where c is a small int
     pub fn imul(&mut self, c: isize) {
         let mut cc = c;
         let mut s = false;
@@ -352,7 +348,7 @@ impl FP {
             s = true;
         }
 
-        if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
+        if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
             let mut d = self.x.pxmul(cc);
             self.x.copy(&FP::modulo(&mut d));
             self.xes = 2
@@ -372,9 +368,9 @@ impl FP {
         }
     }
 
-    /* self*=self mod Modulus */
+    // self*=self mod Modulus
     pub fn sqr(&mut self) {
-        if (self.xes as i64) * (self.xes as i64) > FEXCESS as i64 {
+        if i64::from(self.xes) * i64::from(self.xes) > i64::from(FEXCESS) {
             self.reduce()
         }
 
@@ -383,7 +379,7 @@ impl FP {
         self.xes = 2
     }
 
-    /* self+=b */
+    // self+=b
     pub fn add(&mut self, b: &FP) {
         self.x.add(&(b.x));
         self.xes += b.xes;
@@ -392,7 +388,7 @@ impl FP {
         }
     }
 
-    /* self+=self */
+    // self+=self
     pub fn dbl(&mut self) {
         self.x.dbl();
         self.xes += self.xes;
@@ -401,20 +397,20 @@ impl FP {
         }
     }
 
-    /* self-=b */
+    // self-=b
     pub fn sub(&mut self, b: &FP) {
         let mut n = FP::new_copy(b);
         n.neg();
         self.add(&n);
     }
 
-    /* self=b-self */
+    // self=b-self
     pub fn rsub(&mut self, b: &FP) {
         self.neg();
         self.add(&b);
     }
 
-    /* self/=2 mod Modulus */
+    // self/=2 mod Modulus
     pub fn div2(&mut self) {
         if self.x.parity() == 0 {
             self.x.fshr(1);
@@ -479,7 +475,7 @@ impl FP {
         let mut n = MODBITS as isize;
         let c: isize;
 
-        if MODTYPE == ModType::GENERALISED_MERSENNE {
+        if MODTYPE == ModType::GeneralisedMersenne {
             // Goldilocks ONLY
             n /= 2;
         }
@@ -564,21 +560,21 @@ impl FP {
             }
             r.mul(&key);
         }
-        if MODTYPE == ModType::GENERALISED_MERSENNE {
+        if MODTYPE == ModType::GeneralisedMersenne {
             // Goldilocks ONLY
             key.copy(&r);
             r.sqr();
             r.mul(&self);
-            for _ in 0..n + 1 {
+            for _ in 0..=n {
                 r.sqr();
             }
             r.mul(&key);
         }
-        return r;
+        r
     }
-    /* self=1/self mod Modulus */
+    // self=1/self mod Modulus
     pub fn inverse(&mut self) {
-        if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
+        if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
             let mut y = self.fpow();
             if MOD8 == 5 {
                 let mut t = FP::new_copy(self);
@@ -600,7 +596,7 @@ impl FP {
         }
     }
 
-    /* return TRUE if self==a */
+    // return TRUE if self==a
     pub fn equals(&self, a: &FP) -> bool {
         let mut f = FP::new_copy(self);
         let mut s = FP::new_copy(a);
@@ -612,7 +608,7 @@ impl FP {
         return false;
     }
 
-    /* return self^e mod Modulus */
+    // return self^e mod Modulus
     pub fn pow(&mut self, e: &mut Big) -> FP {
         let mut tb: [FP; 16] = [
             FP::new(),
@@ -668,7 +664,7 @@ impl FP {
         return r;
     }
 
-    /* return sqrt(this) mod Modulus */
+    // return sqrt(this) mod Modulus
     pub fn sqrt(&mut self) -> FP {
         self.reduce();
 
@@ -676,7 +672,7 @@ impl FP {
             let v: FP;
             let mut i = FP::new_copy(self);
             i.x.shl(1);
-            if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
+            if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
                 v = i.fpow();
             } else {
                 let mut p = Big::new_ints(&rom::MODULUS);
@@ -695,7 +691,7 @@ impl FP {
             return r;
         } else {
             let mut r: FP;
-            if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
+            if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
                 r = self.fpow();
                 r.mul(self);
             } else {
@@ -708,10 +704,10 @@ impl FP {
             return r;
         }
     }
-    /* return jacobi symbol (this/Modulus) */
+    // return jacobi symbol (this/Modulus)
     pub fn jacobi(&mut self) -> isize {
-        let mut p = Big::new_ints(&rom::MODULUS);
+        let p = Big::new_ints(&rom::MODULUS);
         let mut w = self.redc();
-        return w.jacobi(&mut p);
+        return w.jacobi(&p);
     }
 }
diff --git a/src/fp12.rs b/src/fp12.rs
index 311fe87..0ba5fc1 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -18,19 +18,19 @@ under the License.
 */
 
 use super::big;
+use super::big::Big;
+use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::Big;
 use super::rom;
-use types::SexticTwist;
 use std::str::SplitWhitespace;
-use super::ecp;
+use types::SexticTwist;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP12 {
@@ -41,9 +41,9 @@ pub struct FP12 {
 }
 
 impl PartialEq for FP12 {
-	fn eq(&self, other: &FP12) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP12) -> bool {
+        self.equals(other)
+    }
 }
 
 impl FP12 {
@@ -52,12 +52,12 @@ impl FP12 {
             a: FP4::new(),
             b: FP4::new(),
             c: FP4::new(),
-	    stype: ZERO,
+            stype: ZERO,
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -69,11 +69,11 @@ impl FP12 {
         f.a.copy(&FP4::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -82,7 +82,7 @@ impl FP12 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -91,7 +91,7 @@ impl FP12 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -100,7 +100,7 @@ impl FP12 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -129,9 +129,9 @@ impl FP12 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -175,20 +175,20 @@ impl FP12 {
 
     pub fn geta(&mut self) -> FP4 {
         return self.a;
-//        let f = FP4::new_copy(&self.a);
-//        return f;
+        //        let f = FP4::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP4 {
         return self.b;
-//        let f = FP4::new_copy(&self.b);
-//        return f;
+        //        let f = FP4::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP4 {
         return self.c;
-//        let f = FP4::new_copy(&self.c);
-//        return f;
+        //        let f = FP4::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -196,7 +196,7 @@ impl FP12 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -204,7 +204,7 @@ impl FP12 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -212,7 +212,7 @@ impl FP12 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -260,13 +260,13 @@ impl FP12 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
 
@@ -304,10 +304,10 @@ impl FP12 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -316,7 +316,7 @@ impl FP12 {
     pub fn mul(&mut self, y: &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 z2 = FP4::new_copy(&self.b);
         let mut z3 = FP4::new();
         let mut t0 = FP4::new_copy(&self.a);
         let mut t1 = FP4::new_copy(&y.a);
@@ -379,100 +379,112 @@ impl FP12 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
-/* FP12 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP12 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP12) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP4::new_copy(&self.a);
-            let mut z1=FP4::new_int(0);
-            let mut z2=FP4::new_int(0);
-            let mut z3=FP4::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP4::new_copy(&self.a);
+            let mut z1 = FP4::new_int(0);
+            let mut z2 = FP4::new_int(0);
+            let mut z3 = FP4::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP2::new_int(0);
-		    let mut gb=FP2::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP2::new_int(0);
+                    let mut gb = FP2::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp2s(&ga,&gb);
+                    z2.set_fp2s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
             } else {
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP4::new_copy(&self.a);
-            let mut t1=FP4::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
-
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
-
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
+            let mut t0 = FP4::new_copy(&self.a);
+            let mut t1 = FP4::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
 
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP2::new_int(0);
-		    let mut gb=FP2::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP2::new_int(0);
+                    let mut gb = FP2::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp2s(&ga,&gb);
+                    t0.set_fp2s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
@@ -481,26 +493,30 @@ impl FP12 {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
-                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_int(0);
-                let mut t1=FP4::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                // dense by sparser - 13m
+                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_int(0);
+                let mut t1 = FP4::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -514,8 +530,10 @@ impl FP12 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -523,16 +541,19 @@ impl FP12 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 let mut z0 = FP4::new_copy(&self.a);
                 let mut z1 = FP4::new();
                 let mut z2 = FP4::new();
@@ -541,23 +562,31 @@ impl FP12 {
                 let mut t1 = FP4::new();
 
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
@@ -565,55 +594,68 @@ impl FP12 {
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP12) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-            let mut w1=FP2::new_copy(&self.a.geta());
-            let mut w2=FP2::new_copy(&self.a.getb());
-            let mut w3=FP2::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
+            let mut w1 = FP2::new_copy(&self.a.geta());
+            let mut w2 = FP2::new_copy(&self.a.getb());
+            let mut w3 = FP2::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP2::new_copy(&self.a.geta());
-            let mut tb=FP2::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP2::new_copy(&ta);
+            let mut ta = FP2::new_copy(&self.a.geta());
+            let mut tb = FP2::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP2::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP2::new_copy(&w1);
+            let mut t = FP2::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP2::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP2::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP2::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP2::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -623,44 +665,54 @@ impl FP12 {
             w2.mul_ip();
             w1.add(&w2);
 
-	    self.a.set_fp2s(&w1,&tc);
-	    self.b.set_fp2s(&td,&te);
-	    self.c.set_fp2(&w3);
+            self.a.set_fp2s(&w1, &tc);
+            self.b.set_fp2s(&td, &te);
+            self.c.set_fp2(&w3);
 
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP2::new_copy(&self.a.geta());
-            let mut w2=FP2::new_copy(&self.a.getb());
-            let mut w3=FP2::new_copy(&self.c.getb());
+            let mut w1 = FP2::new_copy(&self.a.geta());
+            let mut w2 = FP2::new_copy(&self.a.getb());
+            let mut w3 = FP2::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP2::new_copy(&self.a.geta());
-            let mut tb=FP2::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP2::new_copy(&ta);
+            let mut ta = FP2::new_copy(&self.a.geta());
+            let mut tb = FP2::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP2::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP2::new_copy(&w1);
+            let mut t = FP2::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP2::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP2::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP2::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP2::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -669,20 +721,20 @@ impl FP12 {
 
             w2.mul_ip();
             w1.add(&w2);
-	    self.a.set_fp2s(&w1,&tc);
+            self.a.set_fp2s(&w1, &tc);
 
             w3.mul_ip();
             w3.norm();
-	    self.b.set_fp2h(&w3);
+            self.b.set_fp2h(&w3);
 
             te.norm();
             te.mul_ip();
-	    self.c.set_fp2s(&te,&td);
+            self.c.set_fp2s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -730,7 +782,7 @@ impl FP12 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -747,7 +799,7 @@ impl FP12 {
 
         self.b.pmul(f);
         self.c.pmul(&f2);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
@@ -902,7 +954,12 @@ impl FP12 {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.a.to_hex(), self.b.to_hex(), self.c.to_hex())
+        format!(
+            "{} {} {}",
+            self.a.to_hex(),
+            self.b.to_hex(),
+            self.c.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP12 {
@@ -910,7 +967,7 @@ impl FP12 {
             a: FP4::from_hex_iter(iter),
             b: FP4::from_hex_iter(iter),
             c: FP4::from_hex_iter(iter),
-	    stype: DENSE
+            stype: DENSE,
         }
     }
 
@@ -973,15 +1030,15 @@ impl FP12 {
         m.rmod(&r);
 
         let mut a = Big::new_copy(&e);
-        a.rmod(&mut m);
+        a.rmod(&m);
 
         let mut b = Big::new_copy(&e);
-        b.div(&mut m);
+        b.div(&m);
 
         let mut c = g1.trace();
 
         if b.iszilch() {
-            c = c.xtr_pow(&mut a);
+            c = c.xtr_pow(&a);
             return c;
         }
 
@@ -993,7 +1050,7 @@ impl FP12 {
         g2.mul(&g1);
         let cpm2 = g2.trace();
 
-        c = c.xtr_pow2(&cp, &cpm1, &cpm2, &mut a, &mut b);
+        c = c.xtr_pow2(&cp, &cpm1, &cpm2, &a, &b);
 
         return c;
     }
@@ -1086,15 +1143,15 @@ impl FP12 {
                 t[j].dec((bt >> 1) as isize);
                 t[j].norm();
                 w[i] += bt * (k as i8);
-                k = 2 * k;
+                k *= 2;
             }
         }
 
         // Main loop
-        p.selector(&g, (2 * w[nb - 1] + 1) as i32);
+        p.selector(&g, i32::from(2 * w[nb - 1] + 1));
         for i in (0..nb - 1).rev() {
             p.usqr();
-            r.selector(&g, (2 * w[i] + s[i]) as i32);
+            r.selector(&g, i32::from(2 * w[i] + s[i]));
             p.mul(&r);
         }
 
diff --git a/src/fp16.rs b/src/fp16.rs
index 2c4e976..55dd573 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::Big;
 use super::fp2::FP2;
 use super::fp8::FP8;
-use super::big::Big;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -64,19 +64,19 @@ impl FP16 {
         return f;
     }
 
-    pub fn set_fp8s(&mut self,c: &FP8, d: &FP8) {
+    pub fn set_fp8s(&mut self, c: &FP8, d: &FP8) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp8(&mut self,c: &FP8) {
+    pub fn set_fp8(&mut self, c: &FP8) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp8h(&mut self,c: &FP8) {
+    pub fn set_fp8h(&mut self, c: &FP8) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
     /* reduce components mod Modulus */
@@ -119,14 +119,14 @@ impl FP16 {
 
     pub fn geta(&self) -> FP8 {
         return self.a;
-//        let f = FP8::new_copy(&self.a);
-//        return f;
+        //        let f = FP8::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP8 {
         return self.b;
-//        let f = FP8::new_copy(&self.b);
-//        return f;
+        //        let f = FP8::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
@@ -359,7 +359,7 @@ impl FP16 {
             let bt = z.parity();
             z.fshr(1);
             if bt == 1 {
-                r.mul(&mut w)
+                r.mul(&w)
             };
             if z.iszilch() {
                 break;
diff --git a/src/fp2.rs b/src/fp2.rs
index 060b9de..7ed108b 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::fp;
-use super::fp::FP;
 use super::big::Big;
 use super::dbig::DBig;
+use super::fp;
+use super::fp::FP;
 use super::rom;
-use std::str::SplitWhitespace;
 use std::fmt;
+use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
 pub struct FP2 {
@@ -32,21 +32,21 @@ pub struct FP2 {
 }
 
 impl PartialEq for FP2 {
-	fn eq(&self, other: &FP2) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP2) -> bool {
+        self.equals(other)
+    }
 }
 
 impl fmt::Display for FP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "FP2: [ {}, {} ]", self.a, self.b)
-	}
+    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)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "FP2: [ {}, {} ]", self.a, self.b)
+    }
 }
 
 impl FP2 {
@@ -239,7 +239,9 @@ impl FP2 {
 
     /* this*=y */
     pub fn mul(&mut self, y: &FP2) {
-        if ((self.a.xes + self.b.xes) as i64) * ((y.a.xes + y.b.xes) as i64) > fp::FEXCESS as i64 {
+        if i64::from(self.a.xes + self.b.xes) * i64::from(y.a.xes + y.b.xes)
+            > i64::from(fp::FEXCESS)
+        {
             if self.a.xes > 1 {
                 self.a.reduce()
             }
@@ -331,7 +333,7 @@ impl FP2 {
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP2 {
         FP2 {
             a: FP::from_hex_iter(iter),
-            b: FP::from_hex_iter(iter)
+            b: FP::from_hex_iter(iter),
         }
     }
 
diff --git a/src/fp24.rs b/src/fp24.rs
index 3deb850..93c1266 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -18,20 +18,20 @@ under the License.
 */
 
 use super::big;
+use super::big::Big;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::Big;
 use super::rom;
-use types::{SexticTwist};
+use types::SexticTwist;
 //use std::str::SplitWhitespace;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP24 {
@@ -51,8 +51,8 @@ impl FP24 {
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -64,11 +64,11 @@ impl FP24 {
         f.a.copy(&FP8::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -77,7 +77,7 @@ impl FP24 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -86,7 +86,7 @@ impl FP24 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -95,7 +95,7 @@ impl FP24 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -123,9 +123,9 @@ impl FP24 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -169,20 +169,20 @@ impl FP24 {
 
     pub fn geta(&mut self) -> FP8 {
         return self.a;
-//        let f = FP8::new_copy(&self.a);
-//        return f;
+        //        let f = FP8::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP8 {
         return self.b;
-//	let f = FP8::new_copy(&self.b);
-//        return f;
+        //	let f = FP8::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP8 {
         return self.c;
-//        let f = FP8::new_copy(&self.c);
-//        return f;
+        //        let f = FP8::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -190,7 +190,7 @@ impl FP24 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -198,7 +198,7 @@ impl FP24 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -206,7 +206,7 @@ impl FP24 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -254,13 +254,13 @@ impl FP24 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
         let mut a = FP8::new_copy(&self.a);
@@ -297,10 +297,10 @@ impl FP24 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -373,99 +373,112 @@ impl FP24 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-/* FP24 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP24 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP24) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP8::new_copy(&self.a);
-            let mut z1=FP8::new_int(0);
-            let mut z2=FP8::new_int(0);
-            let mut z3=FP8::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP8::new_copy(&self.a);
+            let mut z1 = FP8::new_int(0);
+            let mut z2 = FP8::new_int(0);
+            let mut z3 = FP8::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP4::new_int(0);
-		    let mut gb=FP4::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP4::new_int(0);
+                    let mut gb = FP4::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp4s(&ga,&gb);
+                    z2.set_fp4s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
             } else {
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP8::new_copy(&self.a);
-            let mut t1=FP8::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
-
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
-
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
+            let mut t0 = FP8::new_copy(&self.a);
+            let mut t1 = FP8::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
 
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP4::new_int(0);
-		    let mut gb=FP4::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP4::new_int(0);
+                    let mut gb = FP4::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp4s(&ga,&gb);
+                    t0.set_fp4s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
@@ -474,26 +487,30 @@ impl FP24 {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
-                let mut z0=FP8::new_copy(&self.a);
-                let mut z2=FP8::new_copy(&self.b);
-                let mut z3=FP8::new_copy(&self.b);
-                let mut t0=FP8::new_int(0);
-                let mut t1=FP8::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                // dense by sparser - 13m
+                let mut z0 = FP8::new_copy(&self.a);
+                let mut z2 = FP8::new_copy(&self.b);
+                let mut z3 = FP8::new_copy(&self.b);
+                let mut t0 = FP8::new_int(0);
+                let mut t1 = FP8::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -507,8 +524,10 @@ impl FP24 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -516,16 +535,19 @@ impl FP24 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 let mut z0 = FP8::new_copy(&self.a);
                 let mut z1 = FP8::new();
                 let mut z2 = FP8::new();
@@ -534,23 +556,31 @@ impl FP24 {
                 let mut t1 = FP8::new();
 
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
@@ -558,56 +588,68 @@ impl FP24 {
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP24) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-            let mut w1=FP4::new_copy(&self.a.geta());
-            let mut w2=FP4::new_copy(&self.a.getb());
-            let mut w3=FP4::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
+            let mut w1 = FP4::new_copy(&self.a.geta());
+            let mut w2 = FP4::new_copy(&self.a.getb());
+            let mut w3 = FP4::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP4::new_copy(&self.a.geta());
-            let mut tb=FP4::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP4::new_copy(&ta);
+            let mut ta = FP4::new_copy(&self.a.geta());
+            let mut tb = FP4::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP4::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP4::new_copy(&w1);
+            let mut t = FP4::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP4::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP4::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP4::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP4::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -617,44 +659,54 @@ impl FP24 {
             w2.times_i();
             w1.add(&w2);
 
-	    self.a.set_fp4s(&w1,&tc);
-	    self.b.set_fp4s(&td,&te);
-	    self.c.set_fp4(&w3);
+            self.a.set_fp4s(&w1, &tc);
+            self.b.set_fp4s(&td, &te);
+            self.c.set_fp4(&w3);
 
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP4::new_copy(&self.a.geta());
-            let mut w2=FP4::new_copy(&self.a.getb());
-            let mut w3=FP4::new_copy(&self.c.getb());
+            let mut w1 = FP4::new_copy(&self.a.geta());
+            let mut w2 = FP4::new_copy(&self.a.getb());
+            let mut w3 = FP4::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP4::new_copy(&self.a.geta());
-            let mut tb=FP4::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP4::new_copy(&ta);
+            let mut ta = FP4::new_copy(&self.a.geta());
+            let mut tb = FP4::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP4::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP4::new_copy(&w1);
+            let mut t = FP4::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP4::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP4::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP4::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP4::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -663,20 +715,20 @@ impl FP24 {
 
             w2.times_i();
             w1.add(&w2);
-	    self.a.set_fp4s(&w1,&tc);
+            self.a.set_fp4s(&w1, &tc);
 
             w3.times_i();
             w3.norm();
-	    self.b.set_fp4h(&w3);
+            self.b.set_fp4h(&w3);
 
             te.norm();
             te.times_i();
-	    self.c.set_fp4s(&te,&td);
+            self.c.set_fp4s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -724,7 +776,7 @@ impl FP24 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -749,7 +801,7 @@ impl FP24 {
             self.c.times_i2();
             self.c.times_i2();
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
diff --git a/src/fp4.rs b/src/fp4.rs
index d2d890b..3fda179 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::Big;
 use super::fp::FP;
 use super::fp2::FP2;
-use super::big::Big;
 use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -29,9 +29,9 @@ pub struct FP4 {
 }
 
 impl PartialEq for FP4 {
-	fn eq(&self, other: &FP4) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP4) -> bool {
+        self.equals(other)
+    }
 }
 
 impl FP4 {
@@ -70,19 +70,19 @@ impl FP4 {
         return f;
     }
 
-    pub fn set_fp2s(&mut self,c: &FP2, d: &FP2) {
+    pub fn set_fp2s(&mut self, c: &FP2, d: &FP2) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp2(&mut self,c: &FP2) {
+    pub fn set_fp2(&mut self, c: &FP2) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp2h(&mut self,c: &FP2) {
+    pub fn set_fp2h(&mut self, c: &FP2) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
     /* reduce components mod Modulus */
@@ -125,14 +125,14 @@ impl FP4 {
 
     pub fn geta(&self) -> FP2 {
         return self.a;
-//        let f = FP2::new_copy(&self.a);
-//        return f;
+        //        let f = FP2::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP2 {
         return self.b;
-//        let f = FP2::new_copy(&self.b);
-//        return f;
+        //        let f = FP2::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
@@ -313,7 +313,7 @@ impl FP4 {
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP4 {
         FP4 {
             a: FP2::from_hex_iter(iter),
-            b: FP2::from_hex_iter(iter)
+            b: FP2::from_hex_iter(iter),
         }
     }
 
@@ -370,7 +370,7 @@ impl FP4 {
             let bt = z.parity();
             z.fshr(1);
             if bt == 1 {
-                r.mul(&mut w)
+                r.mul(&w)
             };
             if z.iszilch() {
                 break;
@@ -607,7 +607,7 @@ impl FP4 {
         for _ in 0..f2 {
             r.xtr_d()
         }
-        r = r.xtr_pow(&mut d);
+        r = r.xtr_pow(&d);
         return r;
     }
 
diff --git a/src/fp48.rs b/src/fp48.rs
index ff64d4c..8ab6063 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -18,21 +18,21 @@ under the License.
 */
 
 use super::big;
+use super::big::Big;
 use super::ecp;
+use super::fp16::FP16;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::fp16::FP16;
-use super::big::Big;
 use super::rom;
 use types::SexticTwist;
 //use std::str::SplitWhitespace;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP48 {
@@ -48,12 +48,12 @@ impl FP48 {
             a: FP16::new(),
             b: FP16::new(),
             c: FP16::new(),
-	    stype: ZERO,
+            stype: ZERO,
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -65,11 +65,11 @@ impl FP48 {
         f.a.copy(&FP16::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -78,7 +78,7 @@ impl FP48 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -87,7 +87,7 @@ impl FP48 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -96,7 +96,7 @@ impl FP48 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -124,9 +124,9 @@ impl FP48 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -170,20 +170,20 @@ impl FP48 {
 
     pub fn geta(&mut self) -> FP16 {
         return self.a;
-//        let f = FP16::new_copy(&self.a);
-//        return f;
+        //        let f = FP16::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP16 {
         return self.b;
-//        let f = FP16::new_copy(&self.b);
-//        return f;
+        //        let f = FP16::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP16 {
         return self.c;
-//        let f = FP16::new_copy(&self.c);
-//        return f;
+        //        let f = FP16::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -191,7 +191,7 @@ impl FP48 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -199,7 +199,7 @@ impl FP48 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -207,7 +207,7 @@ impl FP48 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -255,13 +255,13 @@ impl FP48 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
         let mut a = FP16::new_copy(&self.a);
@@ -298,10 +298,10 @@ impl FP48 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -373,99 +373,112 @@ impl FP48 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-/* FP48 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP48 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP48) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP16::new_copy(&self.a);
-            let mut z1=FP16::new_int(0);
-            let mut z2=FP16::new_int(0);
-            let mut z3=FP16::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP16::new_copy(&self.a);
+            let mut z1 = FP16::new_int(0);
+            let mut z2 = FP16::new_int(0);
+            let mut z3 = FP16::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP8::new_int(0);
-		    let mut gb=FP8::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP8::new_int(0);
+                    let mut gb = FP8::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp8s(&ga,&gb);
+                    z2.set_fp8s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
             } else {
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP16::new_copy(&self.a);
-            let mut t1=FP16::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
-
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
-
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
+            let mut t0 = FP16::new_copy(&self.a);
+            let mut t1 = FP16::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
 
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP8::new_int(0);
-		    let mut gb=FP8::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP8::new_int(0);
+                    let mut gb = FP8::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp8s(&ga,&gb);
+                    t0.set_fp8s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
@@ -474,26 +487,30 @@ impl FP48 {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
-                let mut z0=FP16::new_copy(&self.a);
-                let mut z2=FP16::new_copy(&self.b);
-                let mut z3=FP16::new_copy(&self.b);
-                let mut t0=FP16::new_int(0);
-                let mut t1=FP16::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::DType {
+                // dense by sparser - 13m
+                let mut z0 = FP16::new_copy(&self.a);
+                let mut z2 = FP16::new_copy(&self.b);
+                let mut z3 = FP16::new_copy(&self.b);
+                let mut t0 = FP16::new_int(0);
+                let mut t1 = FP16::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -507,8 +524,10 @@ impl FP48 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -516,16 +535,19 @@ impl FP48 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::MType {
                 let mut z0 = FP16::new_copy(&self.a);
                 let mut z1 = FP16::new();
                 let mut z2 = FP16::new();
@@ -534,23 +556,31 @@ impl FP48 {
                 let mut t1 = FP16::new();
 
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
@@ -558,56 +588,68 @@ impl FP48 {
 
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP48) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-            let mut w1=FP8::new_copy(&self.a.geta());
-            let mut w2=FP8::new_copy(&self.a.getb());
-            let mut w3=FP8::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::DType {
+            let mut w1 = FP8::new_copy(&self.a.geta());
+            let mut w2 = FP8::new_copy(&self.a.getb());
+            let mut w3 = FP8::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP8::new_copy(&self.a.geta());
-            let mut tb=FP8::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP8::new_copy(&ta);
+            let mut ta = FP8::new_copy(&self.a.geta());
+            let mut tb = FP8::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP8::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP8::new_copy(&w1);
+            let mut t = FP8::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP8::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP8::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP8::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP8::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -617,44 +659,54 @@ impl FP48 {
             w2.times_i();
             w1.add(&w2);
 
-	    self.a.set_fp8s(&w1,&tc);
-	    self.b.set_fp8s(&td,&te);
-	    self.c.set_fp8(&w3);
+            self.a.set_fp8s(&w1, &tc);
+            self.b.set_fp8s(&td, &te);
+            self.c.set_fp8(&w3);
 
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP8::new_copy(&self.a.geta());
-            let mut w2=FP8::new_copy(&self.a.getb());
-            let mut w3=FP8::new_copy(&self.c.getb());
+            let mut w1 = FP8::new_copy(&self.a.geta());
+            let mut w2 = FP8::new_copy(&self.a.getb());
+            let mut w3 = FP8::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP8::new_copy(&self.a.geta());
-            let mut tb=FP8::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP8::new_copy(&ta);
+            let mut ta = FP8::new_copy(&self.a.geta());
+            let mut tb = FP8::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP8::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP8::new_copy(&w1);
+            let mut t = FP8::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP8::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP8::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP8::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP8::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -663,20 +715,20 @@ impl FP48 {
 
             w2.times_i();
             w1.add(&w2);
-	    self.a.set_fp8s(&w1,&tc);
+            self.a.set_fp8s(&w1, &tc);
 
             w3.times_i();
             w3.norm();
-	    self.b.set_fp8h(&w3);
+            self.b.set_fp8h(&w3);
 
             te.norm();
             te.times_i();
-	    self.c.set_fp8s(&te,&td);
+            self.c.set_fp8s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -724,7 +776,7 @@ impl FP48 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -753,7 +805,7 @@ impl FP48 {
             self.c.times_i4();
             self.c.times_i4();
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
diff --git a/src/fp8.rs b/src/fp8.rs
index 1fcc336..38515a8 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::Big;
 use super::fp::FP;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::Big;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -65,22 +65,21 @@ impl FP8 {
         return f;
     }
 
-    pub fn set_fp4s(&mut self,c: &FP4, d: &FP4) {
+    pub fn set_fp4s(&mut self, c: &FP4, d: &FP4) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp4(&mut self,c: &FP4) {
+    pub fn set_fp4(&mut self, c: &FP4) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp4h(&mut self,c: &FP4) {
+    pub fn set_fp4h(&mut self, c: &FP4) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
-
     /* reduce components mod Modulus */
     pub fn reduce(&mut self) {
         self.a.reduce();
@@ -121,14 +120,14 @@ impl FP8 {
 
     pub fn geta(&self) -> FP4 {
         return self.a;
-//        let f = FP4::new_copy(&self.a);
-//        return f;
+        //        let f = FP4::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP4 {
         return self.b;
-//        let f = FP4::new_copy(&self.b);
-//        return f;
+        //        let f = FP4::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
@@ -368,7 +367,7 @@ impl FP8 {
             let bt = z.parity();
             z.fshr(1);
             if bt == 1 {
-                r.mul(&mut w)
+                r.mul(&w)
             };
             if z.iszilch() {
                 break;
diff --git a/src/hash256.rs b/src/hash256.rs
index e8d6260..5df85d9 100644
--- a/src/hash256.rs
+++ b/src/hash256.rs
@@ -17,14 +17,14 @@ specific language governing permissions and limitations
 under the License.
 */
 
-const HASH256_H0: u32 = 0x6A09E667;
-const HASH256_H1: u32 = 0xBB67AE85;
-const HASH256_H2: u32 = 0x3C6EF372;
-const HASH256_H3: u32 = 0xA54FF53A;
-const HASH256_H4: u32 = 0x510E527F;
-const HASH256_H5: u32 = 0x9B05688C;
-const HASH256_H6: u32 = 0x1F83D9AB;
-const HASH256_H7: u32 = 0x5BE0CD19;
+const HASH256_H0: u32 = 0x6A09_E667;
+const HASH256_H1: u32 = 0xBB67_AE85;
+const HASH256_H2: u32 = 0x3C6E_F372;
+const HASH256_H3: u32 = 0xA54F_F53A;
+const HASH256_H4: u32 = 0x510E_527F;
+const HASH256_H5: u32 = 0x9B05_688C;
+const HASH256_H6: u32 = 0x1F83_D9AB;
+const HASH256_H7: u32 = 0x5BE0_CD19;
 
 const HASH256_K: [u32; 64] = [
     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
diff --git a/src/lib.rs b/src/lib.rs
index 108057b..c68a165 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,18 +1,18 @@
 pub mod aes;
+#[cfg(target_pointer_width = "32")]
+#[path = "arch/arch32.rs"]
+pub mod arch;
+#[cfg(target_pointer_width = "64")]
+#[path = "arch/arch64.rs"]
+pub mod arch;
 pub mod gcm;
 pub mod hash256;
 pub mod hash384;
 pub mod hash512;
+pub mod nhs;
 pub mod rand;
 pub mod sha3;
-pub mod nhs;
 pub mod types;
-#[cfg(target_pointer_width = "32")]
-#[path = "arch/arch32.rs"]
-pub mod arch;
-#[cfg(target_pointer_width = "64")]
-#[path = "arch/arch64.rs"]
-pub mod arch;
 
 #[cfg(feature = "bls48")]
 #[path = "./"]
@@ -25,18 +25,18 @@ pub mod bls48 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls256;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp8;
+    pub mod fp;
+    pub mod fp16;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp8;
-    pub mod fp16;
     pub mod fp48;
-    pub mod pair256;
+    pub mod fp8;
     pub mod mpin256;
-    pub mod bls256;
+    pub mod pair256;
 }
 
 #[cfg(feature = "bls461")]
@@ -50,16 +50,16 @@ pub mod bls461 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls383")]
@@ -73,16 +73,16 @@ pub mod bls383 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls381")]
@@ -96,16 +96,16 @@ pub mod bls381 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "fp512bn")]
@@ -119,16 +119,16 @@ pub mod fp512bn {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "fp256bn")]
@@ -142,16 +142,16 @@ pub mod fp256bn {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls24")]
@@ -165,17 +165,17 @@ pub mod bls24 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls192;
     pub mod dbig;
+    pub mod ecp;
+    pub mod ecp4;
     pub mod fp;
     pub mod fp2;
+    pub mod fp24;
     pub mod fp4;
     pub mod fp8;
-    pub mod fp24;
-    pub mod ecp;
-    pub mod ecp4;
-    pub mod pair192;
     pub mod mpin192;
-    pub mod bls192;
+    pub mod pair192;
 }
 
 #[cfg(feature = "anssi")]
@@ -190,9 +190,9 @@ pub mod anssi {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "brainpool")]
@@ -207,9 +207,9 @@ pub mod brainpool {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "goldilocks")]
@@ -224,9 +224,9 @@ pub mod goldilocks {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "hifive")]
@@ -241,9 +241,9 @@ pub mod hifive {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist256")]
@@ -258,9 +258,9 @@ pub mod nist256 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist384")]
@@ -275,9 +275,9 @@ pub mod nist384 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist521")]
@@ -292,9 +292,9 @@ pub mod nist521 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums256e")]
@@ -309,9 +309,9 @@ pub mod nums256e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums256w")]
@@ -326,9 +326,9 @@ pub mod nums256w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums384e")]
@@ -343,9 +343,9 @@ pub mod nums384e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums384w")]
@@ -360,9 +360,9 @@ pub mod nums384w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums512w")]
@@ -377,9 +377,9 @@ pub mod nums512w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums512e")]
@@ -394,9 +394,9 @@ pub mod nums512e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "secp256k1")]
@@ -411,9 +411,9 @@ pub mod secp256k1 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "c25519")]
@@ -428,9 +428,9 @@ pub mod c25519 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "c41417")]
@@ -445,9 +445,9 @@ pub mod c41417 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "ed25519")]
@@ -462,9 +462,9 @@ pub mod ed25519 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "bn254CX")]
@@ -478,17 +478,17 @@ pub mod bn254CX {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bn254")]
@@ -502,60 +502,60 @@ pub mod bn254 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "rsa2048")]
 #[path = "./"]
 pub mod rsa2048 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa2048_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa2048_64.rs"]
     pub mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
 }
 
 #[cfg(feature = "rsa3072")]
 #[path = "./"]
 pub mod rsa3072 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa3072_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa3072_64.rs"]
     pub mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
 }
 
 #[cfg(feature = "rsa4096")]
 #[path = "./"]
 pub mod rsa4096 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa4096_32.rs"]
     mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa4096_64.rs"]
     mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
-}
\ No newline at end of file
+}
diff --git a/src/mpin.rs b/src/mpin.rs
index ba272d1..425d03e 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -20,21 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::Big;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp2::ECP2;
-use super::fp4::FP4;
 use super::fp12::FP12;
-use super::big::Big;
+use super::fp4::FP4;
 use super::pair;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-
+use rand::RAND;
 
 /* MPIN API Functions */
 
@@ -196,8 +195,8 @@ pub fn today() -> usize {
 fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
     let mut x = Big::new_copy(u);
-    let mut p = Big::new_ints(&rom::MODULUS);
-    x.rmod(&mut p);
+    let p = Big::new_ints(&rom::MODULUS);
+    x.rmod(&p);
     loop {
         P = ECP::new_bigint(&x, cb);
         if !P.is_infinity() {
@@ -260,8 +259,8 @@ pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     let mut su = rng.getbyte() as isize;
     su %= 2;
 
-    let mut W = emap(&mut u, su);
-    P.sub(&mut W);
+    let W = emap(&u, su);
+    P.sub(&W);
     let sv = P.gets();
     let rn = unmap(&mut v, &mut P);
     let mut m = rng.getbyte() as isize;
@@ -299,9 +298,9 @@ pub fn decoding(d: &mut [u8]) -> isize {
 
     let su = (d[0] & 1) as isize;
     let sv = ((d[0] >> 1) & 1) as isize;
-    let mut W = emap(&mut u, su);
-    let mut P = emap(&mut v, sv);
-    P.add(&mut W);
+    let W = emap(&u, su);
+    let mut P = emap(&v, sv);
+    P.add(&W);
     u = P.getx();
     v = P.gety();
     d[0] = 0x04;
@@ -321,13 +320,13 @@ pub fn decoding(d: &mut [u8]) -> isize {
 #[allow(non_snake_case)]
 pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
     let mut P = ECP::frombytes(&r1);
-    let mut Q = ECP::frombytes(&r2);
+    let Q = ECP::frombytes(&r2);
 
     if P.is_infinity() || Q.is_infinity() {
         return INVALID_POINT;
     }
 
-    P.add(&mut Q);
+    P.add(&Q);
 
     P.tobytes(r, false);
     return 0;
@@ -337,13 +336,13 @@ pub fn recombine_g1(r1: &[u8], r2: &[u8], r: &mut [u8]) -> isize {
 #[allow(non_snake_case)]
 pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
     let mut P = ECP2::frombytes(&w1);
-    let mut Q = ECP2::frombytes(&w2);
+    let Q = ECP2::frombytes(&w2);
 
     if P.is_infinity() || Q.is_infinity() {
         return INVALID_POINT;
     }
 
-    P.add(&mut Q);
+    P.add(&Q);
 
     P.tobytes(w);
     return 0;
@@ -362,8 +361,8 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP2::generator();
 
-    let mut sc = Big::frombytes(s);
-    Q = pair::g2mul(&mut Q, &mut sc);
+    let sc = Big::frombytes(s);
+    Q = pair::g2mul(&Q, &sc);
     Q.tobytes(sst);
     return 0;
 }
@@ -391,7 +390,7 @@ pub fn get_g1_multiple(
     } else {
         sx = Big::frombytes(x);
     }
-    let mut P: ECP;
+    let P: ECP;
 
     if typ == 0 {
         P = ECP::frombytes(g);
@@ -402,7 +401,7 @@ pub fn get_g1_multiple(
         P = ECP::mapit(g)
     }
 
-    pair::g1mul(&mut P, &mut sx).tobytes(w, false);
+    pair::g1mul(&P, &mut sx).tobytes(w, false);
     return 0;
 }
 
@@ -437,7 +436,7 @@ pub fn extract_factor(
     let mut R = ECP::mapit(&h);
 
     R = R.pinmul(factor, facbits);
-    P.sub(&mut R);
+    P.sub(&R);
 
     P.tobytes(token, false);
 
@@ -463,7 +462,7 @@ pub fn restore_factor(
     let mut R = ECP::mapit(&h);
 
     R = R.pinmul(factor, facbits);
-    P.add(&mut R);
+    P.add(&R);
 
     P.tobytes(token, false);
 
@@ -499,10 +498,10 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     const RM: usize = big::MODBYTES as usize;
     let mut h: [u8; RM] = [0; RM];
     hashit(sha, date, cid, &mut h);
-    let mut P = ECP::mapit(&h);
+    let P = ECP::mapit(&h);
 
     let mut sc = Big::frombytes(s);
-    pair::g1mul(&mut P, &mut sc).tobytes(ctt, false);
+    pair::g1mul(&P, &mut sc).tobytes(ctt, false);
     return 0;
 }
 
@@ -544,7 +543,7 @@ pub fn client_1(
     }
 
     let mut W = P.pinmul((pin as i32) % MAXPIN, PBLEN);
-    T.add(&mut W);
+    T.add(&W);
     if date != 0 {
         if let Some(rpermit) = permit {
             W = ECP::frombytes(&rpermit);
@@ -552,25 +551,25 @@ pub fn client_1(
         if W.is_infinity() {
             return INVALID_POINT;
         }
-        T.add(&mut W);
+        T.add(&W);
         let mut h2: [u8; RM] = [0; RM];
         hashit(sha, date, &h, &mut h2);
         W = ECP::mapit(&h2);
         if let Some(mut rxid) = xid {
-            P = pair::g1mul(&mut P, &mut sx);
+            P = pair::g1mul(&P, &mut sx);
             P.tobytes(&mut rxid, false);
-            W = pair::g1mul(&mut W, &mut sx);
-            P.add(&mut W);
+            W = pair::g1mul(&W, &mut sx);
+            P.add(&W);
         } else {
-            P.add(&mut W);
-            P = pair::g1mul(&mut P, &mut sx);
+            P.add(&W);
+            P = pair::g1mul(&P, &mut sx);
         }
         if let Some(mut rxcid) = xcid {
             P.tobytes(&mut rxcid, false)
         }
     } else {
         if let Some(mut rxid) = xid {
-            P = pair::g1mul(&mut P, &mut sx);
+            P = pair::g1mul(&P, &mut sx);
             P.tobytes(&mut rxid, false);
         }
     }
@@ -593,8 +592,8 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
     if date != 0 {
         let mut h2: [u8; RM] = [0; RM];
         hashit(sha, date, &h, &mut h2);
-        let mut R = ECP::mapit(&h2);
-        P.add(&mut R);
+        let R = ECP::mapit(&h2);
+        P.add(&R);
         if let Some(rhtid) = htid {
             P.tobytes(rhtid, false);
         }
@@ -604,7 +603,7 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
 /* Implement step 2 on client side of MPin protocol */
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
-    let mut r = Big::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
     let mut P = ECP::frombytes(sec);
     if P.is_infinity() {
         return INVALID_POINT;
@@ -613,9 +612,9 @@ pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
     let mut px = Big::frombytes(x);
     let py = Big::frombytes(y);
     px.add(&py);
-    px.rmod(&mut r);
+    px.rmod(&r);
 
-    P = pair::g1mul(&mut P, &mut px);
+    P = pair::g1mul(&P, &mut px);
     P.neg();
     P.tobytes(sec, false);
 
@@ -638,8 +637,8 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
     hashit(sha, timevalue, xcid, &mut h);
 
     let mut sy = Big::frombytes(&h);
-    let mut q = Big::new_ints(&rom::CURVE_ORDER);
-    sy.rmod(&mut q);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
+    sy.rmod(&q);
     sy.tobytes(y);
 }
 
@@ -698,8 +697,8 @@ pub fn server_2(
         return INVALID_POINT;
     }
 
-    P = pair::g1mul(&mut P, &mut sy);
-    P.add(&mut R);
+    P = pair::g1mul(&P, &mut sy);
+    P.add(&R);
     R = ECP::frombytes(&msec);
     if R.is_infinity() {
         return INVALID_POINT;
@@ -724,8 +723,8 @@ pub fn server_2(
                         if R.is_infinity() {
                             return INVALID_POINT;
                         }
-                        P = pair::g1mul(&mut P, &mut sy);
-                        P.add(&mut R); //P.affine();
+                        P = pair::g1mul(&P, &mut sy);
+                        P.add(&R); //P.affine();
                     }
                     g = pair::ate(&Q, &P);
                     g = pair::fexp(&g);
@@ -760,7 +759,7 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
     let mut i: usize;
     for _ in 0..TRAP {
         i = (t.geta().geta().geta().lastbits(20) % (TS as isize)) as usize;
-        t.mul(&mut table[i]);
+        t.mul(&table[i]);
         dn += distance[i];
     }
     gf.copy(&t);
@@ -774,13 +773,13 @@ pub fn kangaroo(e: &[u8], f: &[u8]) -> isize {
             break;
         }
         i = (ge.geta().geta().geta().lastbits(20) % (TS as isize)) as usize;
-        ge.mul(&mut table[i]);
+        ge.mul(&table[i]);
         dm += distance[i];
-        if ge.equals(&mut t) {
+        if ge.equals(&t) {
             res = dm - dn;
             break;
         }
-        if ge.equals(&mut gf) {
+        if ge.equals(&gf) {
             res = dn - dm;
             break;
         }
@@ -873,17 +872,17 @@ pub fn client_key(
         return INVALID_POINT;
     }
 
-    W = pair::g1mul(&mut W, &mut x);
+    W = pair::g1mul(&W, &mut x);
 
-    let mut r = Big::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     z.add(&h); //new
-    z.rmod(&mut r);
+    z.rmod(&r);
 
     g2.pinpow(pin as i32, PBLEN);
-    g1.mul(&mut g2);
+    g1.mul(&g2);
 
-    let mut c = g1.compow(&z, &mut r);
+    let mut c = g1.compow(&z, &r);
 
     hash(sha, &mut c, &mut W, ck);
 
@@ -930,10 +929,10 @@ pub fn server_key(
 
     let mut w = Big::frombytes(&w);
     let mut h = Big::frombytes(&h);
-    A = pair::g1mul(&mut A, &mut h); // new
-    R.add(&mut A);
+    A = pair::g1mul(&A, &mut h); // new
+    R.add(&A);
 
-    U = pair::g1mul(&mut U, &mut w);
+    U = pair::g1mul(&U, &mut w);
     let mut g = pair::ate(&sQ, &R);
     g = pair::fexp(&g);
 
diff --git a/src/mpin192.rs b/src/mpin192.rs
index e133dcd..63970d1 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -20,21 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::Big;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp4::ECP4;
-use super::fp8::FP8;
 use super::fp24::FP24;
-use super::big::Big;
+use super::fp8::FP8;
 use super::pair192;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-
+use rand::RAND;
 
 /* MPIN API Functions */
 
diff --git a/src/mpin256.rs b/src/mpin256.rs
index 4892ff5..5f9cee9 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -20,20 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::Big;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp8::ECP8;
 use super::fp16::FP16;
 use super::fp48::FP48;
-use super::big::Big;
 use super::pair256;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
+use rand::RAND;
 
 /* MPIN API Functions */
 
diff --git a/src/nhs.rs b/src/nhs.rs
index 7f2f605..dda49b0 100644
--- a/src/nhs.rs
+++ b/src/nhs.rs
@@ -313,7 +313,7 @@ fn encode(key: &[u8], poly: &mut [i32]) {
         let mut kj = key[j];
         j += 1;
         for _ in 0..8 {
-            let b = (kj & 1) as i32;
+            let b = i32::from(kj & 1);
             poly[i] = b * q2;
             poly[i + 256] = b * q2;
             poly[i + 512] = b * q2;
@@ -359,13 +359,13 @@ fn parse(seed: &[u8], poly: &mut [i32]) {
 
     let mut j = 0;
     for i in 0..DEGREE {
-        let mut n = (hash[j] & 0x7f) as i32;
+        let mut n = i32::from(hash[j] & 0x7f);
         n <<= 8;
-        n += (hash[j + 1]) as i32;
+        n += i32::from(hash[j + 1]);
         n <<= 8;
-        n += (hash[j + 2]) as i32;
+        n += i32::from(hash[j + 2]);
         n <<= 8;
-        n += (hash[j + 3]) as i32;
+        n += i32::from(hash[j + 3]);
         j += 4;
         poly[i] = nres(n);
         //poly[i]=modmul(n,ONE); // reduce 31-bit random number mod q
diff --git a/src/pair.rs b/src/pair.rs
index b85efaa..36c9045 100644
--- a/src/pair.rs
+++ b/src/pair.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::Big;
+use super::dbig::DBig;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp2::ECP2;
-use super::fp4::FP4;
+use super::fp::FP;
 use super::fp12;
 use super::fp12::FP12;
-use super::big::Big;
-use super::dbig::DBig;
-use super::ecp;
+use super::fp2::FP2;
+use super::fp4::FP4;
 use super::rom;
-use types::{SexticTwist, CurvePairingType, SignOfX};
+use types::{CurvePairingType, SexticTwist, SignOfX};
 
 #[allow(non_snake_case)]
 fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
@@ -56,10 +55,10 @@ fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
 
     let sb = 3 * rom::CURVE_B_I;
     zz.imul(sb);
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         zz.div_ip2();
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         zz.mul_ip();
         zz.dbl();
         yz.mul_ip();
@@ -73,15 +72,15 @@ fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
     zz.norm(); // 3b.Z^2-Y^2
 
     a.copy(&FP4::new_fp2s(&yz, &zz)); // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP4::new_fp2(&xx)); // L(0,1) | L(0,0) | L(1,0)
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP4::new_fp2(&xx));
         c.times_i();
     }
     A.dbl();
-    let mut res= FP12::new_fp4s(&a, &b, &c);
+    let mut res = FP12::new_fp4s(&a, &b, &c);
     res.settype(fp12::SPARSER);
     return res;
 }
@@ -107,7 +106,7 @@ fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
 
     t1.copy(&x1); // T1=X1-Z1.X2
     x1.pmul(qy); // X1=(X1-Z1.X2).Ys
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         x1.mul_ip();
         x1.norm();
     }
@@ -123,27 +122,27 @@ fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
     y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
 
     a.copy(&FP4::new_fp2s(&x1, &t2)); // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP4::new_fp2(&y1));
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP4::new_fp2(&y1));
         c.times_i();
     }
 
     A.add(B);
-    let mut res= FP12::new_fp4s(&a, &b, &c);
+    let mut res = FP12::new_fp4s(&a, &b, &c);
     res.settype(fp12::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+fn lbits(n3: &mut Big, n: &mut Big) -> usize {
     n.copy(&Big::new_ints(&rom::CURVE_BNX));
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
         n.pmul(6);
-        if ecp::SIGN_OF_X==SignOfX::POSITIVEX {
+        if ecp::SIGN_OF_X == SignOfX::PositiveX {
             n.inc(2);
         } else {
             n.dec(2);
@@ -159,18 +158,18 @@ fn lbits(n3: &mut Big,n: &mut Big) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP12; rom::ATE_BITS] {
     let r: [FP12; rom::ATE_BITS] = [FP12::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP12]) -> FP12 {
-    let mut res=FP12::new_int(1);
+pub fn miller(r: &[FP12]) -> FP12 {
+    let mut res = FP12::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -179,14 +178,13 @@ pub fn miller(r:&[FP12]) -> FP12 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
+pub fn another(r: &mut [FP12], P1: &ECP2, Q1: &ECP) {
     let mut f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
     let mut n = Big::new();
     let mut n3 = Big::new();
     let mut K = ECP2::new();
 
-
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP2::new();
     P.copy(P1);
     P.affine();
@@ -194,8 +192,8 @@ pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
     Q.copy(Q1);
     Q.affine();
 
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
-        if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f.inverse();
             f.norm();
         }
@@ -210,36 +208,36 @@ pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
     }
 
-/* R-ate fixup required for BN curves */
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
-        if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    /* R-ate fixup required for BN curves */
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             A.neg();
         }
         K.copy(&P);
         K.frob(&f);
-        let mut lv=lineadd(&mut A,&K,&qx,&qy);
+        let mut lv = lineadd(&mut A, &K, &qx, &qy);
         K.frob(&f);
         K.neg();
-        let lv2=lineadd(&mut A,&K,&qx,&qy);
+        let lv2 = lineadd(&mut A, &K, &qx, &qy);
         lv.smul(&lv2);
-	r[0].ssmul(&lv);
+        r[0].ssmul(&lv);
     }
 }
 
@@ -251,8 +249,8 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
     let mut n3 = Big::new();
     let mut K = ECP2::new();
 
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f.inverse();
             f.norm();
         }
@@ -275,7 +273,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -292,14 +290,14 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
         r.ssmul(&lv);
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
     /* R-ate fixup required for BN curves */
 
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             A.neg();
         }
 
@@ -310,7 +308,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         let lv2 = lineadd(&mut A, &K, &qx, &qy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
     }
 
@@ -325,8 +323,8 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
     let mut n3 = Big::new();
     let mut K = ECP2::new();
 
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f.inverse();
             f.norm();
         }
@@ -365,36 +363,36 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
     NR.copy(&R);
     NR.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
-    /* R-ate fixup */
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    // R-ate fixup
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             A.neg();
             B.neg();
         }
@@ -405,7 +403,7 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         let mut lv2 = lineadd(&mut A, &K, &qx, &qy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
 
         K.copy(&R);
@@ -415,21 +413,20 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         lv2 = lineadd(&mut B, &K, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
-
     }
 
     return r;
 }
 
-/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+// final exponentiation - keep separate for multi-pairings and to avoid thrashing stack
 pub fn fexp(m: &FP12) -> FP12 {
     let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
     let mut x = Big::new_ints(&rom::CURVE_BNX);
     let mut r = FP12::new_copy(m);
 
-    /* Easy part of final exp */
+    // Easy part of final exp
     let mut lv = FP12::new_copy(&r);
     lv.inverse();
     r.conj();
@@ -439,13 +436,13 @@ pub fn fexp(m: &FP12) -> FP12 {
     r.frob(&f);
     r.frob(&f);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
 
     /* Hard part of final exp */
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
         lv.copy(&r);
         lv.frob(&f);
         let mut x0 = FP12::new_copy(&lv);
@@ -455,22 +452,22 @@ pub fn fexp(m: &FP12) -> FP12 {
         x0.frob(&f);
         let mut x1 = FP12::new_copy(&r);
         x1.conj();
-        let mut x4 = r.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::POSITIVEX {
+        let mut x4 = r.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::PositiveX {
             x4.conj();
         }
 
         let mut x3 = FP12::new_copy(&x4);
         x3.frob(&f);
 
-        let mut x2 = x4.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::POSITIVEX {
+        let mut x2 = x4.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::PositiveX {
             x2.conj();
         }
         let mut x5 = FP12::new_copy(&x2);
         x5.conj();
-        lv = x2.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::POSITIVEX {
+        lv = x2.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::PositiveX {
             lv.conj();
         }
         x2.frob(&f);
@@ -505,13 +502,13 @@ pub fn fexp(m: &FP12) -> FP12 {
 
         let mut y0 = FP12::new_copy(&r);
         y0.usqr();
-        let mut y1 = y0.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        let mut y1 = y0.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             y1.conj();
         }
         x.fshr(1);
-        let mut y2 = y1.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        let mut y2 = y1.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             y2.conj();
         }
         x.fshl(1);
@@ -522,12 +519,12 @@ pub fn fexp(m: &FP12) -> FP12 {
         y1.conj();
         y1.mul(&y2);
 
-        y2 = y1.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        y2 = y1.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             y2.conj();
         }
-        y3 = y2.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        y3 = y2.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             y3.conj();
         }
         y1.conj();
@@ -541,8 +538,8 @@ pub fn fexp(m: &FP12) -> FP12 {
         y2.frob(&f);
         y1.mul(&y2);
 
-        y2 = y3.pow(&mut x);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        y2 = y3.pow(&x);
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             y2.conj();
         }
         y2.mul(&y0);
@@ -562,7 +559,7 @@ pub fn fexp(m: &FP12) -> FP12 {
 /* GLV method */
 fn glv(e: &Big) -> [Big; 2] {
     let mut u: [Big; 2] = [Big::new(), Big::new()];
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
         let mut t = Big::new();
         let q = Big::new_ints(&rom::CURVE_ORDER);
         let mut v: [Big; 2] = [Big::new(), Big::new()];
@@ -576,7 +573,7 @@ fn glv(e: &Big) -> [Big; 2] {
         for i in 0..2 {
             for j in 0..2 {
                 t = Big::new_ints(&rom::CURVE_SB[j][i]);
-                t = Big::modmul(&mut v[j], &mut t, &q);
+                t = Big::modmul(&v[j], &t, &q);
                 u[i].add(&q);
                 u[i].sub(&t);
                 u[i].rmod(&q);
@@ -599,7 +596,7 @@ fn glv(e: &Big) -> [Big; 2] {
 /* Galbraith & Scott Method */
 pub fn gs(e: &Big) -> [Big; 4] {
     let mut u: [Big; 4] = [Big::new(), Big::new(), Big::new(), Big::new()];
-    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
         let mut t = Big::new();
         let q = Big::new_ints(&rom::CURVE_ORDER);
 
@@ -613,7 +610,7 @@ pub fn gs(e: &Big) -> [Big; 4] {
         for i in 0..4 {
             for j in 0..4 {
                 t = Big::new_ints(&rom::CURVE_BB[j][i]);
-                t = Big::modmul(&mut v[j], &mut t, &q);
+                t = Big::modmul(&v[j], &t, &q);
                 u[i].add(&q);
                 u[i].sub(&t);
                 u[i].rmod(&q);
@@ -629,11 +626,11 @@ pub fn gs(e: &Big) -> [Big; 4] {
             w.div(&x);
         }
         u[3].copy(&w);
-        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+        if ecp::SIGN_OF_X == SignOfX::NegativeX {
             let mut t = Big::new();
-            t.copy(&Big::modneg(&mut u[1], &q));
+            t.copy(&Big::modneg(&u[1], &q));
             u[1].copy(&t);
-            t.copy(&Big::modneg(&mut u[3], &q));
+            t.copy(&Big::modneg(&u[3], &q));
             u[3].copy(&t);
         }
     }
@@ -655,7 +652,7 @@ pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
         Q.mulx(&mut cru);
 
         let mut np = u[0].nbits();
-        let mut t: Big = Big::modneg(&mut u[0], &q);
+        let mut t: Big = Big::modneg(&u[0], &q);
         let mut nn = t.nbits();
         if nn < np {
             u[0].copy(&t);
@@ -663,7 +660,7 @@ pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
         }
 
         np = u[1].nbits();
-        t = Big::modneg(&mut u[1], &q);
+        t = Big::modneg(&u[1], &q);
         nn = t.nbits();
         if nn < np {
             u[1].copy(&t);
@@ -671,7 +668,7 @@ pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
         }
         u[0].norm();
         u[1].norm();
-        R = R.mul2(&u[0], &mut Q, &u[1]);
+        R = R.mul2(&u[0], &Q, &u[1]);
     } else {
         R = P.mul(e);
     }
@@ -689,7 +686,7 @@ pub fn g2mul(P: &ECP2, e: &Big) -> ECP2 {
         let mut u = gs(e);
         let mut T = ECP2::new();
 
-        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+        if ecp::SEXTIC_TWIST == SexticTwist::MType {
             f.inverse();
             f.norm();
         }
@@ -703,7 +700,7 @@ pub fn g2mul(P: &ECP2, e: &Big) -> ECP2 {
         }
         for i in 0..4 {
             let np = u[i].nbits();
-            t.copy(&Big::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
@@ -739,7 +736,7 @@ pub fn gtpow(d: &FP12, e: &Big) -> FP12 {
         }
         for i in 0..4 {
             let np = u[i].nbits();
-            t.copy(&Big::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
@@ -747,7 +744,7 @@ pub fn gtpow(d: &FP12, e: &Big) -> FP12 {
             }
             u[i].norm();
         }
-        r.copy(&FP12::pow4(&mut g, &u));
+        r.copy(&FP12::pow4(&g, &u));
     } else {
         r.copy(&d.pow(e));
     }
diff --git a/src/pair192.rs b/src/pair192.rs
index a7c2993..84a9f03 100644
--- a/src/pair192.rs
+++ b/src/pair192.rs
@@ -17,17 +17,16 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::Big;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp4::ECP4;
-use super::fp4::FP4;
-use super::fp8::FP8;
+use super::fp::FP;
+use super::fp2::FP2;
 use super::fp24;
 use super::fp24::FP24;
-use super::big::Big;
-use super::ecp;
+use super::fp4::FP4;
+use super::fp8::FP8;
 use super::rom;
 use types::{SexticTwist, SignOfX};
 
@@ -56,10 +55,10 @@ fn linedbl(A: &mut ECP4, qx: &FP, qy: &FP) -> FP24 {
 
     let sb = 3 * rom::CURVE_B_I;
     zz.imul(sb);
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         zz.div_2i();
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         zz.times_i();
         zz.dbl();
         yz.times_i();
@@ -72,15 +71,15 @@ fn linedbl(A: &mut ECP4, qx: &FP, qy: &FP) -> FP24 {
     zz.norm(); // 3b.Z^2-Y^2
 
     a.copy(&FP8::new_fp4s(&yz, &zz)); // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP8::new_fp4(&xx)); // L(0,1) | L(0,0) | L(1,0)
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP8::new_fp4(&xx));
         c.times_i();
     }
     A.dbl();
-    let mut res= FP24::new_fp8s(&a, &b, &c);
+    let mut res = FP24::new_fp8s(&a, &b, &c);
     res.settype(fp24::SPARSER);
     return res;
 }
@@ -106,7 +105,7 @@ fn lineadd(A: &mut ECP4, B: &ECP4, qx: &FP, qy: &FP) -> FP24 {
 
     t1.copy(&x1); // T1=X1-Z1.X2
     x1.qmul(qy); // X1=(X1-Z1.X2).Ys
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         x1.times_i();
     }
 
@@ -121,23 +120,23 @@ fn lineadd(A: &mut ECP4, B: &ECP4, qx: &FP, qy: &FP) -> FP24 {
     y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
 
     a.copy(&FP8::new_fp4s(&x1, &t2)); // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP8::new_fp4(&y1));
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP8::new_fp4(&y1));
         c.times_i();
     }
 
     A.add(B);
-    let mut res= FP24::new_fp8s(&a, &b, &c);
+    let mut res = FP24::new_fp8s(&a, &b, &c);
     res.settype(fp24::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+fn lbits(n3: &mut Big, n: &mut Big) -> usize {
     n.copy(&Big::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
@@ -148,18 +147,18 @@ fn lbits(n3: &mut Big,n: &mut Big) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP24; rom::ATE_BITS] {
     let r: [FP24; rom::ATE_BITS] = [FP24::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP24]) -> FP24 {
-    let mut res=FP24::new_int(1);
+pub fn miller(r: &[FP24]) -> FP24 {
+    let mut res = FP24::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -168,11 +167,11 @@ pub fn miller(r:&[FP24]) -> FP24 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
+pub fn another(r: &mut [FP24], P1: &ECP4, Q1: &ECP) {
     let mut n = Big::new();
     let mut n3 = Big::new();
 
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP4::new();
     P.copy(P1);
     P.affine();
@@ -189,18 +188,18 @@ pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
@@ -231,7 +230,7 @@ pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -250,7 +249,7 @@ pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
         r.ssmul(&lv);
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
@@ -296,30 +295,30 @@ pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) -> FP24 {
     NR.copy(&R);
     NR.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
@@ -341,10 +340,10 @@ pub fn fexp(m: &FP24) -> FP24 {
     lv.copy(&r);
     r.frob(&f, 4);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
@@ -356,7 +355,7 @@ pub fn fexp(m: &FP24) -> FP24 {
     let mut t2 = t1.pow(&mut x);
     x.fshl(1);
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
     let mut t3 = FP24::new_copy(&t1);
@@ -368,7 +367,7 @@ pub fn fexp(m: &FP24) -> FP24 {
     let mut t4 = t3.pow(&mut x);
     let mut t5 = t4.pow(&mut x);
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t3.conj();
         t5.conj();
     }
@@ -378,7 +377,7 @@ pub fn fexp(m: &FP24) -> FP24 {
     t3.mul(&t4);
 
     let mut t6 = t5.pow(&mut x);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t6.conj();
     }
 
@@ -396,7 +395,7 @@ pub fn fexp(m: &FP24) -> FP24 {
     t5.copy(&t6.pow(&mut x));
     t6.copy(&t5.pow(&mut x));
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t5.conj();
     }
 
@@ -409,7 +408,7 @@ pub fn fexp(m: &FP24) -> FP24 {
     t3.mul(&t0);
     t5.copy(&t6.pow(&mut x));
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t5.conj();
     }
     t2.frob(&f, 7);
@@ -463,7 +462,7 @@ pub fn gs(e: &Big) -> [Big; 8] {
         w.div(&x);
     }
     u[7].copy(&w);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         let mut t = Big::new();
         t.copy(&Big::modneg(&mut u[1], &q));
         u[1].copy(&t);
diff --git a/src/pair256.rs b/src/pair256.rs
index f25676c..c9b073e 100644
--- a/src/pair256.rs
+++ b/src/pair256.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::Big;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp8::ECP8;
-use super::fp8::FP8;
+use super::fp::FP;
 use super::fp16::FP16;
+use super::fp2::FP2;
 use super::fp48;
 use super::fp48::FP48;
-use super::big::Big;
-use super::ecp;
+use super::fp8::FP8;
 use super::rom;
-use types::{SignOfX, SexticTwist};
+use types::{SexticTwist, SignOfX};
 
 #[allow(non_snake_case)]
 fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
@@ -56,10 +55,10 @@ fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
 
     let sb = 3 * rom::CURVE_B_I;
     zz.imul(sb);
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         zz.div_2i();
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         zz.times_i();
         zz.dbl();
         yz.times_i();
@@ -72,15 +71,15 @@ fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
     zz.norm(); // 3b.Z^2-Y^2
 
     a.copy(&FP16::new_fp8s(&yz, &zz)); // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP16::new_fp8(&xx)); // L(0,1) | L(0,0) | L(1,0)
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP16::new_fp8(&xx));
         c.times_i();
     }
     A.dbl();
-    let mut res= FP48::new_fp16s(&a, &b, &c);
+    let mut res = FP48::new_fp16s(&a, &b, &c);
     res.settype(fp48::SPARSER);
     return res;
 }
@@ -106,7 +105,7 @@ fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
 
     t1.copy(&x1); // T1=X1-Z1.X2
     x1.tmul(qy); // X1=(X1-Z1.X2).Ys
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         x1.times_i();
     }
 
@@ -121,23 +120,23 @@ fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
     y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
 
     a.copy(&FP16::new_fp8s(&x1, &t2)); // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
-    if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::DType {
         b.copy(&FP16::new_fp8(&y1));
     }
-    if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+    if ecp::SEXTIC_TWIST == SexticTwist::MType {
         c.copy(&FP16::new_fp8(&y1));
         c.times_i();
     }
 
     A.add(B);
-    let mut res= FP48::new_fp16s(&a, &b, &c);
+    let mut res = FP48::new_fp16s(&a, &b, &c);
     res.settype(fp48::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+fn lbits(n3: &mut Big, n: &mut Big) -> usize {
     n.copy(&Big::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
@@ -148,18 +147,18 @@ fn lbits(n3: &mut Big,n: &mut Big) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP48; rom::ATE_BITS] {
     let r: [FP48; rom::ATE_BITS] = [FP48::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP48]) -> FP48 {
-    let mut res=FP48::new_int(1);
+pub fn miller(r: &[FP48]) -> FP48 {
+    let mut res = FP48::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -168,11 +167,11 @@ pub fn miller(r:&[FP48]) -> FP48 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
+pub fn another(r: &mut [FP48], P1: &ECP8, Q1: &ECP) {
     let mut n = Big::new();
     let mut n3 = Big::new();
 
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP8::new();
     P.copy(P1);
     P.affine();
@@ -189,18 +188,18 @@ pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
@@ -231,7 +230,7 @@ pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -248,7 +247,7 @@ pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
         r.ssmul(&lv);
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
@@ -294,30 +293,30 @@ pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
     NR.copy(&R);
     NR.neg();
 
-     let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         r.conj();
     }
 
@@ -339,10 +338,10 @@ pub fn fexp(m: &FP48) -> FP48 {
     lv.copy(&r);
     r.frob(&f, 8);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
@@ -354,7 +353,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     let mut t2 = t1.pow(&mut x);
     x.fshl(1);
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -367,7 +366,7 @@ pub fn fexp(m: &FP48) -> FP48 {
 
     t1.copy(&t2.pow(&mut x));
 
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
     t3.copy(&t1);
@@ -375,7 +374,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -384,7 +383,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -393,7 +392,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -402,7 +401,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -411,7 +410,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -420,7 +419,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -429,7 +428,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -441,7 +440,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -450,7 +449,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -459,7 +458,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -468,7 +467,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -477,7 +476,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -486,7 +485,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -495,7 +494,7 @@ pub fn fexp(m: &FP48) -> FP48 {
     r.mul(&t3);
     lv.copy(&t1.pow(&mut x));
     t1.copy(&lv);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         t1.conj();
     }
 
@@ -555,7 +554,7 @@ pub fn gs(e: &Big) -> [Big; 16] {
         w.div(&x);
     }
     u[15].copy(&w);
-    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NegativeX {
         let mut t = Big::new();
         t.copy(&Big::modneg(&mut u[1], &q));
         u[1].copy(&t);
diff --git a/src/rand.rs b/src/rand.rs
index 34c264d..1ef961a 100644
--- a/src/rand.rs
+++ b/src/rand.rs
@@ -158,7 +158,7 @@ impl RAND {
         if self.pool_ptr >= 32 {
             self.fill_pool()
         }
-        return (r & 0xff) as u8;
+        return u8::from(r);
     }
 }
 
diff --git a/src/roms/rom_anssi_32.rs b/src/roms/rom_anssi_32.rs
index 403fb04..3523fa4 100644
--- a/src/roms/rom_anssi_32.rs
+++ b/src/roms/rom_anssi_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use anssi::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use anssi::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // anssi Modulus
@@ -61,13 +61,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_anssi_64.rs b/src/roms/rom_anssi_64.rs
index b0add0f..1c32ea1 100644
--- a/src/roms/rom_anssi_64.rs
+++ b/src/roms/rom_anssi_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use anssi::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use anssi::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // anssi Modulus
@@ -79,13 +79,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls24_32.rs b/src/roms/rom_bls24_32.rs
index 72afe58..4a41136 100644
--- a/src/roms/rom_bls24_32.rs
+++ b/src/roms/rom_bls24_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls24::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls24::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls24 Modulus
@@ -228,13 +228,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 479;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 49;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_bls24_64.rs b/src/roms/rom_bls24_64.rs
index 0c500da..8324005 100644
--- a/src/roms/rom_bls24_64.rs
+++ b/src/roms/rom_bls24_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls24::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls24::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // bls24 Modulus
@@ -276,13 +276,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 479;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 25;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 49;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_bls381_32.rs b/src/roms/rom_bls381_32.rs
index 1ba0fe5..e282e9d 100644
--- a/src/roms/rom_bls381_32.rs
+++ b/src/roms/rom_bls381_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls381::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls381::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls381 Modulus
@@ -197,13 +197,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 381;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls381_64.rs b/src/roms/rom_bls381_64.rs
index 08df12c..4d95fdb 100644
--- a/src/roms/rom_bls381_64.rs
+++ b/src/roms/rom_bls381_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls381::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls381::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // bls381 Modulus
@@ -199,13 +199,13 @@ pub const BASEBITS: usize = 58;
 
 pub const MODBITS: usize = 381;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 25;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls383_32.rs b/src/roms/rom_bls383_32.rs
index 0ccb42d..b61a4dd 100644
--- a/src/roms/rom_bls383_32.rs
+++ b/src/roms/rom_bls383_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls383::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls383::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 pub const MODULUS: [Chunk; NLEN] = [
@@ -195,13 +195,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 383;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls383_64.rs b/src/roms/rom_bls383_64.rs
index 71bef66..af4d009 100644
--- a/src/roms/rom_bls383_64.rs
+++ b/src/roms/rom_bls383_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls383::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls383::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 pub const MODULUS: [Chunk; NLEN] = [
@@ -206,13 +206,13 @@ pub const BASEBITS: usize = 58;
 
 pub const MODBITS: usize = 383;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 23;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls461_32.rs b/src/roms/rom_bls461_32.rs
index c452a9f..65abfd5 100644
--- a/src/roms/rom_bls461_32.rs
+++ b/src/roms/rom_bls461_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls461::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls461::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // bls461 Modulus
@@ -197,13 +197,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 461;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 78;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls461_64.rs b/src/roms/rom_bls461_64.rs
index 500ef04..e0fb356 100644
--- a/src/roms/rom_bls461_64.rs
+++ b/src/roms/rom_bls461_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls461::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls461::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // bls461 Modulus
@@ -220,13 +220,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 461;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 19;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 78;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bls48_32.rs b/src/roms/rom_bls48_32.rs
index 83517a8..13fafe1 100644
--- a/src/roms/rom_bls48_32.rs
+++ b/src/roms/rom_bls48_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls48::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls48::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls48 Modulus
@@ -297,13 +297,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 556;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 32;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_bls48_64.rs b/src/roms/rom_bls48_64.rs
index 129c776..3b63ce7 100644
--- a/src/roms/rom_bls48_64.rs
+++ b/src/roms/rom_bls48_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls48::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls48::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // bls48 Modulus
@@ -389,13 +389,13 @@ pub const BASEBITS: usize = 58;
 
 pub const MODBITS: usize = 556;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BLS;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 32;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_bn254CX_32.rs b/src/roms/rom_bn254CX_32.rs
index e1cff0d..a6e7ef8 100644
--- a/src/roms/rom_bn254CX_32.rs
+++ b/src/roms/rom_bn254CX_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254CX::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254CX::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // bn254CX Modulus
@@ -171,13 +171,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 254;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::D_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::DType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bn254CX_64.rs b/src/roms/rom_bn254CX_64.rs
index 7f6d274..75d4c28 100644
--- a/src/roms/rom_bn254CX_64.rs
+++ b/src/roms/rom_bn254CX_64.rs
@@ -17,10 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254CX::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
-
+use bn254CX::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // bn254CX Modulus
@@ -230,13 +229,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 254;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 64;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::D_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::DType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bn254_32.rs b/src/roms/rom_bn254_32.rs
index c9ae5ec..1899c4a 100644
--- a/src/roms/rom_bn254_32.rs
+++ b/src/roms/rom_bn254_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 pub const MODULUS: [Chunk; NLEN] = [
@@ -159,13 +159,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 254;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::D_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::DType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_bn254_64.rs b/src/roms/rom_bn254_64.rs
index f61b542..08502f3 100644
--- a/src/roms/rom_bn254_64.rs
+++ b/src/roms/rom_bn254_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // BN254 Modulus
 // Base Bits= 56
@@ -196,13 +196,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 254;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 26;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::D_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::DType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
-pub const AESKEY: usize = 16;
\ No newline at end of file
+pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_brainpool_32.rs b/src/roms/rom_brainpool_32.rs
index b788632..17b1268 100644
--- a/src/roms/rom_brainpool_32.rs
+++ b/src/roms/rom_brainpool_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Note that the original curve has been transformed to an isomorphic curve with A=-3 */
 
-use brainpool::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use brainpool::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // brainpool Modulus
@@ -62,13 +62,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_brainpool_64.rs b/src/roms/rom_brainpool_64.rs
index 8191561..89a445e 100644
--- a/src/roms/rom_brainpool_64.rs
+++ b/src/roms/rom_brainpool_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Note that the original curve has been transformed to an isomorphic curve with A=-3 */
 
-use brainpool::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use brainpool::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // brainpool Modulus
@@ -80,13 +80,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const ATE_BITS: usize = 0;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_c25519_32.rs b/src/roms/rom_c25519_32.rs
index 6da6a05..d07207e 100644
--- a/src/roms/rom_c25519_32.rs
+++ b/src/roms/rom_c25519_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Curve25519 Modulus
@@ -47,13 +47,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 255;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 6;
 
-pub const CURVETYPE: CurveType = CurveType::MONTGOMERY;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Montgomery;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_c25519_64.rs b/src/roms/rom_c25519_64.rs
index 9a8c59f..42b1d70 100644
--- a/src/roms/rom_c25519_64.rs
+++ b/src/roms/rom_c25519_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // Curve25519 Modulus
@@ -49,13 +49,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 255;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 25;
 
-pub const CURVETYPE: CurveType = CurveType::MONTGOMERY;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Montgomery;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_c41417_32.rs b/src/roms/rom_c41417_32.rs
index a8330cb..c471f76 100644
--- a/src/roms/rom_c41417_32.rs
+++ b/src/roms/rom_c41417_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c41417::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c41417::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // c41417 Modulus
@@ -59,13 +59,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 414;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_c41417_64.rs b/src/roms/rom_c41417_64.rs
index 52b51b1..3a2ef58 100644
--- a/src/roms/rom_c41417_64.rs
+++ b/src/roms/rom_c41417_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c41417::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c41417::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // c41417 Modulus
@@ -66,13 +66,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 414;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 6;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_ed25519_32.rs b/src/roms/rom_ed25519_32.rs
index be1d156..c866d50 100644
--- a/src/roms/rom_ed25519_32.rs
+++ b/src/roms/rom_ed25519_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use ed25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use ed25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Curve25519 Modulus
@@ -56,13 +56,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 255;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 6;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_ed25519_64.rs b/src/roms/rom_ed25519_64.rs
index cf23672..a26461b 100644
--- a/src/roms/rom_ed25519_64.rs
+++ b/src/roms/rom_ed25519_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use ed25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use ed25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // Curve25519 Modulus
@@ -67,13 +67,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 255;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 25;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_fp256bn_32.rs b/src/roms/rom_fp256bn_32.rs
index e3cabe1..0f196b0 100644
--- a/src/roms/rom_fp256bn_32.rs
+++ b/src/roms/rom_fp256bn_32.rs
@@ -17,10 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp256bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
-
+use fp256bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 pub const MODULUS: [Chunk; NLEN] = [
@@ -168,13 +167,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_fp256bn_64.rs b/src/roms/rom_fp256bn_64.rs
index bde7639..d1a38b9 100644
--- a/src/roms/rom_fp256bn_64.rs
+++ b/src/roms/rom_fp256bn_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp256bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp256bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // fp256bn Modulus
 // Base Bits= 56
@@ -221,13 +221,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 66;
-pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_fp512bn_32.rs b/src/roms/rom_fp512bn_32.rs
index cdc44af..e18646b 100644
--- a/src/roms/rom_fp512bn_32.rs
+++ b/src/roms/rom_fp512bn_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp512bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp512bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 pub const MODULUS: [Chunk; NLEN] = [
@@ -237,13 +237,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 10;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 130;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_fp512bn_64.rs b/src/roms/rom_fp512bn_64.rs
index 54d85c4..a3e5f57 100644
--- a/src/roms/rom_fp512bn_64.rs
+++ b/src/roms/rom_fp512bn_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp512bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp512bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 pub const MODULUS: [Chunk; NLEN] = [
@@ -470,13 +470,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 28;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::BN;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::M_TYPE;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 130;
-pub const SIGN_OF_X: SignOfX = SignOfX::POSITIVEX;
+pub const SIGN_OF_X: SignOfX = SignOfX::PositiveX;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_goldilocks_32.rs b/src/roms/rom_goldilocks_32.rs
index 5d5f8bb..096ff30 100644
--- a/src/roms/rom_goldilocks_32.rs
+++ b/src/roms/rom_goldilocks_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use goldilocks::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use goldilocks::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Goldilocks modulus
@@ -61,13 +61,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 448;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::GENERALISED_MERSENNE;
+pub const MODTYPE: ModType = ModType::GeneralisedMersenne;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_goldilocks_64.rs b/src/roms/rom_goldilocks_64.rs
index d6cadf1..6547052 100644
--- a/src/roms/rom_goldilocks_64.rs
+++ b/src/roms/rom_goldilocks_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use goldilocks::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use goldilocks::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // Goldilocks modulus
@@ -87,13 +87,13 @@ pub const BASEBITS: usize = 58;
 
 pub const MODBITS: usize = 448;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::GENERALISED_MERSENNE;
+pub const MODTYPE: ModType = ModType::GeneralisedMersenne;
 pub const SH: usize = 16;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_hifive_32.rs b/src/roms/rom_hifive_32.rs
index cfa9f59..01dcb03 100644
--- a/src/roms/rom_hifive_32.rs
+++ b/src/roms/rom_hifive_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use hifive::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use hifive::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
@@ -56,13 +56,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 336;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 12;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_hifive_64.rs b/src/roms/rom_hifive_64.rs
index b2eebb9..f7b5621 100644
--- a/src/roms/rom_hifive_64.rs
+++ b/src/roms/rom_hifive_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use hifive::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use hifive::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 
@@ -65,13 +65,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 336;
 pub const MOD8: usize = 5;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_nist256_32.rs b/src/roms/rom_nist256_32.rs
index 6859da5..12c47f9 100644
--- a/src/roms/rom_nist256_32.rs
+++ b/src/roms/rom_nist256_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use nist256::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist256::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 
@@ -45,8 +45,7 @@ pub const CURVE_B: [Chunk; NLEN] = [
     0xAC635D8, 0x5,
 ];
 pub const CURVE_ORDER: [Chunk; NLEN] = [
-    0xC632551, 0xB9CAC2F, 0x79E84F3, 0xFAADA71, 0xFFFBCE6, 0xFFFFFFF, 0xFFFFFF, 0x0, 0xFFFFFFF,
-    0xF,
+    0xC632551, 0xB9CAC2F, 0x79E84F3, 0xFAADA71, 0xFFFBCE6, 0xFFFFFFF, 0xFFFFFF, 0x0, 0xFFFFFFF, 0xF,
 ];
 pub const CURVE_GX: [Chunk; NLEN] = [
     0x898C296, 0xA13945D, 0xB33A0F4, 0x7D812DE, 0xF27703, 0xE563A44, 0x7F8BCE6, 0xE12C424,
@@ -62,13 +61,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_nist256_64.rs b/src/roms/rom_nist256_64.rs
index 015bbb3..5da758c 100644
--- a/src/roms/rom_nist256_64.rs
+++ b/src/roms/rom_nist256_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use nist256::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist256::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nist256 modulus
@@ -74,13 +74,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_nist384_32.rs b/src/roms/rom_nist384_32.rs
index 48d7826..2939f30 100644
--- a/src/roms/rom_nist384_32.rs
+++ b/src/roms/rom_nist384_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist384::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist384::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
@@ -64,13 +64,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_nist384_64.rs b/src/roms/rom_nist384_64.rs
index f0f5c69..4654ec6 100644
--- a/src/roms/rom_nist384_64.rs
+++ b/src/roms/rom_nist384_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist384::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist384::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 
@@ -44,7 +44,6 @@ pub const R2MODP: [Chunk; NLEN] = [
 ];
 pub const MCONST: Chunk = 0x100000001;
 
-
 // nist384 Curve
 pub const CURVE_COF_I: isize = 1;
 pub const CURVE_A: isize = -3;
@@ -92,13 +91,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 8;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
diff --git a/src/roms/rom_nist521_32.rs b/src/roms/rom_nist521_32.rs
index 55cbf30..7a74956 100644
--- a/src/roms/rom_nist521_32.rs
+++ b/src/roms/rom_nist521_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist521::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist521::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // nist521 Modulus
@@ -67,13 +67,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 521;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 11;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_nist521_64.rs b/src/roms/rom_nist521_64.rs
index bf241b2..dec3c9c 100644
--- a/src/roms/rom_nist521_64.rs
+++ b/src/roms/rom_nist521_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist521::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist521::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nist521 Modulus
@@ -92,13 +92,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 521;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 19;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_nums256e_32.rs b/src/roms/rom_nums256e_32.rs
index 45506bd..b1d20c3 100644
--- a/src/roms/rom_nums256e_32.rs
+++ b/src/roms/rom_nums256e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
@@ -58,14 +58,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 5;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
-
diff --git a/src/roms/rom_nums256e_64.rs b/src/roms/rom_nums256e_64.rs
index 4382924..b8ac09e 100644
--- a/src/roms/rom_nums256e_64.rs
+++ b/src/roms/rom_nums256e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums256 Modulus
@@ -67,14 +67,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
-
diff --git a/src/roms/rom_nums256w_32.rs b/src/roms/rom_nums256w_32.rs
index b768380..4ffb798 100644
--- a/src/roms/rom_nums256w_32.rs
+++ b/src/roms/rom_nums256w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // nums256 modulus
@@ -54,13 +54,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_nums256w_64.rs b/src/roms/rom_nums256w_64.rs
index 5b5d491..be3b7ff 100644
--- a/src/roms/rom_nums256w_64.rs
+++ b/src/roms/rom_nums256w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums256 Modulus
@@ -66,13 +66,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_nums384e_32.rs b/src/roms/rom_nums384e_32.rs
index eaad1c8..787f4c1 100644
--- a/src/roms/rom_nums384e_32.rs
+++ b/src/roms/rom_nums384e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums384 Modulus
@@ -61,14 +61,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384e_64.rs b/src/roms/rom_nums384e_64.rs
index 08d83c2..a1a4318 100644
--- a/src/roms/rom_nums384e_64.rs
+++ b/src/roms/rom_nums384e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums384 Modulus
@@ -82,14 +82,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 8;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384w_32.rs b/src/roms/rom_nums384w_32.rs
index 92181a6..74d5216 100644
--- a/src/roms/rom_nums384w_32.rs
+++ b/src/roms/rom_nums384w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums384 Modulus
@@ -61,14 +61,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384w_64.rs b/src/roms/rom_nums384w_64.rs
index 3f51d94..bd057e2 100644
--- a/src/roms/rom_nums384w_64.rs
+++ b/src/roms/rom_nums384w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // nums384 Modulus
@@ -81,14 +81,13 @@ pub const BASEBITS: usize = 58;
 
 pub const MODBITS: usize = 384;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 22;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums512e_32.rs b/src/roms/rom_nums512e_32.rs
index 8d53f9f..48ca9ea 100644
--- a/src/roms/rom_nums512e_32.rs
+++ b/src/roms/rom_nums512e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums512 Modulus
@@ -67,13 +67,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 10;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_nums512e_64.rs b/src/roms/rom_nums512e_64.rs
index 298f3cc..f645d85 100644
--- a/src/roms/rom_nums512e_64.rs
+++ b/src/roms/rom_nums512e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nums512 Modulus
@@ -92,13 +92,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 28;
 
-pub const CURVETYPE: CurveType = CurveType::EDWARDS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Edwards;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_nums512w_32.rs b/src/roms/rom_nums512w_32.rs
index 785070c..c787795 100644
--- a/src/roms/rom_nums512w_32.rs
+++ b/src/roms/rom_nums512w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums512 Modulus
@@ -65,13 +65,13 @@ pub const BASEBITS: usize = 29;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 10;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_nums512w_64.rs b/src/roms/rom_nums512w_64.rs
index 6868c87..79ed127 100644
--- a/src/roms/rom_nums512w_64.rs
+++ b/src/roms/rom_nums512w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nums512 Modulus
@@ -82,13 +82,13 @@ pub const BASEBITS: usize = 60;
 
 pub const MODBITS: usize = 512;
 pub const MOD8: usize = 3;
-pub const MODTYPE: ModType = ModType::PSEUDO_MERSENNE;
+pub const MODTYPE: ModType = ModType::PseudoMersenne;
 pub const SH: usize = 28;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 64;
 pub const AESKEY: usize = 32;
diff --git a/src/roms/rom_rsa2048_32.rs b/src/roms/rom_rsa2048_32.rs
index 6dd06a6..29b5a60 100644
--- a/src/roms/rom_rsa2048_32.rs
+++ b/src/roms/rom_rsa2048_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 128;
 pub const BASEBITS: usize = 28;
-pub const FFLEN: usize = 2;
\ No newline at end of file
+pub const FFLEN: usize = 2;
diff --git a/src/roms/rom_rsa2048_64.rs b/src/roms/rom_rsa2048_64.rs
index be3ba0d..4caac22 100644
--- a/src/roms/rom_rsa2048_64.rs
+++ b/src/roms/rom_rsa2048_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 128;
 pub const BASEBITS: usize = 58;
-pub const FFLEN: usize = 2;
\ No newline at end of file
+pub const FFLEN: usize = 2;
diff --git a/src/roms/rom_rsa3072_32.rs b/src/roms/rom_rsa3072_32.rs
index d5622e2..62b929e 100644
--- a/src/roms/rom_rsa3072_32.rs
+++ b/src/roms/rom_rsa3072_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 48;
 pub const BASEBITS: usize = 28;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa3072_64.rs b/src/roms/rom_rsa3072_64.rs
index 4d1ed2b..ef66da7 100644
--- a/src/roms/rom_rsa3072_64.rs
+++ b/src/roms/rom_rsa3072_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 48;
 pub const BASEBITS: usize = 58;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa4096_32.rs b/src/roms/rom_rsa4096_32.rs
index 223cb7d..16ade15 100644
--- a/src/roms/rom_rsa4096_32.rs
+++ b/src/roms/rom_rsa4096_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 64;
 pub const BASEBITS: usize = 29;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa4096_64.rs b/src/roms/rom_rsa4096_64.rs
index 77d3eb6..e8ebfc6 100644
--- a/src/roms/rom_rsa4096_64.rs
+++ b/src/roms/rom_rsa4096_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 64;
 pub const BASEBITS: usize = 60;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_secp256k1_32.rs b/src/roms/rom_secp256k1_32.rs
index 94bbbaa..cb9b32b 100644
--- a/src/roms/rom_secp256k1_32.rs
+++ b/src/roms/rom_secp256k1_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use secp256k1::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use secp256k1::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // secp256k1 modulus
@@ -58,13 +58,13 @@ pub const BASEBITS: usize = 28;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 14;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_secp256k1_64.rs b/src/roms/rom_secp256k1_64.rs
index b22d875..0b100b6 100644
--- a/src/roms/rom_secp256k1_64.rs
+++ b/src/roms/rom_secp256k1_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use secp256k1::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use secp256k1::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 
@@ -69,13 +69,13 @@ pub const BASEBITS: usize = 56;
 
 pub const MODBITS: usize = 256;
 pub const MOD8: usize = 7;
-pub const MODTYPE: ModType = ModType::NOT_SPECIAL;
+pub const MODTYPE: ModType = ModType::NotSpecial;
 pub const SH: usize = 24;
 
-pub const CURVETYPE: CurveType = CurveType::WEIERSTRASS;
-pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::NOT;
-pub const SEXTIC_TWIST: SexticTwist = SexticTwist::NOT;
+pub const CURVETYPE: CurveType = CurveType::Weierstrass;
+pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Not;
+pub const SEXTIC_TWIST: SexticTwist = SexticTwist::Not;
 pub const ATE_BITS: usize = 0;
-pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
+pub const SIGN_OF_X: SignOfX = SignOfX::Not;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
diff --git a/src/sha3.rs b/src/sha3.rs
index eeaf953..710d20e 100644
--- a/src/sha3.rs
+++ b/src/sha3.rs
@@ -162,7 +162,7 @@ impl SHA3 {
         let ind = cnt / 8;
         let i = ind % 5;
         let j = ind / 5;
-        self.s[i][j] ^= ((byt & 0xff) as u64) << (8 * b);
+        self.s[i][j] ^= u64::from(byt) << (8 * b);
         self.length += 1;
         if cnt + 1 == self.rate {
             self.transform();
diff --git a/src/types.rs b/src/types.rs
index ea310d7..9db4257 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,45 +1,44 @@
 #[derive(PartialEq)]
 pub enum ModType {
-    NOT_SPECIAL,
-    PSEUDO_MERSENNE,
-    MONTGOMERY_FRIENDLY,
-    GENERALISED_MERSENNE,
+    NotSpecial,
+    PseudoMersenne,
+    MontgomeryFriendly,
+    GeneralisedMersenne,
 }
 
 #[derive(PartialEq)]
 pub enum CurveType {
-    EDWARDS,
-    WEIERSTRASS,
-    MONTGOMERY,
+    Edwards,
+    Weierstrass,
+    Montgomery,
 }
 
 #[derive(PartialEq)]
 pub enum CurvePairingType {
-    NOT,
-    BN,
-    BLS,
+    Not,
+    Bn,
+    Bls,
 }
 
 #[derive(PartialEq)]
 pub enum SexticTwist {
-    NOT,
-    D_TYPE,
-    M_TYPE,
+    Not,
+    DType,
+    MType,
 }
 impl Into<usize> for SexticTwist {
     fn into(self) -> usize {
         match self {
-            SexticTwist::NOT => 0,
-            SexticTwist::D_TYPE => 0,
-            SexticTwist::M_TYPE => 1,
+            SexticTwist::Not => 0,
+            SexticTwist::DType => 0,
+            SexticTwist::MType => 1,
         }
     }
 }
 
 #[derive(PartialEq)]
 pub enum SignOfX {
-    NOT,
-    POSITIVEX,
-    NEGATIVEX,
+    Not,
+    PositiveX,
+    NegativeX,
 }
-


[incubator-milagro-crypto-rust] 35/44: Cargo fmt

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit cab59142deb620a5fc169d387db6fdfbe5da3b10
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Apr 21 11:15:36 2020 +1000

    Cargo fmt
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/ecp.rs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/ecp.rs b/src/ecp.rs
index 1f1bed2..f75cd07 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -896,7 +896,7 @@ impl ECP {
         a.norm();
         d.norm();
 
-        let mut da  = d.clone();
+        let mut da = d.clone();
         da.mul(&a);
 
         c.norm();
@@ -905,7 +905,7 @@ impl ECP {
         let mut cb = c.clone();
         cb.mul(&b);
 
-        a  = da.clone();
+        a = da.clone();
         a.add(&cb);
         a.norm();
         a.sqr();
@@ -994,7 +994,7 @@ impl ECP {
             W[0] = self.clone();
 
             for i in 1..8 {
-                W[i]  = W[i - 1].clone();
+                W[i] = W[i - 1].clone();
                 W[i].add(&Q);
             }
 
@@ -1067,18 +1067,18 @@ impl ECP {
         let mut S = Q.clone();
         S.dbl();
         let mut C = W[1].clone();
-        W[0]  = C.clone();
+        W[0] = C.clone();
         W[0].sub(&S); // copy to C is stupid Rust thing..
         C = W[2].clone();
-        W[3]  = C.clone();
+        W[3] = C.clone();
         W[3].add(&S);
         let mut T = self.clone();
         T.dbl();
         C = W[1].clone();
-        W[5]  = C.clone();
+        W[5] = C.clone();
         W[5].add(&T);
         C = W[2].clone();
-        W[6]  = C.clone();
+        W[6] = C.clone();
         W[6].add(&T);
         C = W[5].clone();
         W[4] = C.clone();


[incubator-milagro-crypto-rust] 28/44: Remove warnings

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit a3f47db5e7dd8bfde8a8677a854650d02dfe6953
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Mon Mar 30 18:53:52 2020 +1100

    Remove warnings
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/big.rs | 12 ++++++------
 src/ff.rs  | 10 +++++-----
 src/fp.rs  |  2 +-
 src/nhs.rs |  2 +-
 4 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/big.rs b/src/big.rs
index 0af6458..e4eca10 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -30,13 +30,13 @@ pub use super::rom::MODBYTES;
 use std::cmp::Ordering;
 use std::fmt;
 
-pub const NLEN: usize = (1 + ((8 * MODBYTES - 1) / BASEBITS));
+pub const NLEN: usize = 1 + (8 * MODBYTES - 1) / BASEBITS;
 pub const DNLEN: usize = 2 * NLEN;
-pub const BMASK: Chunk = ((1 << BASEBITS) - 1);
-pub const HBITS: usize = (BASEBITS / 2);
-pub const HMASK: Chunk = ((1 << HBITS) - 1);
-pub const NEXCESS: isize = (1 << ((arch::CHUNK) - BASEBITS - 1));
-pub const BIGBITS: usize = (MODBYTES * 8);
+pub const BMASK: Chunk = (1 << BASEBITS) - 1;
+pub const HBITS: usize = BASEBITS / 2;
+pub const HMASK: Chunk = (1 << HBITS) - 1;
+pub const NEXCESS: isize = 1 << (arch::CHUNK - BASEBITS - 1);
+pub const BIGBITS: usize = MODBYTES * 8;
 
 #[derive(Copy)]
 pub struct Big {
diff --git a/src/ff.rs b/src/ff.rs
index 90e7fdf..316c156 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -31,13 +31,13 @@ use super::super::arch::DChunk;
 pub use super::rom::FFLEN;
 //use std::str::SplitWhitespace;
 
-pub const FF_BITS: usize = (big::BIGBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
-pub const HFLEN: usize = (FFLEN / 2); /* Useful for half-size RSA private key operations */
+pub const FF_BITS: usize = big::BIGBITS * FFLEN; /* Finite Field Size in bits - must be 256.2^n */
+pub const HFLEN: usize = FFLEN / 2; /* Useful for half-size RSA private key operations */
 
 pub const P_MBITS: usize = (big::MODBYTES as usize) * 8;
-pub const P_OMASK: Chunk = ((-1) << (P_MBITS % big::BASEBITS));
-pub const P_FEXCESS: Chunk = (1 << (big::BASEBITS * big::NLEN - P_MBITS - 1));
-pub const P_TBITS: usize = (P_MBITS % big::BASEBITS);
+pub const P_OMASK: Chunk = (-1) << (P_MBITS % big::BASEBITS);
+pub const P_FEXCESS: Chunk = 1 << (big::BASEBITS * big::NLEN - P_MBITS - 1);
+pub const P_TBITS: usize = P_MBITS % big::BASEBITS;
 
 pub struct FF {
     v: Vec<Big>,
diff --git a/src/fp.rs b/src/fp.rs
index 45a828c..95cddff 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -54,7 +54,7 @@ pub use super::rom::{MOD8, MODBITS, MODTYPE, SH};
 use std::fmt;
 use std::str::SplitWhitespace;
 
-pub const FEXCESS: i32 = (((1 as i32) << SH) - 1);
+pub const FEXCESS: i32 = ((1 as i32) << SH) - 1;
 pub const OMASK: Chunk = (-1) << (MODBITS % big::BASEBITS);
 pub const TBITS: usize = MODBITS % big::BASEBITS; // Number of active bits in top word
 pub const TMASK: Chunk = (1 << TBITS) - 1;
diff --git a/src/nhs.rs b/src/nhs.rs
index cf0f9c2..9a7f856 100644
--- a/src/nhs.rs
+++ b/src/nhs.rs
@@ -29,7 +29,7 @@ const ND: u32 = 0xF7002FFF; // 1/(R-q) mod R
 const ONE: i32 = 0x2AC8; // R mod q
 const R2MODP: u64 = 0x1620; // R^2 mod q
 
-const DEGREE: usize = (1 << LGN);
+const DEGREE: usize = 1 << LGN;
 const WL: usize = 32;
 
 const INV: i32 = 0xeab;


[incubator-milagro-crypto-rust] 05/44: Formatting of some comments and BIG -> Big

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit a3d3ebdcce80b5db73ac494ff092ac253595e0db
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Aug 7 16:44:25 2019 +1000

    Formatting of some comments and BIG -> Big
---
 src/aes.rs     |  44 +++----
 src/big.rs     | 357 +++++++++++++++++++++++++++++----------------------------
 src/bls.rs     |  29 +++--
 src/bls192.rs  |  29 +++--
 src/bls256.rs  |  29 +++--
 src/dbig.rs    |  80 ++++++-------
 src/ecdh.rs    |  62 +++++-----
 src/ecp.rs     |  66 +++++------
 src/ecp2.rs    |  50 ++++----
 src/ecp4.rs    |  76 ++++++------
 src/ecp8.rs    | 124 ++++++++++----------
 src/ff.rs      |  74 ++++++------
 src/fp.rs      |  80 ++++++-------
 src/fp12.rs    |  78 ++++++-------
 src/fp16.rs    |  28 ++---
 src/fp2.rs     |  28 ++---
 src/fp24.rs    | 110 +++++++++---------
 src/fp4.rs     |  30 ++---
 src/fp48.rs    | 174 ++++++++++++++--------------
 src/fp8.rs     |  28 ++---
 src/mpin.rs    |  70 +++++------
 src/mpin192.rs |  70 +++++------
 src/mpin256.rs |  70 +++++------
 src/pair.rs    | 120 +++++++++----------
 src/pair192.rs | 100 ++++++++--------
 src/pair256.rs | 124 ++++++++++----------
 26 files changed, 1062 insertions(+), 1068 deletions(-)

diff --git a/src/aes.rs b/src/aes.rs
index eedea79..32a0f86 100644
--- a/src/aes.rs
+++ b/src/aes.rs
@@ -33,7 +33,7 @@ pub const CTR4: usize = 33;
 pub const CTR8: usize = 37;
 pub const CTR16: usize = 45;
 
-const INCO: [u8; 4] = [0xB, 0xD, 0x9, 0xE]; /* Inverse Coefficients */
+const INCO: [u8; 4] = [0xB, 0xD, 0x9, 0xE]; // Inverse Coefficients
 
 const PTAB: [u8; 256] = [
     1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, 95, 225, 56, 72, 216, 115,
@@ -196,7 +196,7 @@ impl AES {
     }
 
     fn pack(b: [u8; 4]) -> u32 {
-        /* pack bytes into a 32-bit Word */
+        // pack bytes into a 32-bit Word
         return ((((b[3]) & 0xff) as u32) << 24)
             | ((((b[2]) & 0xff) as u32) << 16)
             | ((((b[1]) & 0xff) as u32) << 8)
@@ -204,7 +204,7 @@ impl AES {
     }
 
     fn unpack(a: u32) -> [u8; 4] {
-        /* unpack bytes from a word */
+        // unpack bytes from a word
         let b: [u8; 4] = [
             (a & 0xff) as u8,
             ((a >> 8) & 0xff) as u8,
@@ -215,7 +215,7 @@ impl AES {
     }
 
     fn bmul(x: u8, y: u8) -> u8 {
-        /* x.y= AntiLog(Log(x) + Log(y)) */
+        // x.y= AntiLog(Log(x) + Log(y))
         let ix = (x as usize) & 0xff;
         let iy = (y as usize) & 0xff;
         let lx = (LTAB[ix] as usize) & 0xff;
@@ -238,7 +238,7 @@ impl AES {
     }
 
     fn product(x: u32, y: u32) -> u8 {
-        /* dot product of two 4-byte arrays */
+        // dot product of two 4-byte arrays
         let xb = AES::unpack(x);
         let yb = AES::unpack(y);
 
@@ -249,7 +249,7 @@ impl AES {
     }
 
     fn invmixcol(x: u32) -> u32 {
-        /* matrix Multiplication */
+        // matrix Multiplication
         let mut b: [u8; 4] = [0; 4];
         let mut m = AES::pack(INCO);
         b[3] = AES::product(m, x);
@@ -283,9 +283,9 @@ impl AES {
         }
     }
 
-    /* reset cipher */
+    // reset cipher
     pub fn reset(&mut self, m: usize, iv: Option<[u8; 16]>) {
-        /* reset mode, or reset iv */
+        // reset mode, or reset iv
         self.mode = m;
         for i in 0..16 {
             self.f[i] = 0
@@ -300,7 +300,7 @@ impl AES {
     }
 
     pub fn init(&mut self, m: usize, nkey: usize, key: &[u8], iv: Option<[u8; 16]>) -> bool {
-        /* Key Scheduler. Create expanded encryption key */
+        // Key Scheduler. Create expanded encryption key
         let mut cipherkey: [u32; 8] = [0; 8];
         let mut b: [u8; 4] = [0; 4];
         let nk = nkey / 4;
@@ -331,7 +331,7 @@ impl AES {
         while j < n {
             self.fkey[j] =
                 self.fkey[j - nk] ^ AES::subbyte(AES::rotl24(self.fkey[j - 1])) ^ (RCO[k] as u32);
-            if nk<=6 { 
+            if nk<=6 {
 		for i in 1..nk {
 			if (i + j) >= n {
 				break;
@@ -345,7 +345,7 @@ impl AES {
 			}
 			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
 		}
-		
+
 		if (j + 4) < n {
 			self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
 		}
@@ -354,13 +354,13 @@ impl AES {
 				break;
 			}
 			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}	        
+		}
 	    }
             j += nk;
             k += 1;
         }
 
-        /* now for the expanded decrypt key in reverse order */
+        // now for the expanded decrypt key in reverse order
 
         for j in 0..4 {
             self.rkey[j + n - 4] = self.fkey[j]
@@ -387,7 +387,7 @@ impl AES {
         return ir;
     }
 
-    /* Encrypt a single block */
+    // Encrypt a single block
     pub fn ecb_encrypt(&mut self, buff: &mut [u8; 16]) {
         let mut b: [u8; 4] = [0; 4];
         let mut p: [u32; 4] = [0; 4];
@@ -405,7 +405,7 @@ impl AES {
 
         let mut k = 4;
 
-        /* State alternates between p and q */
+        // State alternates between p and q
         for _ in 1..self.nr {
             q[0] = self.fkey[k]
                 ^ FTABLE[(p[0] & 0xff) as usize]
@@ -439,7 +439,7 @@ impl AES {
             }
         }
 
-        /* Last Round */
+        // Last Round
 
         q[0] = self.fkey[k]
             ^ (FBSUB[(p[0] & 0xff) as usize] as u32)
@@ -475,7 +475,7 @@ impl AES {
         }
     }
 
-    /* Decrypt a single block */
+    // Decrypt a single block
     pub fn ecb_decrypt(&mut self, buff: &mut [u8; 16]) {
         let mut b: [u8; 4] = [0; 4];
         let mut p: [u32; 4] = [0; 4];
@@ -493,7 +493,7 @@ impl AES {
 
         let mut k = 4;
 
-        /* State alternates between p and q */
+        // State alternates between p and q
         for _ in 1..self.nr {
             q[0] = self.rkey[k]
                 ^ RTABLE[(p[0] & 0xff) as usize]
@@ -527,7 +527,7 @@ impl AES {
             }
         }
 
-        /* Last Round */
+        // Last Round
 
         q[0] = self.rkey[k]
             ^ (RBSUB[(p[0] & 0xff) as usize] as u32)
@@ -563,7 +563,7 @@ impl AES {
         }
     }
 
-    /* Encrypt using selected mode of operation */
+    // Encrypt using selected mode of operation
     pub fn encrypt(&mut self, buff: &mut [u8; 16]) -> u32 {
         let mut st: [u8; 16] = [0; 16];
 
@@ -643,7 +643,7 @@ impl AES {
         }
     }
 
-    /* Decrypt using selected mode of operation */
+    // Decrypt using selected mode of operation
     pub fn decrypt(&mut self, buff: &mut [u8; 16]) -> u32 {
         let mut st: [u8; 16] = [0; 16];
 
@@ -722,7 +722,7 @@ impl AES {
         }
     }
 
-    /* Clean up and delete left-overs */
+    // Clean up and delete left-overs
     pub fn end(&mut self) {
         // clean up
         for i in 0..4 * (self.nr + 1) {
diff --git a/src/big.rs b/src/big.rs
index 7267ad4..99342f4 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -22,7 +22,7 @@ use super::super::arch::Chunk;
 
 use super::super::arch::DChunk;
 
-use super::dbig::DBIG;
+use super::dbig::DBig;
 use rand::RAND;
 
 pub use super::rom::MODBYTES;
@@ -39,31 +39,31 @@ pub const NEXCESS: isize = (1 << ((arch::CHUNK) - BASEBITS - 1));
 pub const BIGBITS: usize = (MODBYTES * 8);
 
 #[derive(Copy)]
-pub struct BIG {
+pub struct Big {
     pub w: [Chunk; NLEN],
 }
 
-impl Clone for BIG {
-    fn clone(&self) -> BIG { *self }
+impl Clone for Big {
+    fn clone(&self) -> Big { *self }
 }
 
-impl fmt::Display for BIG {
+impl fmt::Display for Big {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut big = self.clone();
-        write!(f, "BIG: [ {} ]", big.tostring())
+        write!(f, "Big: [ {} ]", big.tostring())
     }
 }
 
-impl fmt::Debug for BIG {
+impl fmt::Debug for Big {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let mut big = self.clone();
-        write!(f, "BIG: [ {} ]", big.tostring())
+        write!(f, "Big: [ {} ]", big.tostring())
     }
 }
 
-impl PartialEq for BIG {
-    fn eq(&self, other: &BIG) -> bool {
-        if BIG::comp(self,other)==0 {
+impl PartialEq for Big {
+    fn eq(&self, other: &Big) -> bool {
+        if Big::comp(self,other)==0 {
             return true;
         } else {
             return false;
@@ -71,9 +71,9 @@ impl PartialEq for BIG {
     }
 }
 
-impl Ord for BIG {
-    fn cmp(&self, other: &BIG) -> Ordering {
-        let r = BIG::comp(self, other);
+impl Ord for Big {
+    fn cmp(&self, other: &Big) -> Ordering {
+        let r = Big::comp(self, other);
         if r > 0 {
             return Ordering::Greater;
         }
@@ -84,51 +84,51 @@ impl Ord for BIG {
     }
 }
 
-impl Eq for BIG { }
+impl Eq for Big { }
 
-impl PartialOrd for BIG {
-    fn partial_cmp(&self, other: &BIG) -> Option<Ordering> {
+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; NLEN] }
+impl Big {
+    pub fn new() -> Big {
+        Big { w: [0; NLEN] }
     }
 
-    pub fn new_int(x: isize) -> BIG {
-        let mut s = BIG::new();
+    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();
+    pub fn new_ints(a: &[Chunk]) -> Big {
+        let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = a[i]
         }
         return s;
     }
 
-    pub fn new_copy(y: &BIG) -> BIG {
-        let mut s = BIG::new();
+    pub fn new_copy(y: &Big) -> Big {
+        let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = y.w[i]
         }
         return s;
     }
 
-    pub fn new_big(y: &BIG) -> BIG {
-        let mut s = BIG::new();
+    pub fn new_big(y: &Big) -> Big {
+        let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = y.w[i]
         }
         return s;
     }
 
-    pub fn new_dcopy(y: &DBIG) -> BIG {
-        let mut s = BIG::new();
+    pub fn new_dcopy(y: &DBig) -> Big {
+        let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = y.w[i]
         }
@@ -151,7 +151,7 @@ impl BIG {
         self.w[NLEN - 1] |= x;
     }
 
-    /* test for zero */
+    // test for zero
     pub fn iszilch(&self) -> bool {
         for i in 0..NLEN {
             if self.w[i] != 0 {
@@ -161,14 +161,14 @@ impl BIG {
         return true;
     }
 
-    /* set to zero */
+    // set to zero
     pub fn zero(&mut self) {
         for i in 0..NLEN {
             self.w[i] = 0
         }
     }
 
-    /* Test for equal to one */
+    // Test for equal to one
     pub fn isunity(&self) -> bool {
         for i in 1..NLEN {
             if self.w[i] != 0 {
@@ -181,7 +181,7 @@ impl BIG {
         return true;
     }
 
-    /* set to one */
+    /// Set to one
     pub fn one(&mut self) {
         self.w[0] = 1;
         for i in 1..NLEN {
@@ -189,20 +189,21 @@ impl BIG {
         }
     }
 
-    /* Copy from another BIG */
-    pub fn copy(&mut self, x: &BIG) {
+    /// Copy from another Big
+    pub fn copy(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] = x.w[i]
         }
     }
 
-    pub fn dcopy(&mut self, x: &DBIG) {
+    /// Copy from a DBig
+    pub fn dcopy(&mut self, x: &DBig) {
         for i in 0..NLEN {
             self.w[i] = x.w[i]
         }
     }
 
-    /* Get top and bottom half of =x*y+c+r */
+    /// Get top and bottom half of =x*y+c+r
     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 & (BMASK as DChunk)) as Chunk;
@@ -210,7 +211,7 @@ impl BIG {
         return (top, bot);
     }
 
-    /* normalise BIG - force all digits < 2^BASEBITS */
+    /// normalise Big - force all digits < 2^BASEBITS
     pub fn norm(&mut self) -> Chunk {
         let mut carry = 0 as Chunk;
         for i in 0..NLEN - 1 {
@@ -222,8 +223,8 @@ impl BIG {
         return (self.w[NLEN - 1] >> ((8 * MODBYTES) % 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) {
+    /// 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..NLEN {
@@ -233,17 +234,17 @@ impl BIG {
         }
     }
 
-    pub fn cmove(&mut self, g: &BIG, d: isize) {
+    pub fn cmove(&mut self, g: &Big, d: isize) {
         let b = -d as Chunk;
         for i in 0..NLEN {
             self.w[i] ^= (self.w[i] ^ g.w[i]) & b;
         }
     }
 
-    /* Shift right by less than a word */
+    /// 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 */
+        let w = self.w[0] & ((1 << n) - 1); // shifted out part
         for i in 0..NLEN - 1 {
             self.w[i] = (self.w[i] >> k) | ((self.w[i + 1] << (BASEBITS - n)) & BMASK);
         }
@@ -251,7 +252,7 @@ impl BIG {
         return w as isize;
     }
 
-    /* general shift right */
+    /// general shift right
     pub fn shr(&mut self, k: usize) {
         let n = k % BASEBITS;
         let m = k / BASEBITS;
@@ -264,7 +265,7 @@ impl BIG {
         }
     }
 
-    /* Shift right by less than a word */
+    /// Shift right by less than a word
     pub fn fshl(&mut self, k: usize) -> isize {
         let n = k;
         self.w[NLEN - 1] = (self.w[NLEN - 1] << n) | (self.w[NLEN - 2] >> (BASEBITS - n));
@@ -272,10 +273,10 @@ impl BIG {
             self.w[i] = ((self.w[i] << k) & BMASK) | (self.w[i - 1] >> (BASEBITS - n));
         }
         self.w[0] = (self.w[0] << n) & BMASK;
-        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as isize; /* return excess - only used in ff.c */
+        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as isize; // return excess - only used in ff.c
     }
 
-    /* general shift left */
+    /// general shift left
     pub fn shl(&mut self, k: usize) {
         let n = k % BASEBITS;
         let m = k / BASEBITS;
@@ -293,10 +294,10 @@ impl BIG {
         }
     }
 
-    /* return number of bits */
+    // return number of bits
     pub fn nbits(&self) -> usize {
         let mut k = NLEN - 1;
-        let mut s = BIG::new_copy(&self);
+        let mut s = Big::new_copy(&self);
         s.norm();
         while (k as isize) >= 0 && s.w[k] == 0 {
             k = k.wrapping_sub(1)
@@ -313,7 +314,7 @@ impl BIG {
         return bts;
     }
 
-    /* Convert to Hex String */
+    // Convert to Hex String
     pub fn tostring(&mut self) -> String {
         let mut s = String::new();
         let mut len = self.nbits();
@@ -330,15 +331,15 @@ impl BIG {
         }
 
         for i in (0..len).rev() {
-            let mut b = BIG::new_copy(&self);
+            let mut b = Big::new_copy(&self);
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
         return s;
     }
 
-    pub fn fromstring(val: String) -> BIG {
-        let mut res = BIG::new();
+    pub fn fromstring(val: String) -> Big {
+        let mut res = Big::new();
         let len = val.len();
         let op = &val[0..1];
         let n = u8::from_str_radix(op, 16).unwrap();
@@ -352,21 +353,21 @@ impl BIG {
         return res;
     }
 
-    pub fn from_hex(val: String) -> BIG {
-        BIG::fromstring(val)
+    pub fn from_hex(val: String) -> Big {
+        Big::fromstring(val)
     }
-    
+
     pub fn to_hex(&mut self) -> String {
         self.tostring()
     }
 
-    pub fn add(&mut self, r: &BIG) {
+    pub fn add(&mut self, r: &Big) {
         for i in 0..NLEN {
             self.w[i] += r.w[i]
         }
     }
 
-    pub fn or(&mut self, r: &BIG) {
+    pub fn or(&mut self, r: &Big) {
         for i in 0..NLEN {
             self.w[i] |= r.w[i]
         }
@@ -378,9 +379,9 @@ impl BIG {
         }
     }
 
-    /* return this+x */
-    pub fn plus(&self, x: &BIG) -> BIG {
-        let mut s = BIG::new();
+    // return this+x
+    pub fn plus(&self, x: &Big) -> Big {
+        let mut s = Big::new();
         for i in 0..NLEN {
             s.w[i] = self.w[i] + x.w[i];
         }
@@ -392,46 +393,46 @@ impl BIG {
         self.w[0] += x as Chunk;
     }
 
-    /* return self-x */
-    pub fn minus(&self, x: &BIG) -> BIG {
-        let mut d = BIG::new();
+    // return self-x
+    pub fn minus(&self, x: &Big) -> Big {
+        let mut d = Big::new();
         for i in 0..NLEN {
             d.w[i] = self.w[i] - x.w[i];
         }
         return d;
     }
 
-    /* self-=x */
-    pub fn sub(&mut self, x: &BIG) {
+    // self-=x
+    pub fn sub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] -= x.w[i];
         }
     }
 
-    /* reverse subtract this=x-this */
+    // reverse subtract this=x-this
 
-    pub fn rsub(&mut self, x: &BIG) {
+    pub fn rsub(&mut self, x: &Big) {
         for i in 0..NLEN {
             self.w[i] = x.w[i] - self.w[i]
         }
     }
 
-    /* self-=x, where x is int */
+    // 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 */
+    // self*=x, where x is small int<NEXCESS
     pub fn imul(&mut self, c: isize) {
         for i in 0..NLEN {
             self.w[i] *= c as Chunk;
         }
     }
 
-    /* convert this BIG to byte array */
+    // convert this Big to byte array
     pub fn tobytearray(&mut self, b: &mut [u8], n: usize) {
-        let mut c = BIG::new_copy(self);
+        let mut c = Big::new_copy(self);
         c.norm();
 
         for i in (0..(MODBYTES as usize)).rev() {
@@ -440,9 +441,9 @@ impl BIG {
         }
     }
 
-    /* convert from byte array to BIG */
-    pub fn frombytearray(b: &[u8], n: usize) -> BIG {
-        let mut m = BIG::new();
+    // convert from byte array to Big
+    pub fn frombytearray(b: &[u8], n: usize) -> Big {
+        let mut m = Big::new();
         for i in 0..(MODBYTES as usize) {
             m.fshl(8);
             m.w[0] += (b[i + n] & 0xff) as Chunk;
@@ -454,28 +455,28 @@ impl BIG {
         self.tobytearray(b, 0)
     }
 
-    pub fn frombytes(b: &[u8]) -> BIG {
-        return BIG::frombytearray(b, 0);
+    pub fn frombytes(b: &[u8]) -> Big {
+        return Big::frombytearray(b, 0);
     }
 
-    /* self*=x, where x is >NEXCESS */
+    // self*=x, where x is >NEXCESS
     pub fn pmul(&mut self, c: isize) -> Chunk {
         let mut carry = 0 as Chunk;
         for i in 0..NLEN {
             let ak = self.w[i];
-            let tuple = BIG::muladd(ak, c as Chunk, carry, 0 as Chunk);
+            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();
+    // 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..NLEN {
-            let tuple = BIG::muladd(self.w[j], c as Chunk, carry, m.w[j]);
+            let tuple = Big::muladd(self.w[j], c as Chunk, carry, m.w[j]);
             carry = tuple.0;
             m.w[j] = tuple.1;
         }
@@ -483,7 +484,7 @@ impl BIG {
         return m;
     }
 
-    /* divide by 3 */
+    // divide by 3
     pub fn div3(&mut self) -> Chunk {
         let mut carry = 0 as Chunk;
         self.norm();
@@ -496,14 +497,14 @@ impl BIG {
         return carry;
     }
 
-    /* return a*b where result fits in a BIG */
-    pub fn smul(a: &BIG, b: &BIG) -> BIG {
-        let mut c = BIG::new();
+    // 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..NLEN {
             let mut carry = 0 as Chunk;
             for j in 0..NLEN {
                 if i + j < NLEN {
-                    let tuple = BIG::muladd(a.w[i], b.w[j], carry, c.w[i + j]);
+                    let tuple = Big::muladd(a.w[i], b.w[j], carry, c.w[i + j]);
                     carry = tuple.0;
                     c.w[i + j] = tuple.1;
                 }
@@ -512,8 +513,8 @@ impl BIG {
         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 {
+    // 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..NLEN).rev() {
             if a.w[i] == b.w[i] {
                 continue;
@@ -527,7 +528,7 @@ impl BIG {
         return 0;
     }
 
-    /* set x = x mod 2^m */
+    // set x = x mod 2^m
     pub fn mod2m(&mut self, m: usize) {
         let wd = m / BASEBITS;
         let bt = m % BASEBITS;
@@ -538,7 +539,7 @@ impl BIG {
         }
     }
 
-    /* Arazi and Qi inversion mod 256 */
+    // Arazi and Qi inversion mod 256
     pub fn invmod256(a: isize) -> isize {
         let mut t1: isize = 0;
         let mut c = (a >> 1) & 1;
@@ -577,12 +578,12 @@ impl BIG {
         return u;
     }
 
-    /* return parity */
+    // return parity
     pub fn parity(&self) -> isize {
         return (self.w[0] % 2) as isize;
     }
 
-    /* return n-th bit */
+    // return n-th bit
     pub fn bit(&self, n: usize) -> isize {
         if (self.w[n / (BASEBITS as usize)] & (1 << (n % BASEBITS))) > 0 {
             return 1;
@@ -591,37 +592,37 @@ impl BIG {
         }
     }
 
-    /* return n last bits */
+    // 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! */
+    // 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();
+        let mut u = Big::new();
+        let mut b = Big::new();
+        let mut c = Big::new();
 
-        u.inc(BIG::invmod256(self.lastbits(8)));
+        u.inc(Big::invmod256(self.lastbits(8)));
 
         let mut i = 8;
         while i < BIGBITS {
             u.norm();
             b.copy(self);
             b.mod2m(i);
-            let mut t1 = BIG::smul(&u, &b);
+            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);
+            let mut t2 = Big::smul(&u, &c);
             t2.mod2m(i);
             t1.add(&t2);
             t1.norm();
-            b = BIG::smul(&t1, &u);
+            b = Big::smul(&t1, &u);
             t1.copy(&b);
             t1.mod2m(i);
 
@@ -638,19 +639,19 @@ impl BIG {
         self.norm();
     }
 
-    /* reduce self mod m */
-    pub fn rmod(&mut self, n: &BIG) {
+    // 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();
+        let mut m = Big::new_copy(n);
+        let mut r = Big::new();
         self.norm();
-        if BIG::comp(self, &m) < 0 {
+        if Big::comp(self, &m) < 0 {
             return;
         }
         loop {
             m.fshl(1);
             k += 1;
-            if BIG::comp(self, &m) < 0 {
+            if Big::comp(self, &m) < 0 {
                 break;
             }
         }
@@ -669,17 +670,17 @@ impl BIG {
         }
     }
 
-    /* divide self by m */
-    pub fn div(&mut self, n: &BIG) {
+    // 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();
+        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 {
+        while Big::comp(&b, &m) >= 0 {
             e.fshl(1);
             m.fshl(1);
             k += 1;
@@ -702,12 +703,12 @@ impl BIG {
         }
     }
 
-    /* get 8*MODBYTES size random number */
-    pub fn random(rng: &mut RAND) -> BIG {
-        let mut m = BIG::new();
+    // 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 */
+        // generate random Big
 
         for _ in 0..8 * (MODBYTES as usize) {
             if j == 0 {
@@ -725,12 +726,12 @@ impl BIG {
         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();
+    // 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;
-        let t = BIG::new_copy(q);
+        let t = Big::new_copy(q);
         for _ in 0..2 * t.nbits() {
             if j == 0 {
                 r = rng.getbyte();
@@ -748,15 +749,15 @@ impl BIG {
         return m;
     }
 
-    /* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
-    pub fn jacobi(&mut self, p: &BIG) -> isize {
+    // 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 {
+        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();
@@ -765,8 +766,8 @@ impl BIG {
         n.copy(p);
         x.rmod(p);
 
-        while BIG::comp(&n, &one) > 0 {
-            if BIG::comp(&x, &zilch) == 0 {
+        while Big::comp(&n, &one) > 0 {
+            if Big::comp(&x, &zilch) == 0 {
                 return 0;
             }
             let n8 = n.lastbits(3) as usize;
@@ -792,17 +793,17 @@ impl BIG {
         }
     }
 
-    /* self=1/self mod p. Binary method */
-    pub fn invmodp(&mut self, p: &BIG) {
+    // 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) {
+        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.fshr(1);
                 if x1.parity() != 0 {
@@ -819,10 +820,10 @@ impl BIG {
                 }
                 x2.fshr(1);
             }
-            if BIG::comp(&u, &v) >= 0 {
+            if Big::comp(&u, &v) >= 0 {
                 u.sub(&v);
                 u.norm();
-                if BIG::comp(&x1, &x2) >= 0 {
+                if Big::comp(&x1, &x2) >= 0 {
                     x1.sub(&x2)
                 } else {
                     t.copy(p);
@@ -833,7 +834,7 @@ impl BIG {
             } else {
                 v.sub(&u);
                 v.norm();
-                if BIG::comp(&x2, &x1) >= 0 {
+                if Big::comp(&x2, &x1) >= 0 {
                     x2.sub(&x1)
                 } else {
                     t.copy(p);
@@ -843,17 +844,17 @@ impl BIG {
                 x2.norm();
             }
         }
-        if BIG::comp(&u, &one) == 0 {
+        if Big::comp(&u, &one) == 0 {
             self.copy(&x1)
         } else {
             self.copy(&x2)
         }
     }
 
-    /* return a*b as DBIG */
+    // return a*b as DBig
 
-    pub fn mul(a: &BIG, b: &BIG) -> DBIG {
-        let mut c = DBIG::new();
+    pub fn mul(a: &Big, b: &Big) -> DBig {
+        let mut c = DBig::new();
         let rm = BMASK as DChunk;
         let rb = BASEBITS;
 
@@ -890,9 +891,9 @@ impl BIG {
         return c;
     }
 
-    /* return a^2 as DBIG */
-    pub fn sqr(a: &BIG) -> DBIG {
-        let mut c = DBIG::new();
+    // return a^2 as DBig
+    pub fn sqr(a: &Big) -> DBig {
+        let mut c = DBig::new();
         let rm = BMASK as DChunk;
         let rb = BASEBITS;
 
@@ -960,8 +961,8 @@ impl BIG {
         return c;
     }
 
-    pub fn monty(md: &BIG, mc: Chunk, d: &mut DBIG) -> BIG {
-        let mut b = BIG::new();
+    pub fn monty(md: &Big, mc: Chunk, d: &mut DBig) -> Big {
+        let mut b = Big::new();
         let rm = BMASK as DChunk;
         let rb = BASEBITS;
 
@@ -1004,7 +1005,7 @@ impl BIG {
         return b;
     }
 
-    pub fn ssn(r: &mut BIG, a: &BIG, m: &mut BIG) -> isize {
+    pub fn ssn(r: &mut Big, a: &Big, m: &mut Big) -> isize {
         let n = NLEN - 1;
         m.w[0] = (m.w[0] >> 1) | ((m.w[1] << (BASEBITS - 1)) & BMASK);
         r.w[0] = a.w[0] - m.w[0];
@@ -1021,49 +1022,49 @@ impl BIG {
         return ((r.w[n] >> (arch::CHUNK - 1)) & 1) as isize;
     }
 
-    /* return a*b mod m */
-    pub fn modmul(a1: &BIG, b1: &BIG, m: &BIG) -> BIG {
-        let mut a = BIG::new_copy(a1);
-        let mut b = BIG::new_copy(b1);
+    // return a*b mod m
+    pub fn modmul(a1: &Big, b1: &Big, m: &Big) -> Big {
+        let mut a = Big::new_copy(a1);
+        let mut b = Big::new_copy(b1);
         a.rmod(m);
         b.rmod(m);
-        let mut d = BIG::mul(&a, &b);
+        let mut d = Big::mul(&a, &b);
         return d.dmod(m);
     }
 
-    /* return a^2 mod m */
-    pub fn modsqr(a1: &BIG, m: &BIG) -> BIG {
-        let mut a = BIG::new_copy(a1);
+    // return a^2 mod m
+    pub fn modsqr(a1: &Big, m: &Big) -> Big {
+        let mut a = Big::new_copy(a1);
         a.rmod(m);
-        let mut d = BIG::sqr(&a);
+        let mut d = Big::sqr(&a);
         return d.dmod(m);
     }
 
-    /* return -a mod m */
-    pub fn modneg(a1: &BIG, m: &BIG) -> BIG {
-        let mut a = BIG::new_copy(a1);
+    // return -a mod m
+    pub fn modneg(a1: &Big, m: &Big) -> Big {
+        let mut a = Big::new_copy(a1);
         a.rmod(m);
         return m.minus(&a);
     }
 
-    /* return this^e mod m */
-    pub fn powmod(&mut self, e1: &BIG, m: &BIG) -> BIG {
+    // return this^e mod m
+    pub fn powmod(&mut self, e1: &Big, m: &Big) -> Big {
         self.norm();
-        let mut e = BIG::new_copy(e1);
+        let mut e = Big::new_copy(e1);
         e.norm();
-        let mut a = BIG::new_int(1);
-        let mut z = BIG::new_copy(&e);
-        let mut s = BIG::new_copy(self);
+        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(&a, &s, m)
+                a = Big::modmul(&a, &s, m)
             }
             if z.iszilch() {
                 break;
             }
-            s = BIG::modsqr(&mut s, m);
+            s = Big::modsqr(&mut s, m);
         }
         return a;
     }
diff --git a/src/bls.rs b/src/bls.rs
index 7e7fd7a..2ef80a4 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -16,11 +16,12 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
+
 use std::str;
 use super::ecp::ECP;
 use super::ecp2::ECP2;
 //use super::fp12::FP12;
-use super::big::BIG;
+use super::big::Big;
 use super::pair;
 use super::big;
 use super::rom;
@@ -29,15 +30,13 @@ use rand::RAND;
 use sha3::SHA3;
 use sha3::SHAKE256;
 
-/* BLS API Functions */
-
+// BLS API Functions
 pub const BFS: usize = big::MODBYTES as usize;
 pub const BGS: usize = big::MODBYTES as usize;
 pub const BLS_OK: isize = 0;
 pub const BLS_FAIL: isize = -1;
 
-/* hash a message to an ECP point, using SHA3 */
-
+// hash a message to an ECP point, using SHA3
 #[allow(non_snake_case)]
 fn bls_hashit(m: &str) -> ECP {
     let mut sh = SHA3::new(SHAKE256);
@@ -51,27 +50,25 @@ fn bls_hashit(m: &str) -> ECP {
     return P;
 }
 
-/* generate key pair, private key s, public key w */
+// generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP2::generator();
-    let mut sc = BIG::randomnum(&q, &mut rng);
+    let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair::g2mul(&g, &mut sc).tobytes(w);
     return BLS_OK;
 }
 
-/* Sign message m using private key s to produce signature sig */
-
+// Sign message m using private key s to produce signature sig
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
-    let mut sc = BIG::frombytes(&s);
+    let mut sc = Big::frombytes(&s);
     pair::g1mul(&d, &mut sc).tobytes(sig, true);
     return BLS_OK;
 }
 
-/* Verify signature given message m, the signature sig, and the public key w */
-
+// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -79,14 +76,14 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP2::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
+    // Use new multi-pairing mechanism
     let mut r=pair::initmp();
     pair::another(&mut r,&g,&d);
     pair::another(&mut r,&pk,&hm);
     let mut v=pair::miller(&r);
 
-//.. or alternatively
-//    let mut v = pair::ate2(&g, &d, &pk, &hm);
+    //.. or alternatively
+    //    let mut v = pair::ate2(&g, &d, &pk, &hm);
 
     v = pair::fexp(&v);
     if v.isunity() {
diff --git a/src/bls192.rs b/src/bls192.rs
index 20ee92e..b2c7e97 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -16,11 +16,12 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
+
 use std::str;
 use super::ecp::ECP;
 use super::ecp4::ECP4;
 //use super::fp24::FP24;
-use super::big::BIG;
+use super::big::Big;
 use super::pair192;
 use super::big;
 use super::rom;
@@ -29,14 +30,14 @@ use rand::RAND;
 use sha3::SHA3;
 use sha3::SHAKE256;
 
-/* BLS API Functions */
+// BLS API Functions
 
 pub const BFS: usize = big::MODBYTES as usize;
 pub const BGS: usize = big::MODBYTES as usize;
 pub const BLS_OK: isize = 0;
 pub const BLS_FAIL: isize = -1;
 
-/* hash a message to an ECP point, using SHA3 */
+// hash a message to an ECP point, using SHA3
 
 #[allow(non_snake_case)]
 fn bls_hashit(m: &str) -> ECP {
@@ -51,27 +52,25 @@ fn bls_hashit(m: &str) -> ECP {
     return P;
 }
 
-/* generate key pair, private key s, public key w */
+// generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP4::generator();
-    let mut sc = BIG::randomnum(&q, &mut rng);
+    let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair192::g2mul(&g, &mut sc).tobytes(w);
     return BLS_OK;
 }
 
-/* Sign message m using private key s to produce signature sig */
-
+// Sign message m using private key s to produce signature sig
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
-    let mut sc = BIG::frombytes(&s);
+    let mut sc = Big::frombytes(&s);
     pair192::g1mul(&d, &mut sc).tobytes(sig, true);
     return BLS_OK;
 }
 
-/* Verify signature given message m, the signature sig, and the public key w */
-
+// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -79,15 +78,15 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP4::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
+    // Use new multi-pairing mechanism
     let mut r=pair192::initmp();
     pair192::another(&mut r,&g,&d);
     pair192::another(&mut r,&pk,&hm);
     let mut v=pair192::miller(&r);
 
-//.. or alternatively
-//    let mut v = pair192::ate2(&g, &d, &pk, &hm);
-    
+    //.. or alternatively
+    //    let mut v = pair192::ate2(&g, &d, &pk, &hm);
+
     v = pair192::fexp(&v);
     if v.isunity() {
         return BLS_OK;
diff --git a/src/bls256.rs b/src/bls256.rs
index cdb553d..a0ac094 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -16,11 +16,12 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
+
 use std::str;
 use super::ecp::ECP;
 use super::ecp8::ECP8;
 //use super::fp48::FP48;
-use super::big::BIG;
+use super::big::Big;
 use super::pair256;
 use super::big;
 use super::rom;
@@ -29,15 +30,13 @@ use rand::RAND;
 use sha3::SHA3;
 use sha3::SHAKE256;
 
-/* BLS API Functions */
-
+// BLS API Functions
 pub const BFS: usize = big::MODBYTES as usize;
 pub const BGS: usize = big::MODBYTES as usize;
 pub const BLS_OK: isize = 0;
 pub const BLS_FAIL: isize = -1;
 
-/* hash a message to an ECP point, using SHA3 */
-
+// hash a message to an ECP point, using SHA3
 #[allow(non_snake_case)]
 fn bls_hashit(m: &str) -> ECP {
     let mut sh = SHA3::new(SHAKE256);
@@ -51,27 +50,25 @@ fn bls_hashit(m: &str) -> ECP {
     return P;
 }
 
-/* generate key pair, private key s, public key w */
+// generate key pair, private key s, public key w
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP8::generator();
-    let mut sc = BIG::randomnum(&q, &mut rng);
+    let mut sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair256::g2mul(&g, &mut sc).tobytes(w);
     return BLS_OK;
 }
 
-/* Sign message m using private key s to produce signature sig */
-
+// Sign message m using private key s to produce signature sig
 pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
     let d = bls_hashit(m);
-    let mut sc = BIG::frombytes(&s);
+    let mut sc = Big::frombytes(&s);
     pair256::g1mul(&d, &mut sc).tobytes(sig, true);
     return BLS_OK;
 }
 
-/* Verify signature given message m, the signature sig, and the public key w */
-
+// Verify signature given message m, the signature sig, and the public key w
 pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let hm = bls_hashit(m);
     let mut d = ECP::frombytes(&sig);
@@ -79,14 +76,14 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP8::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
+    // Use new multi-pairing mechanism
     let mut r=pair256::initmp();
     pair256::another(&mut r,&g,&d);
     pair256::another(&mut r,&pk,&hm);
     let mut v=pair256::miller(&r);
 
-//.. or alternatively
-//    let mut v = pair256::ate2(&g, &d, &pk, &hm);
+    //.. or alternatively
+    //    let mut v = pair256::ate2(&g, &d, &pk, &hm);
 
     v = pair256::fexp(&v);
     if v.isunity() {
diff --git a/src/dbig.rs b/src/dbig.rs
index 353443a..31cf402 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -19,35 +19,35 @@ under the License.
 
 use super::super::arch;
 use super::big;
-use super::big::BIG;
+use super::big::Big;
 use super::super::arch::Chunk;
 
 #[derive(Copy)]
-pub struct DBIG {
+pub struct DBig {
     pub w: [Chunk; big::DNLEN],
 }
 
-impl Clone for DBIG {
-    fn clone(&self) -> DBIG { *self }
+impl Clone for DBig {
+    fn clone(&self) -> DBig { *self }
 }
 
-impl DBIG {
-    pub fn new() -> DBIG {
-        DBIG {
+impl DBig {
+    pub fn new() -> DBig {
+        DBig {
             w: [0; big::DNLEN as usize],
         }
     }
 
-    pub fn new_copy(y: &DBIG) -> DBIG {
-        let mut s = DBIG::new();
+    pub fn new_copy(y: &DBig) -> DBig {
+        let mut s = DBig::new();
         for i in 0..big::DNLEN {
             s.w[i] = y.w[i]
         }
         return s;
     }
 
-    pub fn new_scopy(x: &BIG) -> DBIG {
-        let mut b = DBIG::new();
+    pub fn new_scopy(x: &Big) -> DBig {
+        let mut b = DBig::new();
         for i in 0..big::NLEN {
             b.w[i] = x.w[i];
         }
@@ -60,9 +60,9 @@ impl DBIG {
         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();
+    /* 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 % big::BASEBITS;
         let mut carry = self.w[big::DNLEN - 1] << (big::BASEBITS - m);
 
@@ -106,14 +106,14 @@ impl DBIG {
         }
     }
 
-    /* Copy from another DBIG */
-    pub fn copy(&mut self, x: &DBIG) {
+    /* Copy from another DBig */
+    pub fn copy(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] = x.w[i];
         }
     }
 
-    pub fn ucopy(&mut self, x: &BIG) {
+    pub fn ucopy(&mut self, x: &Big) {
         for i in 0..big::NLEN {
             self.w[i] = 0;
         }
@@ -122,7 +122,7 @@ impl DBIG {
         }
     }
 
-    pub fn cmove(&mut self, g: &DBIG, d: isize) {
+    pub fn cmove(&mut self, g: &DBig, d: isize) {
         let b = -d as Chunk;
         for i in 0..big::DNLEN {
             self.w[i] ^= (self.w[i] ^ g.w[i]) & b;
@@ -130,28 +130,28 @@ impl DBIG {
     }
 
     /* self+=x */
-    pub fn add(&mut self, x: &DBIG) {
+    pub fn add(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] += x.w[i];
         }
     }
 
     /* self-=x */
-    pub fn sub(&mut self, x: &DBIG) {
+    pub fn sub(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] -= x.w[i];
         }
     }
 
     /* self=x-self */
-    pub fn rsub(&mut self, x: &DBIG) {
+    pub fn rsub(&mut self, x: &DBig) {
         for i in 0..big::DNLEN {
             self.w[i] = x.w[i] - self.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 {
+    pub fn comp(a: &DBig, b: &DBig) -> isize {
         for i in (0..big::DNLEN).rev() {
             if a.w[i] == b.w[i] {
                 continue;
@@ -165,7 +165,7 @@ impl DBIG {
         return 0;
     }
 
-    /* normalise BIG - force all digits < 2^big::BASEBITS */
+    /* normalise Big - force all digits < 2^big::BASEBITS */
     pub fn norm(&mut self) {
         let mut carry = 0 as Chunk;
         for i in 0..big::DNLEN - 1 {
@@ -176,22 +176,22 @@ impl DBIG {
         self.w[big::DNLEN - 1] += carry
     }
 
-    /* reduces self DBIG mod a BIG, and returns the BIG */
-    pub fn dmod(&mut self, c: &BIG) -> BIG {
+    /* 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();
+        let mut m = DBig::new_scopy(c);
+        let mut dr = DBig::new();
 
-        if DBIG::comp(self, &m) < 0 {
-            let r = BIG::new_dcopy(self);
+        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 {
+            if DBig::comp(self, &m) < 0 {
                 break;
             }
         }
@@ -209,21 +209,21 @@ impl DBIG {
 
             k -= 1;
         }
-        let r = BIG::new_dcopy(self);
+        let r = Big::new_dcopy(self);
         return r;
     }
 
     /* return this/c */
-    pub fn div(&mut self, c: &BIG) -> BIG {
+    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();
+        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 {
+        while DBig::comp(self, &m) >= 0 {
             e.fshl(1);
             m.shl(1);
             k += 1;
@@ -262,7 +262,7 @@ impl DBIG {
     /* return number of bits */
     pub fn nbits(&mut self) -> usize {
         let mut k = big::DNLEN - 1;
-        let mut s = DBIG::new_copy(&self);
+        let mut s = DBig::new_copy(&self);
         s.norm();
         while (k as isize) >= 0 && s.w[k] == 0 {
             k = k.wrapping_sub(1)
@@ -292,7 +292,7 @@ impl DBIG {
         }
 
         for i in (0..len).rev() {
-            let mut b = DBIG::new_copy(&self);
+            let mut b = DBig::new_copy(&self);
             b.shr(i * 4);
             s = s + &format!("{:X}", b.w[0] & 15);
         }
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 9b49e18..1df8446 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -19,7 +19,7 @@ under the License.
 
 use super::ecp;
 use super::ecp::ECP;
-use super::big::BIG;
+use super::big::Big;
 use super::rom;
 use super::big;
 
@@ -393,15 +393,15 @@ pub fn cbc_iv0_decrypt(k: &[u8], c: &[u8]) -> Option<Vec<u8>> {
 #[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 sc: Big;
     let G = ECP::generator();
 
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     if let Some(mut x) = rng {
-        sc = BIG::randomnum(&r, &mut x);
+        sc = Big::randomnum(&r, &mut x);
     } else {
-        sc = BIG::frombytes(&s);
+        sc = Big::frombytes(&s);
         sc.rmod(&r);
     }
 
@@ -420,15 +420,15 @@ pub fn public_key_validate(w: &[u8]) -> isize {
     let mut WP = ECP::frombytes(w);
     let mut res = 0;
 
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     if WP.is_infinity() {
         res = INVALID_PUBLIC_KEY
     }
     if res == 0 {
-        let q = BIG::new_ints(&rom::MODULUS);
+        let q = Big::new_ints(&rom::MODULUS);
         let nb = q.nbits();
-        let mut k = BIG::new();
+        let mut k = Big::new();
         k.one();
         k.shl((nb + 4) / 2);
         k.add(&q);
@@ -455,7 +455,7 @@ 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 sc = Big::frombytes(&s);
 
     let mut W = ECP::frombytes(&wd);
     if W.is_infinity() {
@@ -463,7 +463,7 @@ pub fn ecpsvdp_dh(s: &[u8], wd: &[u8], z: &mut [u8]) -> isize {
     }
 
     if res == 0 {
-        let r = BIG::new_ints(&rom::CURVE_ORDER);
+        let r = Big::new_ints(&rom::CURVE_ORDER);
         sc.rmod(&r);
         W = W.mul(&mut sc);
         if W.is_infinity() {
@@ -495,19 +495,19 @@ pub fn ecpsp_dsa(
 
     let G = ECP::generator();
 
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut sc = BIG::frombytes(s); /* s or &s? */
-    let fb = BIG::frombytes(&b);
+    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 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); /* side channel masking */
+        let mut u = Big::randomnum(&r, rng);
+        let mut w = Big::randomnum(&r, rng); /* side channel masking */
 
         V.copy(&G);
         V = V.mul(&mut u);
@@ -518,17 +518,17 @@ pub fn ecpsp_dsa(
             continue;
         }
 
-        tb.copy(&BIG::modmul(&mut u, &mut w, &r));
+        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.copy(&Big::modmul(&mut sc, &mut cb, &r));
         db.add(&fb);
 
-        tb.copy(&BIG::modmul(&mut db, &mut w, &r));
+        tb.copy(&Big::modmul(&mut db, &mut w, &r));
         db.copy(&tb);
 
-        tb.copy(&BIG::modmul(&mut u, &mut db, &r));
+        tb.copy(&Big::modmul(&mut u, &mut db, &r));
         db.copy(&tb);
     }
 
@@ -554,22 +554,22 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
 
     let mut G = ECP::generator();
 
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    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();
+    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 {
+    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));
+        tb.copy(&Big::modmul(&mut fb, &mut db, &r));
         fb.copy(&tb);
-        let h2 = BIG::modmul(&mut cb, &mut db, &r);
+        let h2 = Big::modmul(&mut cb, &mut db, &r);
 
         let WP = ECP::frombytes(&w);
         if WP.is_infinity() {
@@ -586,7 +586,7 @@ pub fn ecpvp_dsa(sha: usize, w: &[u8], f: &[u8], c: &[u8], d: &[u8]) -> isize {
                 db = P.getx();
                 db.rmod(&r);
 
-                if BIG::comp(&db, &cb) != 0 {
+                if Big::comp(&db, &cb) != 0 {
                     res = INVALID
                 }
             }
diff --git a/src/ecp.rs b/src/ecp.rs
index 9e7b29c..0e27f32 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -18,7 +18,7 @@ under the License.
 */
 
 use super::fp::FP;
-use super::big::BIG;
+use super::big::Big;
 use super::big;
 use super::rom;
 
@@ -70,8 +70,8 @@ impl ECP {
         return E;
     }
 
-    /* set (x,y) from two BIGs */
-    pub fn new_bigs(ix: &BIG, iy: &BIG) -> ECP {
+    /* 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);
@@ -92,8 +92,8 @@ impl ECP {
         return E;
     }
 
-    /* set (x,y) from BIG and a bit */
-    pub fn new_bigint(ix: &BIG, s: isize) -> ECP {
+    /* 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.x.norm();
@@ -115,7 +115,7 @@ impl ECP {
 
     #[allow(non_snake_case)]
     /* set from x - calculate y from curve equation */
-    pub fn new_big(ix: &BIG) -> ECP {
+    pub fn new_big(ix: &Big) -> ECP {
         let mut E = ECP::new();
         E.x.bcopy(ix);
         E.x.norm();
@@ -151,7 +151,7 @@ impl ECP {
 
         if CURVETYPE == CurveType::WEIERSTRASS {
             // x^3+Ax+B
-            let b = FP::new_big(&BIG::new_ints(&rom::CURVE_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);
@@ -164,7 +164,7 @@ impl ECP {
         }
         if CURVETYPE == CurveType::EDWARDS {
             // (Ax^2-1)/(Bx^2-1)
-            let mut b = FP::new_big(&BIG::new_ints(&rom::CURVE_B));
+            let mut b = FP::new_big(&Big::new_ints(&rom::CURVE_B));
             let one = FP::new_int(1);
             b.mul(&r);
             b.sub(&one);
@@ -316,16 +316,16 @@ impl ECP {
         self.z.copy(&one);
     }
 
-    /* extract x as a BIG */
-    pub fn getx(&self) -> BIG {
+    /* extract x as a Big */
+    pub fn getx(&self) -> Big {
         let mut W = ECP::new();
         W.copy(self);
         W.affine();
         return W.x.redc();
     }
 
-    /* extract y as a BIG */
-    pub fn gety(&self) -> BIG {
+    /* extract y as a Big */
+    pub fn gety(&self) -> Big {
         let mut W = ECP::new();
         W.copy(self);
         W.affine();
@@ -393,13 +393,13 @@ impl ECP {
     pub fn frombytes(b: &[u8]) -> ECP {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
-        let p = BIG::new_ints(&rom::MODULUS);
+        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 {
+        let px = Big::frombytes(&t);
+        if Big::comp(&px, &p) >= 0 {
             return ECP::new();
         }
 
@@ -411,8 +411,8 @@ impl ECP {
             for i in 0..mb {
                 t[i] = b[i + mb + 1]
             }
-            let py = BIG::frombytes(&t);
-            if BIG::comp(&py, &p) >= 0 {
+            let py = Big::frombytes(&t);
+            if Big::comp(&py, &p) >= 0 {
                 return ECP::new();
             }
             return ECP::new_bigs(&px, &py);
@@ -509,7 +509,7 @@ impl ECP {
                 let mut b = FP::new();
 
                 if rom::CURVE_B_I == 0 {
-                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
+                    b.copy(&FP::new_big(&Big::new_ints(&rom::CURVE_B)));
                 }
 
                 t0.sqr(); //1    x^2
@@ -742,7 +742,7 @@ impl ECP {
                 let mut b = FP::new();
 
                 if rom::CURVE_B_I == 0 {
-                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
+                    b.copy(&FP::new_big(&Big::new_ints(&rom::CURVE_B)));
                 }
 
                 t0.mul(&Q.x); //1
@@ -848,7 +848,7 @@ impl ECP {
             }
         }
         if CURVETYPE == CurveType::EDWARDS {
-            let bb = FP::new_big(&BIG::new_ints(&rom::CURVE_B));
+            let 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);
@@ -960,7 +960,7 @@ impl ECP {
     /* constant time multiply by small integer of length bts - use ladder */
     pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
         if CURVETYPE == CurveType::MONTGOMERY {
-            return self.mul(&mut BIG::new_int(e as isize));
+            return self.mul(&mut Big::new_int(e as isize));
         } else {
             let mut P = ECP::new();
             let mut R0 = ECP::new();
@@ -984,7 +984,7 @@ impl ECP {
 
     /* return e.self */
 
-    pub fn mul(&self, e: &BIG) -> ECP {
+    pub fn mul(&self, e: &Big) -> ECP {
         if e.iszilch() || self.is_infinity() {
             return ECP::new();
         }
@@ -1013,8 +1013,8 @@ impl ECP {
             P.copy(&R0)
         } else {
             // fixed size windows
-            let mut mt = BIG::new();
-            let mut t = BIG::new();
+            let mut mt = Big::new();
+            let mut t = Big::new();
             let mut Q = ECP::new();
             let mut C = ECP::new();
 
@@ -1084,10 +1084,10 @@ impl ECP {
 
     /* Return e.this+f.Q */
 
-    pub fn mul2(&self, e: &BIG, Q: &ECP, f: &BIG) -> ECP {
-        let mut te = BIG::new();
-        let mut tf = BIG::new();
-        let mut mt = BIG::new();
+    pub fn mul2(&self, e: &Big, Q: &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();
@@ -1210,7 +1210,7 @@ impl ECP {
             self.dbl();
             return;
         }
-        let c = BIG::new_ints(&rom::CURVE_COF);
+        let c = Big::new_ints(&rom::CURVE_COF);
         let P = self.mul(&c);
         self.copy(&P);
     }
@@ -1218,8 +1218,8 @@ impl ECP {
     // Map a given byte slice to a point on the curve. The byte slice should be atleast the size of the modulus
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP {
-        let mut q = BIG::new_ints(&rom::MODULUS);
-        let mut x = BIG::frombytes(h);
+        let mut q = Big::new_ints(&rom::MODULUS);
+        let mut x = Big::frombytes(h);
         x.rmod(&mut q);
         let mut P: ECP;
 
@@ -1248,10 +1248,10 @@ impl ECP {
     pub fn generator() -> ECP {
         let G: ECP;
 
-        let gx = BIG::new_ints(&rom::CURVE_GX);
+        let gx = Big::new_ints(&rom::CURVE_GX);
 
         if CURVETYPE != CurveType::MONTGOMERY {
-            let gy = BIG::new_ints(&rom::CURVE_GY);
+            let gy = Big::new_ints(&rom::CURVE_GY);
             G = ECP::new_bigs(&gx, &gy);
         } else {
             G = ECP::new_big(&gx);
diff --git a/src/ecp2.rs b/src/ecp2.rs
index afd9376..c705863 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -21,7 +21,7 @@ use super::rom;
 use super::big;
 use super::ecp;
 use super::fp2::FP2;
-use super::big::BIG;
+use super::big::Big;
 use types::{SexticTwist, CurvePairingType, SignOfX};
 use std::str::SplitWhitespace;
 use std::fmt;
@@ -259,21 +259,21 @@ impl ECP2 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = BIG::frombytes(&t);
+        let mut ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + mb]
         }
-        let mut rb = BIG::frombytes(&t);
+        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));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 3 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
         let ry = FP2::new_bigs(&ra, &rb);
 
         return ECP2::new_fp2s(&rx, &ry);
@@ -311,7 +311,7 @@ impl ECP2 {
     pub fn rhs(x: &FP2) -> FP2 {
         let mut r = FP2::new_copy(x);
         r.sqr();
-        let mut b = FP2::new_big(&BIG::new_ints(&rom::CURVE_B));
+        let mut b = FP2::new_big(&Big::new_ints(&rom::CURVE_B));
         if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
             b.div_ip();
         }
@@ -513,10 +513,10 @@ impl ECP2 {
     }
 
     /* self*=e */
-    pub fn mul(&self, e: &BIG) -> ECP2 {
+    pub fn mul(&self, e: &Big) -> ECP2 {
         /* fixed size windows */
-        let mut mt = BIG::new();
-        let mut t = BIG::new();
+        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();
@@ -594,7 +594,7 @@ impl ECP2 {
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
 
-    pub fn mul4(Q: &mut [ECP2], u: &[BIG]) -> ECP2 {
+    pub fn mul4(Q: &mut [ECP2], u: &[Big]) -> ECP2 {
         let mut W = ECP2::new();
         let mut P = ECP2::new();
 
@@ -609,13 +609,13 @@ impl ECP2 {
             ECP2::new(),
         ];
 
-        let mut mt = BIG::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]),
+        let mut t: [Big; 4] = [
+            Big::new_copy(&u[0]),
+            Big::new_copy(&u[1]),
+            Big::new_copy(&u[2]),
+            Big::new_copy(&u[3]),
         ];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
@@ -702,11 +702,11 @@ impl ECP2 {
 
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP2 {
-        let mut q = BIG::new_ints(&rom::MODULUS);
-        let mut x = BIG::frombytes(h);
+        let mut q = Big::new_ints(&rom::MODULUS);
+        let mut x = Big::frombytes(h);
         x.rmod(&mut q);
         let mut Q: ECP2;
-        let one = BIG::new_int(1);
+        let one = Big::new_int(1);
 
         loop {
             let X = FP2::new_bigs(&one, &x);
@@ -717,12 +717,12 @@ impl ECP2 {
             x.inc(1);
             x.norm();
         }
-        let mut X = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        let mut X = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
         if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
             X.inverse();
             X.norm();
         }
-        x = BIG::new_ints(&rom::CURVE_BNX);
+        x = Big::new_ints(&rom::CURVE_BNX);
 
         if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
             let mut T = Q.mul(&mut x);
@@ -772,12 +772,12 @@ impl ECP2 {
     pub fn generator() -> ECP2 {
         return ECP2::new_fp2s(
             &FP2::new_bigs(
-                &BIG::new_ints(&rom::CURVE_PXA),
-                &BIG::new_ints(&rom::CURVE_PXB),
+                &Big::new_ints(&rom::CURVE_PXA),
+                &Big::new_ints(&rom::CURVE_PXB),
             ),
             &FP2::new_bigs(
-                &BIG::new_ints(&rom::CURVE_PYA),
-                &BIG::new_ints(&rom::CURVE_PYB),
+                &Big::new_ints(&rom::CURVE_PYA),
+                &Big::new_ints(&rom::CURVE_PYB),
             ),
         );
     }
diff --git a/src/ecp4.rs b/src/ecp4.rs
index d34b0fd..b29b05d 100644
--- a/src/ecp4.rs
+++ b/src/ecp4.rs
@@ -22,7 +22,7 @@ use super::big;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
+use super::big::Big;
 use types::{SexticTwist, SignOfX};
 //use std::str::SplitWhitespace;
 
@@ -263,22 +263,22 @@ impl ECP4 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = BIG::frombytes(&t);
+        let mut ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + mb]
         }
-        let mut rb = BIG::frombytes(&t);
+        let mut rb = Big::frombytes(&t);
 
         let mut ra4 = FP2::new_bigs(&ra, &rb);
 
         for i in 0..mb {
             t[i] = b[i + 2 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 3 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         let mut rb4 = FP2::new_bigs(&ra, &rb);
 
@@ -287,22 +287,22 @@ impl ECP4 {
         for i in 0..mb {
             t[i] = b[i + 4 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 5 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         ra4.copy(&FP2::new_bigs(&ra, &rb));
 
         for i in 0..mb {
             t[i] = b[i + 6 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 7 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         rb4.copy(&FP2::new_bigs(&ra, &rb));
 
@@ -327,7 +327,7 @@ impl ECP4 {
         //x.norm();
         let mut r = FP4::new_copy(x);
         r.sqr();
-        let mut b = FP4::new_fp2(&FP2::new_big(&BIG::new_ints(&rom::CURVE_B)));
+        let mut b = FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B)));
         if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
             b.div_i();
         }
@@ -506,7 +506,7 @@ impl ECP4 {
     }
 
     pub fn frob_constants() -> [FP2; 3] {
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
 
         let mut f0 = FP2::new_copy(&f);
         f0.sqr();
@@ -546,10 +546,10 @@ impl ECP4 {
     }
 
     /* self*=e */
-    pub fn mul(&self, e: &BIG) -> ECP4 {
+    pub fn mul(&self, e: &Big) -> ECP4 {
         /* fixed size windows */
-        let mut mt = BIG::new();
-        let mut t = BIG::new();
+        let mut mt = Big::new();
+        let mut t = Big::new();
         let mut P = ECP4::new();
         let mut Q = ECP4::new();
         let mut C = ECP4::new();
@@ -627,7 +627,7 @@ impl ECP4 {
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
 
-    pub fn mul8(Q: &mut [ECP4], u: &[BIG]) -> ECP4 {
+    pub fn mul8(Q: &mut [ECP4], u: &[Big]) -> ECP4 {
         let mut W = ECP4::new();
         let mut P = ECP4::new();
 
@@ -652,17 +652,17 @@ impl ECP4 {
             ECP4::new(),
         ];
 
-        let mut mt = BIG::new();
-
-        let mut t: [BIG; 8] = [
-            BIG::new_copy(&u[0]),
-            BIG::new_copy(&u[1]),
-            BIG::new_copy(&u[2]),
-            BIG::new_copy(&u[3]),
-            BIG::new_copy(&u[4]),
-            BIG::new_copy(&u[5]),
-            BIG::new_copy(&u[6]),
-            BIG::new_copy(&u[7]),
+        let mut mt = Big::new();
+
+        let mut t: [Big; 8] = [
+            Big::new_copy(&u[0]),
+            Big::new_copy(&u[1]),
+            Big::new_copy(&u[2]),
+            Big::new_copy(&u[3]),
+            Big::new_copy(&u[4]),
+            Big::new_copy(&u[5]),
+            Big::new_copy(&u[6]),
+            Big::new_copy(&u[7]),
         ];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
@@ -788,22 +788,22 @@ impl ECP4 {
         return ECP4::new_fp4s(
             &FP4::new_fp2s(
                 &FP2::new_bigs(
-                    &BIG::new_ints(&rom::CURVE_PXAA),
-                    &BIG::new_ints(&rom::CURVE_PXAB),
+                    &Big::new_ints(&rom::CURVE_PXAA),
+                    &Big::new_ints(&rom::CURVE_PXAB),
                 ),
                 &FP2::new_bigs(
-                    &BIG::new_ints(&rom::CURVE_PXBA),
-                    &BIG::new_ints(&rom::CURVE_PXBB),
+                    &Big::new_ints(&rom::CURVE_PXBA),
+                    &Big::new_ints(&rom::CURVE_PXBB),
                 ),
             ),
             &FP4::new_fp2s(
                 &FP2::new_bigs(
-                    &BIG::new_ints(&rom::CURVE_PYAA),
-                    &BIG::new_ints(&rom::CURVE_PYAB),
+                    &Big::new_ints(&rom::CURVE_PYAA),
+                    &Big::new_ints(&rom::CURVE_PYAB),
                 ),
                 &FP2::new_bigs(
-                    &BIG::new_ints(&rom::CURVE_PYBA),
-                    &BIG::new_ints(&rom::CURVE_PYBB),
+                    &Big::new_ints(&rom::CURVE_PYBA),
+                    &Big::new_ints(&rom::CURVE_PYBB),
                 ),
             ),
         );
@@ -811,11 +811,11 @@ impl ECP4 {
 
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP4 {
-        let mut q = BIG::new_ints(&rom::MODULUS);
-        let mut x = BIG::frombytes(h);
+        let mut q = Big::new_ints(&rom::MODULUS);
+        let mut x = Big::frombytes(h);
         x.rmod(&mut q);
         let mut Q: ECP4;
-        let one = BIG::new_int(1);
+        let one = Big::new_int(1);
 
         loop {
             let X = FP4::new_fp2(&FP2::new_bigs(&one, &x));
@@ -828,7 +828,7 @@ impl ECP4 {
         }
 
         let f = ECP4::frob_constants();
-        x = BIG::new_ints(&rom::CURVE_BNX);
+        x = Big::new_ints(&rom::CURVE_BNX);
 
         let mut xQ = Q.mul(&mut x);
         let mut x2Q = xQ.mul(&mut x);
diff --git a/src/ecp8.rs b/src/ecp8.rs
index a6d32a4..18c8a30 100644
--- a/src/ecp8.rs
+++ b/src/ecp8.rs
@@ -23,7 +23,7 @@ use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::BIG;
+use super::big::Big;
 use types::{SexticTwist, SignOfX};
 
 pub struct ECP8 {
@@ -298,22 +298,22 @@ impl ECP8 {
         for i in 0..mb {
             t[i] = b[i]
         }
-        let mut ra = BIG::frombytes(&t);
+        let mut ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + mb]
         }
-        let mut rb = BIG::frombytes(&t);
+        let mut rb = Big::frombytes(&t);
 
         let mut ra4 = FP2::new_bigs(&ra, &rb);
 
         for i in 0..mb {
             t[i] = b[i + 2 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 3 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         let mut rb4 = FP2::new_bigs(&ra, &rb);
 
@@ -322,22 +322,22 @@ impl ECP8 {
         for i in 0..mb {
             t[i] = b[i + 4 * mb]
         }
-        let mut ra = BIG::frombytes(&t);
+        let mut ra = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = b[i + 5 * mb]
         }
-        let mut rb = BIG::frombytes(&t);
+        let mut rb = Big::frombytes(&t);
 
         ra4.copy(&FP2::new_bigs(&ra, &rb));
 
         for i in 0..mb {
             t[i] = b[i + 6 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 7 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         rb4.copy(&FP2::new_bigs(&ra, &rb));
 
@@ -348,22 +348,22 @@ impl ECP8 {
         for i in 0..mb {
             t[i] = b[i + 8 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 9 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         ra4.copy(&FP2::new_bigs(&ra, &rb));
 
         for i in 0..mb {
             t[i] = b[i + 10 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 11 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         rb4.copy(&FP2::new_bigs(&ra, &rb));
 
@@ -372,22 +372,22 @@ impl ECP8 {
         for i in 0..mb {
             t[i] = b[i + 12 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 13 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         ra4.copy(&FP2::new_bigs(&ra, &rb));
 
         for i in 0..mb {
             t[i] = b[i + 14 * mb]
         }
-        ra.copy(&BIG::frombytes(&t));
+        ra.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = b[i + 15 * mb]
         }
-        rb.copy(&BIG::frombytes(&t));
+        rb.copy(&Big::frombytes(&t));
 
         rb4.copy(&FP2::new_bigs(&ra, &rb));
 
@@ -413,7 +413,7 @@ impl ECP8 {
     pub fn rhs(x: &FP8) -> FP8 {
         let mut r = FP8::new_copy(x);
         r.sqr();
-        let mut b = FP8::new_fp4(&FP4::new_fp2(&FP2::new_big(&BIG::new_ints(&rom::CURVE_B))));
+        let mut b = FP8::new_fp4(&FP4::new_fp2(&FP2::new_big(&Big::new_ints(&rom::CURVE_B))));
         if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
             b.div_i();
         }
@@ -592,7 +592,7 @@ impl ECP8 {
     }
 
     pub fn frob_constants() -> [FP2; 3] {
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
 
         let mut f0 = FP2::new_copy(&f);
         f0.sqr();
@@ -648,10 +648,10 @@ impl ECP8 {
     }
 
     /* self*=e */
-    pub fn mul(&self, e: &BIG) -> ECP8 {
+    pub fn mul(&self, e: &Big) -> ECP8 {
         /* fixed size windows */
-        let mut mt = BIG::new();
-        let mut t = BIG::new();
+        let mut mt = Big::new();
+        let mut t = Big::new();
         let mut P = ECP8::new();
         let mut Q = ECP8::new();
         let mut C = ECP8::new();
@@ -729,7 +729,7 @@ impl ECP8 {
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
 
-    pub fn mul16(Q: &mut [ECP8], u: &[BIG]) -> ECP8 {
+    pub fn mul16(Q: &mut [ECP8], u: &[Big]) -> ECP8 {
         let mut W = ECP8::new();
         let mut P = ECP8::new();
 
@@ -774,25 +774,25 @@ impl ECP8 {
             ECP8::new(),
         ];
 
-        let mut mt = BIG::new();
-
-        let mut t: [BIG; 16] = [
-            BIG::new_copy(&u[0]),
-            BIG::new_copy(&u[1]),
-            BIG::new_copy(&u[2]),
-            BIG::new_copy(&u[3]),
-            BIG::new_copy(&u[4]),
-            BIG::new_copy(&u[5]),
-            BIG::new_copy(&u[6]),
-            BIG::new_copy(&u[7]),
-            BIG::new_copy(&u[8]),
-            BIG::new_copy(&u[9]),
-            BIG::new_copy(&u[10]),
-            BIG::new_copy(&u[11]),
-            BIG::new_copy(&u[12]),
-            BIG::new_copy(&u[13]),
-            BIG::new_copy(&u[14]),
-            BIG::new_copy(&u[15]),
+        let mut mt = Big::new();
+
+        let mut t: [Big; 16] = [
+            Big::new_copy(&u[0]),
+            Big::new_copy(&u[1]),
+            Big::new_copy(&u[2]),
+            Big::new_copy(&u[3]),
+            Big::new_copy(&u[4]),
+            Big::new_copy(&u[5]),
+            Big::new_copy(&u[6]),
+            Big::new_copy(&u[7]),
+            Big::new_copy(&u[8]),
+            Big::new_copy(&u[9]),
+            Big::new_copy(&u[10]),
+            Big::new_copy(&u[11]),
+            Big::new_copy(&u[12]),
+            Big::new_copy(&u[13]),
+            Big::new_copy(&u[14]),
+            Big::new_copy(&u[15]),
         ];
 
         const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
@@ -1031,44 +1031,44 @@ impl ECP8 {
             &FP8::new_fp4s(
                 &FP4::new_fp2s(
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PXAAA),
-                        &BIG::new_ints(&rom::CURVE_PXAAB),
+                        &Big::new_ints(&rom::CURVE_PXAAA),
+                        &Big::new_ints(&rom::CURVE_PXAAB),
                     ),
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PXABA),
-                        &BIG::new_ints(&rom::CURVE_PXABB),
+                        &Big::new_ints(&rom::CURVE_PXABA),
+                        &Big::new_ints(&rom::CURVE_PXABB),
                     ),
                 ),
                 &FP4::new_fp2s(
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PXBAA),
-                        &BIG::new_ints(&rom::CURVE_PXBAB),
+                        &Big::new_ints(&rom::CURVE_PXBAA),
+                        &Big::new_ints(&rom::CURVE_PXBAB),
                     ),
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PXBBA),
-                        &BIG::new_ints(&rom::CURVE_PXBBB),
+                        &Big::new_ints(&rom::CURVE_PXBBA),
+                        &Big::new_ints(&rom::CURVE_PXBBB),
                     ),
                 ),
             ),
             &FP8::new_fp4s(
                 &FP4::new_fp2s(
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PYAAA),
-                        &BIG::new_ints(&rom::CURVE_PYAAB),
+                        &Big::new_ints(&rom::CURVE_PYAAA),
+                        &Big::new_ints(&rom::CURVE_PYAAB),
                     ),
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PYABA),
-                        &BIG::new_ints(&rom::CURVE_PYABB),
+                        &Big::new_ints(&rom::CURVE_PYABA),
+                        &Big::new_ints(&rom::CURVE_PYABB),
                     ),
                 ),
                 &FP4::new_fp2s(
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PYBAA),
-                        &BIG::new_ints(&rom::CURVE_PYBAB),
+                        &Big::new_ints(&rom::CURVE_PYBAA),
+                        &Big::new_ints(&rom::CURVE_PYBAB),
                     ),
                     &FP2::new_bigs(
-                        &BIG::new_ints(&rom::CURVE_PYBBA),
-                        &BIG::new_ints(&rom::CURVE_PYBBB),
+                        &Big::new_ints(&rom::CURVE_PYBBA),
+                        &Big::new_ints(&rom::CURVE_PYBBB),
                     ),
                 ),
             ),
@@ -1077,11 +1077,11 @@ impl ECP8 {
 
     #[allow(non_snake_case)]
     pub fn mapit(h: &[u8]) -> ECP8 {
-        let mut q = BIG::new_ints(&rom::MODULUS);
-        let mut x = BIG::frombytes(h);
+        let mut q = Big::new_ints(&rom::MODULUS);
+        let mut x = Big::frombytes(h);
         x.rmod(&mut q);
         let mut Q: ECP8;
-        let one = BIG::new_int(1);
+        let one = Big::new_int(1);
 
         loop {
             let X = FP8::new_fp4(&FP4::new_fp2(&FP2::new_bigs(&one, &x)));
@@ -1094,7 +1094,7 @@ impl ECP8 {
         }
 
         let f = ECP8::frob_constants();
-        x = BIG::new_ints(&rom::CURVE_BNX);
+        x = Big::new_ints(&rom::CURVE_BNX);
 
         let mut xQ = Q.mul(&mut x);
         let mut x2Q = xQ.mul(&mut x);
diff --git a/src/ff.rs b/src/ff.rs
index 4737ee8..5855d88 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -18,20 +18,20 @@ under the License.
 */
 
 use super::big;
-use super::dbig::DBIG;
-use super::big::BIG;
+use super::dbig::DBig;
+use super::big::Big;
 use super::super::arch::Chunk;
 use rand::RAND;
 
 use super::super::arch::DChunk;
 
 /* Finite field support - for RSA, DH etc. */
-/* RSA/DH modulus length as multiple of BIGBITS */
+/* RSA/DH modulus length as multiple of BigBITS */
 
 pub use super::rom::FFLEN;
 //use std::str::SplitWhitespace;
 
-pub const FF_BITS: usize = (big::BIGBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
+pub const FF_BITS: usize = (big::BigBITS * FFLEN); /* Finite Field Size in bits - must be 256.2^n */
 pub const HFLEN: usize = (FFLEN / 2); /* Useful for half-size RSA private key operations */
 
 pub const P_MBITS: usize = (big::MODBYTES as usize) * 8;
@@ -40,16 +40,16 @@ pub const P_FEXCESS: Chunk = (1 << (big::BASEBITS * big::NLEN - P_MBITS - 1));
 pub const P_TBITS: usize = (P_MBITS % big::BASEBITS);
 
 pub struct FF {
-    v: Vec<BIG>,
+    v: Vec<Big>,
     length: usize,
 }
 
 impl FF {
-    pub fn excess(a: &BIG) -> Chunk {
+    pub fn excess(a: &Big) -> Chunk {
         return ((a.w[big::NLEN - 1] & P_OMASK) >> (P_TBITS)) + 1;
     }
 
-    pub fn pexceed(a: &BIG, b: &BIG) -> bool {
+    pub fn pexceed(a: &Big, b: &Big) -> bool {
         let ea = FF::excess(a);
         let eb = FF::excess(b);
         if ((ea + 1) as DChunk) * ((eb + 1) as DChunk) > P_FEXCESS as DChunk {
@@ -58,7 +58,7 @@ impl FF {
         return false;
     }
 
-    pub fn sexceed(a: &BIG) -> bool {
+    pub fn sexceed(a: &Big) -> bool {
         let ea = FF::excess(a);
         if ((ea + 1) as DChunk) * ((ea + 1) as DChunk) > P_FEXCESS as DChunk {
             return true;
@@ -73,7 +73,7 @@ impl FF {
             length: 0,
         };
         for _ in 0..n {
-            f.v.push(BIG::new());
+            f.v.push(Big::new());
         }
         f.length = n;
         return f;
@@ -142,9 +142,9 @@ impl FF {
         return true;
     }
 
-    /* shift right by BIGBITS-bit words */
+    /* shift right by BigBITS-bit words */
     pub fn shrw(&mut self, n: usize) {
-        let mut t = BIG::new();
+        let mut t = Big::new();
         for i in 0..n {
             t.copy(&self.v[i + n]);
             self.v[i].copy(&t);
@@ -152,9 +152,9 @@ impl FF {
         }
     }
 
-    /* shift left by BIGBITS-bit words */
+    /* shift left by BigBITS-bit words */
     pub fn shlw(&mut self, n: usize) {
-        let mut t = BIG::new();
+        let mut t = Big::new();
         for i in 0..n {
             t.copy(&self.v[i]);
             self.v[n + i].copy(&t);
@@ -176,7 +176,7 @@ impl FF {
         let mut i = a.length - 1;
 
         loop {
-            let j = BIG::comp(&a.v[i], &b.v[i]);
+            let j = Big::comp(&a.v[i], &b.v[i]);
             if j != 0 {
                 return j;
             }
@@ -204,7 +204,7 @@ impl FF {
     }
 
     pub fn rsinc(&mut self, n: usize) {
-        let mut t = BIG::new();
+        let mut t = Big::new();
         for i in 0..n {
             t.copy(&self.v[i]);
             self.v[n + i].add(&t);
@@ -333,7 +333,7 @@ impl FF {
 
     pub fn frombytes(x: &mut FF, b: &[u8]) {
         for i in 0..x.length {
-            x.v[i] = BIG::frombytearray(b, (x.length - i - 1) * (big::MODBYTES as usize))
+            x.v[i] = Big::frombytearray(b, (x.length - i - 1) * (big::MODBYTES as usize))
         }
     }
 
@@ -357,9 +357,9 @@ impl FF {
         n: usize,
     ) {
         if n == 1 {
-            let xx = BIG::new_copy(&x.v[xp]);
-            let yy = BIG::new_copy(&y.v[yp]);
-            let mut d = BIG::mul(&xx, &yy);
+            let xx = Big::new_copy(&x.v[xp]);
+            let yy = Big::new_copy(&y.v[yp]);
+            let mut d = Big::mul(&xx, &yy);
             self.v[vp + 1] = d.split(8 * big::MODBYTES);
             self.v[vp].dcopy(&d);
             return;
@@ -384,8 +384,8 @@ impl FF {
 
     fn karsqr(&mut self, vp: usize, x: &FF, xp: usize, t: *mut FF, tp: usize, n: usize) {
         if n == 1 {
-            let xx = BIG::new_copy(&x.v[xp]);
-            let mut d = BIG::sqr(&xx);
+            let xx = Big::new_copy(&x.v[xp]);
+            let mut d = Big::sqr(&xx);
             self.v[vp + 1].copy(&d.split(8 * big::MODBYTES));
             self.v[vp].dcopy(&d);
             return;
@@ -416,7 +416,7 @@ impl FF {
     ) {
         if n == 1 {
             /* only calculate bottom half of product */
-            self.v[vp].copy(&BIG::smul(&x.v[xp], &y.v[yp]));
+            self.v[vp].copy(&Big::smul(&x.v[xp], &y.v[yp]));
             return;
         }
         let nd2 = n / 2;
@@ -548,7 +548,7 @@ impl FF {
         x.copy(&self);
         x.norm();
         m.dsucopy(&b);
-        let mut k = big::BIGBITS * n;
+        let mut k = big::BigBITS * n;
 
         while FF::comp(&x, &m) >= 0 {
             x.sub(&m);
@@ -641,7 +641,7 @@ impl FF {
     pub fn nres(&mut self, m: &FF) {
         let n = m.length;
         if n == 1 {
-            let mut d = DBIG::new_scopy(&(self.v[0]));
+            let mut d = DBig::new_scopy(&(self.v[0]));
             d.shl(big::NLEN * (big::BASEBITS as usize));
             self.v[0].copy(&d.dmod(&(m.v[0])));
         } else {
@@ -654,8 +654,8 @@ impl FF {
     pub fn redc(&mut self, m: &FF, md: &FF) {
         let n = m.length;
         if n == 1 {
-            let mut d = DBIG::new_scopy(&(self.v[0]));
-            self.v[0].copy(&BIG::monty(
+            let mut d = DBig::new_scopy(&(self.v[0]));
+            self.v[0].copy(&Big::monty(
                 &(m.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - md.v[0].w[0],
                 &mut d,
@@ -720,11 +720,11 @@ impl FF {
     pub fn random(&mut self, rng: &mut RAND) {
         let n = self.length;
         for i in 0..n {
-            self.v[i].copy(&BIG::random(rng))
+            self.v[i].copy(&Big::random(rng))
         }
         /* make sure top bit is 1 */
         while self.v[n - 1].nbits() < (big::MODBYTES as usize) * 8 {
-            self.v[n - 1].copy(&BIG::random(rng));
+            self.v[n - 1].copy(&Big::random(rng));
         }
     }
 
@@ -734,7 +734,7 @@ impl FF {
         let mut d = FF::new_int(2 * n);
 
         for i in 0..2 * n {
-            d.v[i].copy(&BIG::random(rng));
+            d.v[i].copy(&Big::random(rng));
         }
         self.copy(&d.dmod(p));
     }
@@ -746,8 +746,8 @@ impl FF {
         }
         let n = p.length;
         if n == 1 {
-            let mut d = BIG::mul(&self.v[0], &y.v[0]);
-            self.v[0].copy(&BIG::monty(
+            let mut d = Big::mul(&self.v[0], &y.v[0]);
+            self.v[0].copy(&Big::monty(
                 &(p.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                 &mut d,
@@ -765,8 +765,8 @@ impl FF {
         }
         let n = p.length;
         if n == 1 {
-            let mut d = BIG::sqr(&self.v[0]);
-            self.v[0].copy(&BIG::monty(
+            let mut d = Big::sqr(&self.v[0]);
+            self.v[0].copy(&Big::monty(
                 &(p.v[0]),
                 ((1 as Chunk) << big::BASEBITS) - nd.v[0].w[0],
                 &mut d,
@@ -793,7 +793,7 @@ impl FF {
 
         let mut i = 8 * (big::MODBYTES as usize) * n - 1;
         loop {
-            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
+            let b = (e.v[i / (big::BigBITS as usize)]).bit(i % (big::BigBITS as usize)) as isize;
             self.copy(&r0);
             self.modmul(&r1, p, &nd);
 
@@ -812,7 +812,7 @@ impl FF {
     }
 
     /* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
-    pub fn skpows(&mut self, e: &BIG, p: &FF) {
+    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);
@@ -892,7 +892,7 @@ impl FF {
         let mut i = 8 * (big::MODBYTES as usize) * n - 1;
         loop {
             self.modsqr(p, &nd);
-            let b = (e.v[i / (big::BIGBITS as usize)]).bit(i % (big::BIGBITS as usize)) as isize;
+            let b = (e.v[i / (big::BigBITS as usize)]).bit(i % (big::BigBITS as usize)) as isize;
             if b == 1 {
                 self.modmul(&w, p, &nd)
             }
@@ -905,7 +905,7 @@ impl FF {
     }
 
     /* double exponentiation r=x^e.y^f mod p */
-    pub fn pow2(&mut self, e: &BIG, y: &FF, f: &BIG, p: &FF) {
+    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);
diff --git a/src/fp.rs b/src/fp.rs
index 57345c1..205d8d6 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -18,8 +18,8 @@ under the License.
 */
 
 use super::big;
-use super::big::BIG;
-use super::dbig::DBIG;
+use super::big::Big;
+use super::dbig::DBig;
 use super::rom;
 use super::super::arch::Chunk;
 use super::super::arch;
@@ -28,7 +28,7 @@ use std::str::FromStr;
 
 #[derive(Copy, Clone)]
 pub struct FP {
-    pub x: BIG,
+    pub x: Big,
     pub xes: i32,
 }
 
@@ -63,7 +63,7 @@ impl FP {
     /* Constructors */
     pub fn new() -> FP {
         FP {
-            x: BIG::new(),
+            x: Big::new(),
             xes: 1,
         }
     }
@@ -82,7 +82,7 @@ impl FP {
         return f;
     }
 
-    pub fn new_big(y: &BIG) -> FP {
+    pub fn new_big(y: &Big) -> FP {
         let mut f = FP::new();
         f.x.copy(y);
         f.nres();
@@ -91,8 +91,8 @@ impl FP {
 
     pub fn nres(&mut self) {
         if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let r=BIG::new_ints(&rom::R2MODP);
-            let mut d=BIG::mul(&(self.x),&r);
+            let r=Big::new_ints(&rom::R2MODP);
+            let mut d=Big::mul(&(self.x),&r);
             self.x.copy(&FP::modulo(&mut d));
             self.xes = 2;
         } else {
@@ -104,7 +104,7 @@ impl FP {
         let xes = i32::from_str(iter.next().unwrap()).unwrap();
         let x = iter.next().unwrap();
         FP {
-            x: BIG::from_hex(x.to_string()),
+            x: Big::from_hex(x.to_string()),
             xes
         }
     }
@@ -121,21 +121,21 @@ impl FP {
     }
 
 /* convert back to regular form */
-    pub fn redc(&mut self) -> BIG {
+    pub fn redc(&mut self) -> Big {
         if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let mut d=DBIG::new_scopy(&(self.x));
+            let mut d=DBig::new_scopy(&(self.x));
             return FP::modulo(&mut d);
         } else {
-            let r = BIG::new_copy(&(self.x));
+            let r = Big::new_copy(&(self.x));
             return r;
         }
     }
 
-    /* reduce a DBIG to a BIG using the appropriate form of the modulus */
+    /* reduce a DBig to a Big using the appropriate form of the modulus */
     /* dd */
-    pub fn modulo(d: &mut DBIG) -> BIG {
+    pub fn modulo(d: &mut DBig) -> Big {
         if MODTYPE==ModType::PSEUDO_MERSENNE {
-            let mut b=BIG::new();
+            let mut b=Big::new();
             let mut t=d.split(MODBITS);
             b.dcopy(&d);
             let v = t.pmul(rom::MCONST as isize);
@@ -149,13 +149,13 @@ impl FP {
             t.norm();
             return t;
         }
-    
+
         if MODTYPE==ModType::MONTGOMERY_FRIENDLY {
-            let mut b = BIG::new();
+            let mut b = Big::new();
             for i in 0..big::NLEN {
                 let x = d.w[i];
 
-                let tuple = BIG::muladd(x, rom::MCONST - 1, x, d.w[big::NLEN + i - 1]);
+                let tuple = Big::muladd(x, rom::MCONST - 1, x, d.w[big::NLEN + i - 1]);
                 d.w[big::NLEN + i] += tuple.0;
                 d.w[big::NLEN + i - 1] = tuple.1;
             }
@@ -171,16 +171,16 @@ impl FP {
 
         if MODTYPE == ModType::GENERALISED_MERSENNE {
             // GoldiLocks Only
-            let mut b = BIG::new();
+            let mut b = Big::new();
             let t = d.split(MODBITS);
             let rm2 = (MODBITS / 2) as usize;
             b.dcopy(&d);
             b.add(&t);
-            let mut dd = DBIG::new_scopy(&t);
+            let mut dd = DBig::new_scopy(&t);
             dd.shl(rm2);
 
             let mut tt = dd.split(MODBITS);
-            let lo = BIG::new_dcopy(&dd);
+            let lo = Big::new_dcopy(&dd);
             b.add(&tt);
             b.add(&lo);
             b.norm();
@@ -196,10 +196,10 @@ impl FP {
             return b;
         }
         if MODTYPE == ModType::NOT_SPECIAL {
-            let m = BIG::new_ints(&rom::MODULUS);
-            return BIG::monty(&m, rom::MCONST, d);
+            let m = Big::new_ints(&rom::MODULUS);
+            return Big::monty(&m, rom::MCONST, d);
         }
-        return BIG::new();
+        return Big::new();
     }
 
     /* convert to string */
@@ -210,8 +210,8 @@ impl FP {
 
     /* reduce this mod Modulus */
     pub fn reduce(&mut self) {
-        let mut m = BIG::new_ints(&rom::MODULUS);
-        let mut r = BIG::new_copy(&m);
+        let mut m = Big::new_ints(&rom::MODULUS);
+        let mut r = Big::new_copy(&m);
         let mut sb: usize;
         self.x.norm();
         if self.xes > 16 {
@@ -227,7 +227,7 @@ impl FP {
         m.fshl(sb);
 
         while sb > 0 {
-            let sr = BIG::ssn(&mut r, &self.x, &mut m);
+            let sr = Big::ssn(&mut r, &self.x, &mut m);
             self.x.cmove(&r, 1 - sr);
             sb = sb - 1;
         }
@@ -248,8 +248,8 @@ impl FP {
         self.xes = b.xes;
     }
 
-    /* copy from BIG b */
-    pub fn bcopy(&mut self, b: &BIG) {
+    /* copy from Big b */
+    pub fn bcopy(&mut self, b: &Big) {
         self.x.copy(&b);
         self.nres();
     }
@@ -293,7 +293,7 @@ impl FP {
             self.reduce()
         }
 
-        let mut d = BIG::mul(&(self.x), &(b.x));
+        let mut d = Big::mul(&(self.x), &(b.x));
         self.x.copy(&FP::modulo(&mut d));
         self.xes = 2;
     }
@@ -315,7 +315,7 @@ impl FP {
     // find approximation to quotient of a/m
     // Out by at most 2.
     // Note that MAXXES is bounded to be 2-bits less than half a word
-    fn quo(n: &BIG, m: &BIG) -> isize {
+    fn quo(n: &Big, m: &Big) -> isize {
         let hb = arch::CHUNK / 2;
 
         if TBITS < hb {
@@ -332,7 +332,7 @@ impl FP {
 
     /* this = -this mod Modulus */
     pub fn neg(&mut self) {
-        let mut p = BIG::new_ints(&rom::MODULUS);
+        let mut p = Big::new_ints(&rom::MODULUS);
         let sb = FP::logb2((self.xes - 1) as u32);
 
         p.fshl(sb);
@@ -378,7 +378,7 @@ impl FP {
             self.reduce()
         }
 
-        let mut d = BIG::sqr(&(self.x));
+        let mut d = Big::sqr(&(self.x));
         self.x.copy(&FP::modulo(&mut d));
         self.xes = 2
     }
@@ -419,7 +419,7 @@ impl FP {
         if self.x.parity() == 0 {
             self.x.fshr(1);
         } else {
-            let p = BIG::new_ints(&rom::MODULUS);
+            let p = Big::new_ints(&rom::MODULUS);
             self.x.add(&p);
             self.x.norm();
             self.x.fshr(1);
@@ -592,7 +592,7 @@ impl FP {
         } else {
             // Constant time inversion using Fermat's little theorem.
             // Fermat's little theorem says for a prime p and for any a < p, a^p = a % p => a^(p-1) = 1 % p => a^(p-2) = a^-1 % p
-            let mut m2 = BIG::new_ints(&rom::MODULUS);
+            let mut m2 = Big::new_ints(&rom::MODULUS);
             m2.dec(2);
             m2.norm();
             let inv = self.pow(&mut m2);
@@ -606,14 +606,14 @@ impl FP {
         let mut s = FP::new_copy(a);
         f.reduce();
         s.reduce();
-        if BIG::comp(&(f.x), &(s.x)) == 0 {
+        if Big::comp(&(f.x), &(s.x)) == 0 {
             return true;
         }
         return false;
     }
 
     /* return self^e mod Modulus */
-    pub fn pow(&mut self, e: &mut BIG) -> FP {
+    pub fn pow(&mut self, e: &mut Big) -> FP {
         let mut tb: [FP; 16] = [
             FP::new(),
             FP::new(),
@@ -636,7 +636,7 @@ impl FP {
         let mut w: [i8; CT] = [0; CT];
 
         self.norm();
-        let mut t = BIG::new_copy(e);
+        let mut t = Big::new_copy(e);
         t.norm();
         let nb = 1 + (t.nbits() + 3) / 4;
 
@@ -679,7 +679,7 @@ impl FP {
             if MODTYPE == ModType::PSEUDO_MERSENNE || MODTYPE == ModType::GENERALISED_MERSENNE {
                 v = i.fpow();
             } else {
-                let mut p = BIG::new_ints(&rom::MODULUS);
+                let mut p = Big::new_ints(&rom::MODULUS);
                 p.dec(5);
                 p.norm();
                 p.shr(3);
@@ -699,7 +699,7 @@ impl FP {
                 r = self.fpow();
                 r.mul(self);
             } else {
-                let mut p = BIG::new_ints(&rom::MODULUS);
+                let mut p = Big::new_ints(&rom::MODULUS);
                 p.inc(1);
                 p.norm();
                 p.shr(2);
@@ -710,7 +710,7 @@ impl FP {
     }
     /* return jacobi symbol (this/Modulus) */
     pub fn jacobi(&mut self) -> isize {
-        let mut p = BIG::new_ints(&rom::MODULUS);
+        let mut p = Big::new_ints(&rom::MODULUS);
         let mut w = self.redc();
         return w.jacobi(&mut p);
     }
diff --git a/src/fp12.rs b/src/fp12.rs
index 9c06a3e..311fe87 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -20,7 +20,7 @@ under the License.
 use super::big;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
+use super::big::Big;
 use super::rom;
 use types::SexticTwist;
 use std::str::SplitWhitespace;
@@ -425,7 +425,7 @@ impl FP12 {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
+            } else {
                z2.copy(&self.b);
                z2.mul(&y.b);
             }
@@ -442,7 +442,7 @@ impl FP12 {
 
             t0.copy(&z0); t0.neg();
             t1.copy(&z2); t1.neg();
- 
+
             z1.add(&t0);
             self.b.copy(&z1); self.b.add(&t1);
 
@@ -451,7 +451,7 @@ impl FP12 {
 
             t0.copy(&self.a); t0.add(&self.c); t0.norm();
             t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+
             t0.mul(&t1);
             z2.add(&t0);
 
@@ -477,7 +477,7 @@ impl FP12 {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
@@ -495,7 +495,7 @@ impl FP12 {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
+            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
                 let mut z0=FP4::new_copy(&self.a);
                 let mut z2=FP4::new_copy(&self.b);
                 let mut z3=FP4::new_copy(&self.b);
@@ -539,7 +539,7 @@ impl FP12 {
                 let mut z3 = FP4::new();
                 let mut t0 = FP4::new_copy(&self.a);
                 let mut t1 = FP4::new();
-	
+
                 z0.mul(&y.a);
                 t0.add(&self.b); t0.norm();
 
@@ -562,7 +562,7 @@ impl FP12 {
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
                 t1.copy(&t0); t1.neg();
@@ -574,7 +574,7 @@ impl FP12 {
                 z3.norm();
                 z3.times_i();
                 self.a.copy(&z0); self.a.add(&z3);
-           }	
+           }
         }
         self.stype=DENSE;
         self.norm();
@@ -582,7 +582,7 @@ impl FP12 {
 
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP12) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
+        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
             let mut w1=FP2::new_copy(&self.a.geta());
             let mut w2=FP2::new_copy(&self.a.getb());
             let mut w3=FP2::new_copy(&self.b.geta());
@@ -626,7 +626,7 @@ impl FP12 {
 	    self.a.set_fp2s(&w1,&tc);
 	    self.b.set_fp2s(&td,&te);
 	    self.c.set_fp2(&w3);
-           
+
             self.a.norm();
             self.b.norm();
         } else {
@@ -767,21 +767,21 @@ impl FP12 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = BIG::frombytes(&t);
+        let mut a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + mb]
         }
-        let mut b = BIG::frombytes(&t);
+        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);
+        a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 3 * mb]
         }
-        b = BIG::frombytes(&t);
+        b = Big::frombytes(&t);
         let mut d = FP2::new_bigs(&a, &b);
 
         let e = FP4::new_fp2s(&c, &d);
@@ -789,21 +789,21 @@ impl FP12 {
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a = BIG::frombytes(&t);
+        a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 5 * mb]
         }
-        b = BIG::frombytes(&t);
+        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);
+        a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 7 * mb]
         }
-        b = BIG::frombytes(&t);
+        b = Big::frombytes(&t);
         d = FP2::new_bigs(&a, &b);
 
         let f = FP4::new_fp2s(&c, &d);
@@ -811,22 +811,22 @@ impl FP12 {
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        a = BIG::frombytes(&t);
+        a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        b = BIG::frombytes(&t);
+        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);
+        a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 11 * mb]
         }
-        b = BIG::frombytes(&t);
+        b = Big::frombytes(&t);
         d = FP2::new_bigs(&a, &b);
 
         let g = FP4::new_fp2s(&c, &d);
@@ -920,12 +920,12 @@ impl FP12 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP12 {
+    pub fn pow(&self, e: &Big) -> FP12 {
         let mut r = FP12::new_copy(self);
         r.norm();
-        let mut e1 = BIG::new_copy(e);
+        let mut e1 = Big::new_copy(e);
         e1.norm();
-        let mut e3 = BIG::new_copy(&e1);
+        let mut e3 = Big::new_copy(&e1);
         e3.pmul(3);
         e3.norm();
         let mut w = FP12::new_copy(&r);
@@ -962,20 +962,20 @@ impl FP12 {
         self.copy(&r[0]);
     }
 
-    pub fn compow(&mut self, e: &BIG, r: &BIG) -> FP4 {
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::MODULUS);
+    pub fn compow(&mut self, e: &Big, r: &Big) -> FP4 {
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::MODULUS);
 
         let mut g1 = FP12::new_copy(self);
         let mut g2 = FP12::new_copy(self);
 
-        let mut m = BIG::new_copy(&q);
+        let mut m = Big::new_copy(&q);
         m.rmod(&r);
 
-        let mut a = BIG::new_copy(&e);
+        let mut a = Big::new_copy(&e);
         a.rmod(&mut m);
 
-        let mut b = BIG::new_copy(&e);
+        let mut b = Big::new_copy(&e);
         b.div(&mut m);
 
         let mut c = g1.trace();
@@ -1002,7 +1002,7 @@ impl FP12 {
     // Bos & Costello https://eprint.iacr.org/2013/458.pdf
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
-    pub fn pow4(q: &[FP12], u: &[BIG]) -> FP12 {
+    pub fn pow4(q: &[FP12], u: &[Big]) -> FP12 {
         let mut g: [FP12; 8] = [
             FP12::new(),
             FP12::new(),
@@ -1020,12 +1020,12 @@ impl FP12 {
         let mut w: [i8; CT] = [0; CT];
         let mut s: [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]),
+        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]),
         ];
 
         for i in 0..4 {
diff --git a/src/fp16.rs b/src/fp16.rs
index c579db4..2c4e976 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -19,7 +19,7 @@ under the License.
 
 use super::fp2::FP2;
 use super::fp8::FP8;
-use super::big::BIG;
+use super::big::Big;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -349,10 +349,10 @@ impl FP16 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP16 {
+    pub fn pow(&self, e: &Big) -> FP16 {
         let mut w = FP16::new_copy(self);
         w.norm();
-        let mut z = BIG::new_copy(&e);
+        let mut z = Big::new_copy(&e);
         let mut r = FP16::new_int(1);
         z.norm();
         loop {
@@ -401,7 +401,7 @@ impl FP16 {
     }
 
     /* r=x^n using XTR method on traces of FP24s */
-    pub fn xtr_pow(&self, n: &BIG) -> FP16 {
+    pub fn xtr_pow(&self, n: &Big) -> FP16 {
         let mut sf = FP16::new_copy(self);
         sf.norm();
         let mut a = FP16::new_int(3);
@@ -412,7 +412,7 @@ impl FP16 {
         let mut r = FP16::new();
 
         let par = n.parity();
-        let mut v = BIG::new_copy(n);
+        let mut v = Big::new_copy(n);
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -450,10 +450,10 @@ impl FP16 {
     }
 
     /* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
-    pub fn xtr_pow2(&mut self, ck: &FP16, ckml: &FP16, ckm2l: &FP16, a: &BIG, b: &BIG) -> FP16 {
-        let mut e = BIG::new_copy(a);
-        let mut d = BIG::new_copy(b);
-        let mut w = BIG::new();
+    pub fn xtr_pow2(&mut self, ck: &FP16, ckml: &FP16, ckm2l: &FP16, a: &Big, b: &Big) -> FP16 {
+        let mut e = Big::new_copy(a);
+        let mut d = Big::new_copy(b);
+        let mut w = Big::new();
         d.norm();
         e.norm();
 
@@ -471,12 +471,12 @@ impl FP16 {
             f2 += 1;
         }
 
-        while BIG::comp(&d, &e) != 0 {
-            if BIG::comp(&d, &e) > 0 {
+        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 {
+                if Big::comp(&d, &w) <= 0 {
                     w.copy(&d);
                     d.copy(&e);
                     e.rsub(&w);
@@ -531,11 +531,11 @@ impl FP16 {
                     }
                 }
             }
-            if BIG::comp(&d, &e) < 0 {
+            if Big::comp(&d, &e) < 0 {
                 w.copy(&d);
                 w.imul(4);
                 w.norm();
-                if BIG::comp(&e, &w) <= 0 {
+                if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
                     t.copy(&cv);
diff --git a/src/fp2.rs b/src/fp2.rs
index c848f19..060b9de 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -19,8 +19,8 @@ under the License.
 
 use super::fp;
 use super::fp::FP;
-use super::big::BIG;
-use super::dbig::DBIG;
+use super::big::Big;
+use super::dbig::DBig;
 use super::rom;
 use std::str::SplitWhitespace;
 use std::fmt;
@@ -78,7 +78,7 @@ impl FP2 {
         return f;
     }
 
-    pub fn new_bigs(c: &BIG, d: &BIG) -> FP2 {
+    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));
@@ -92,7 +92,7 @@ impl FP2 {
         return f;
     }
 
-    pub fn new_big(c: &BIG) -> FP2 {
+    pub fn new_big(c: &Big) -> FP2 {
         let mut f = FP2::new();
         f.a.copy(&FP::new_big(c));
         f.b.zero();
@@ -133,12 +133,12 @@ impl FP2 {
     }
 
     /* extract a */
-    pub fn geta(&mut self) -> BIG {
+    pub fn geta(&mut self) -> Big {
         return self.a.redc();
     }
 
     /* extract b */
-    pub fn getb(&mut self) -> BIG {
+    pub fn getb(&mut self) -> Big {
         return self.b.redc();
     }
 
@@ -248,24 +248,24 @@ impl FP2 {
             }
         }
 
-        let p = BIG::new_ints(&rom::MODULUS);
-        let mut pr = DBIG::new();
+        let p = Big::new_ints(&rom::MODULUS);
+        let mut pr = DBig::new();
 
         pr.ucopy(&p);
 
-        let mut c = BIG::new_copy(&(self.a.x));
-        let mut d = BIG::new_copy(&(y.a.x));
+        let mut c = Big::new_copy(&(self.a.x));
+        let mut d = Big::new_copy(&(y.a.x));
 
-        let mut a = BIG::mul(&self.a.x, &y.a.x);
-        let mut b = BIG::mul(&self.b.x, &y.b.x);
+        let mut a = Big::mul(&self.a.x, &y.a.x);
+        let mut b = Big::mul(&self.b.x, &y.b.x);
 
         c.add(&self.b.x);
         c.norm();
         d.add(&y.b.x);
         d.norm();
 
-        let mut e = BIG::mul(&c, &d);
-        let mut f = DBIG::new_copy(&a);
+        let mut e = Big::mul(&c, &d);
+        let mut f = DBig::new_copy(&a);
         f.add(&b);
         b.rsub(&pr);
 
diff --git a/src/fp24.rs b/src/fp24.rs
index 5f154b3..3deb850 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -22,7 +22,7 @@ use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::BIG;
+use super::big::Big;
 use super::rom;
 use types::{SexticTwist};
 //use std::str::SplitWhitespace;
@@ -418,7 +418,7 @@ impl FP24 {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
+            } else {
                z2.copy(&self.b);
                z2.mul(&y.b);
             }
@@ -435,7 +435,7 @@ impl FP24 {
 
             t0.copy(&z0); t0.neg();
             t1.copy(&z2); t1.neg();
- 
+
             z1.add(&t0);
             self.b.copy(&z1); self.b.add(&t1);
 
@@ -444,7 +444,7 @@ impl FP24 {
 
             t0.copy(&self.a); t0.add(&self.c); t0.norm();
             t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+
             t0.mul(&t1);
             z2.add(&t0);
 
@@ -470,7 +470,7 @@ impl FP24 {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
@@ -488,7 +488,7 @@ impl FP24 {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
+            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
                 let mut z0=FP8::new_copy(&self.a);
                 let mut z2=FP8::new_copy(&self.b);
                 let mut z3=FP8::new_copy(&self.b);
@@ -532,7 +532,7 @@ impl FP24 {
                 let mut z3 = FP8::new();
                 let mut t0 = FP8::new_copy(&self.a);
                 let mut t1 = FP8::new();
-	
+
                 z0.mul(&y.a);
                 t0.add(&self.b); t0.norm();
 
@@ -555,7 +555,7 @@ impl FP24 {
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
                 t1.copy(&t0); t1.neg();
@@ -567,7 +567,7 @@ impl FP24 {
                 z3.norm();
                 z3.times_i();
                 self.a.copy(&z0); self.a.add(&z3);
-           }	
+           }
         }
         self.stype=DENSE;
         self.norm();
@@ -576,7 +576,7 @@ impl FP24 {
 
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP24) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
+        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
             let mut w1=FP4::new_copy(&self.a.geta());
             let mut w2=FP4::new_copy(&self.a.getb());
             let mut w3=FP4::new_copy(&self.b.geta());
@@ -769,21 +769,21 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = BIG::frombytes(&t);
+        let mut a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + mb]
         }
-        let mut b = BIG::frombytes(&t);
+        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.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 3 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         let mut d = FP2::new_bigs(&a, &b);
 
         let mut ea = FP4::new_fp2s(&c, &d);
@@ -791,21 +791,21 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 5 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 6 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 7 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         let mut eb = FP4::new_fp2s(&c, &d);
@@ -815,21 +815,21 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 10 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 11 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -837,21 +837,21 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i + 12 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 13 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 14 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 15 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -861,22 +861,22 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i + 16 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 17 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 18 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 19 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -884,22 +884,22 @@ impl FP24 {
         for i in 0..mb {
             t[i] = w[i + 20 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 21 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 22 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 23 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -1028,12 +1028,12 @@ impl FP24 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP24 {
+    pub fn pow(&self, e: &Big) -> FP24 {
         let mut r = FP24::new_copy(self);
         r.norm();
-        let mut e1 = BIG::new_copy(e);
+        let mut e1 = Big::new_copy(e);
         e1.norm();
-        let mut e3 = BIG::new_copy(&e1);
+        let mut e3 = Big::new_copy(&e1);
         e3.pmul(3);
         e3.norm();
         let mut w = FP24::new_copy(&r);
@@ -1070,20 +1070,20 @@ impl FP24 {
         self.copy(&r[0]);
     }
 
-    pub fn compow(&mut self, e: &BIG, r: &BIG) -> FP8 {
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::MODULUS);
+    pub fn compow(&mut self, e: &Big, r: &Big) -> FP8 {
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::MODULUS);
 
         let mut g1 = FP24::new_copy(self);
         let mut g2 = FP24::new_copy(self);
 
-        let mut m = BIG::new_copy(&q);
+        let mut m = Big::new_copy(&q);
         m.rmod(&r);
 
-        let mut a = BIG::new_copy(&e);
+        let mut a = Big::new_copy(&e);
         a.rmod(&mut m);
 
-        let mut b = BIG::new_copy(&e);
+        let mut b = Big::new_copy(&e);
         b.div(&mut m);
 
         let mut c = g1.trace();
@@ -1110,7 +1110,7 @@ impl FP24 {
     // Bos & Costello https://eprint.iacr.org/2013/458.pdf
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
-    pub fn pow8(q: &[FP24], u: &[BIG]) -> FP24 {
+    pub fn pow8(q: &[FP24], u: &[Big]) -> FP24 {
         let mut g1: [FP24; 8] = [
             FP24::new(),
             FP24::new(),
@@ -1140,16 +1140,16 @@ impl FP24 {
         let mut w2: [i8; CT] = [0; CT];
         let mut s2: [i8; CT] = [0; CT];
 
-        let mut mt = BIG::new();
-        let mut t: [BIG; 8] = [
-            BIG::new_copy(&u[0]),
-            BIG::new_copy(&u[1]),
-            BIG::new_copy(&u[2]),
-            BIG::new_copy(&u[3]),
-            BIG::new_copy(&u[4]),
-            BIG::new_copy(&u[5]),
-            BIG::new_copy(&u[6]),
-            BIG::new_copy(&u[7]),
+        let mut mt = Big::new();
+        let mut t: [Big; 8] = [
+            Big::new_copy(&u[0]),
+            Big::new_copy(&u[1]),
+            Big::new_copy(&u[2]),
+            Big::new_copy(&u[3]),
+            Big::new_copy(&u[4]),
+            Big::new_copy(&u[5]),
+            Big::new_copy(&u[6]),
+            Big::new_copy(&u[7]),
         ];
 
         for i in 0..8 {
@@ -1180,7 +1180,7 @@ impl FP24 {
         g1[7].mul(&q[3]); // q[0].q[1].q[2].q[3]
 
         // Use Frobenius
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
         for i in 0..8 {
             g2[i].copy(&g1[i]);
             g2[i].frob(&f, 4);
diff --git a/src/fp4.rs b/src/fp4.rs
index 1db4b73..d2d890b 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -19,7 +19,7 @@ under the License.
 
 use super::fp::FP;
 use super::fp2::FP2;
-use super::big::BIG;
+use super::big::Big;
 use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -69,7 +69,7 @@ impl FP4 {
         f.b.zero();
         return f;
     }
-	
+
     pub fn set_fp2s(&mut self,c: &FP2, d: &FP2) {
         self.a.copy(&c);
 	self.b.copy(&d);
@@ -360,10 +360,10 @@ impl FP4 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP4 {
+    pub fn pow(&self, e: &Big) -> FP4 {
         let mut w = FP4::new_copy(self);
         w.norm();
-        let mut z = BIG::new_copy(&e);
+        let mut z = Big::new_copy(&e);
         let mut r = FP4::new_int(1);
         z.norm();
         loop {
@@ -412,7 +412,7 @@ impl FP4 {
     }
 
     /* r=x^n using XTR method on traces of FP12s */
-    pub fn xtr_pow(&self, n: &BIG) -> FP4 {
+    pub fn xtr_pow(&self, n: &Big) -> FP4 {
         let mut sf = FP4::new_copy(self);
         sf.norm();
         let mut a = FP4::new_int(3);
@@ -423,7 +423,7 @@ impl FP4 {
         let mut r = FP4::new();
 
         let par = n.parity();
-        let mut v = BIG::new_copy(n);
+        let mut v = Big::new_copy(n);
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -461,10 +461,10 @@ impl FP4 {
     }
 
     /* 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: &BIG, b: &BIG) -> FP4 {
-        let mut e = BIG::new_copy(a);
-        let mut d = BIG::new_copy(b);
-        let mut w = BIG::new();
+    pub fn xtr_pow2(&mut self, ck: &FP4, ckml: &FP4, ckm2l: &FP4, a: &Big, b: &Big) -> FP4 {
+        let mut e = Big::new_copy(a);
+        let mut d = Big::new_copy(b);
+        let mut w = Big::new();
         e.norm();
         d.norm();
 
@@ -482,12 +482,12 @@ impl FP4 {
             f2 += 1;
         }
 
-        while BIG::comp(&d, &e) != 0 {
-            if BIG::comp(&d, &e) > 0 {
+        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 {
+                if Big::comp(&d, &w) <= 0 {
                     w.copy(&d);
                     d.copy(&e);
                     e.rsub(&w);
@@ -542,11 +542,11 @@ impl FP4 {
                     }
                 }
             }
-            if BIG::comp(&d, &e) < 0 {
+            if Big::comp(&d, &e) < 0 {
                 w.copy(&d);
                 w.imul(4);
                 w.norm();
-                if BIG::comp(&e, &w) <= 0 {
+                if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
                     t.copy(&cv);
diff --git a/src/fp48.rs b/src/fp48.rs
index c72ee4c..ff64d4c 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -23,7 +23,7 @@ use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
 use super::fp16::FP16;
-use super::big::BIG;
+use super::big::Big;
 use super::rom;
 use types::SexticTwist;
 //use std::str::SplitWhitespace;
@@ -418,7 +418,7 @@ impl FP48 {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
+            } else {
                z2.copy(&self.b);
                z2.mul(&y.b);
             }
@@ -435,7 +435,7 @@ impl FP48 {
 
             t0.copy(&z0); t0.neg();
             t1.copy(&z2); t1.neg();
- 
+
             z1.add(&t0);
             self.b.copy(&z1); self.b.add(&t1);
 
@@ -444,7 +444,7 @@ impl FP48 {
 
             t0.copy(&self.a); t0.add(&self.c); t0.norm();
             t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+
             t0.mul(&t1);
             z2.add(&t0);
 
@@ -470,7 +470,7 @@ impl FP48 {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
@@ -488,7 +488,7 @@ impl FP48 {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
+            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m
                 let mut z0=FP16::new_copy(&self.a);
                 let mut z2=FP16::new_copy(&self.b);
                 let mut z3=FP16::new_copy(&self.b);
@@ -532,7 +532,7 @@ impl FP48 {
                 let mut z3 = FP16::new();
                 let mut t0 = FP16::new_copy(&self.a);
                 let mut t1 = FP16::new();
-	
+
                 z0.mul(&y.a);
                 t0.add(&self.b); t0.norm();
 
@@ -555,7 +555,7 @@ impl FP48 {
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
                 t1.copy(&t0); t1.neg();
@@ -567,7 +567,7 @@ impl FP48 {
                 z3.norm();
                 z3.times_i();
                 self.a.copy(&z0); self.a.add(&z3);
-           }	
+           }
         }
         self.stype=DENSE;
         self.norm();
@@ -576,7 +576,7 @@ impl FP48 {
 
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP48) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
+        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
             let mut w1=FP8::new_copy(&self.a.geta());
             let mut w2=FP8::new_copy(&self.a.getb());
             let mut w3=FP8::new_copy(&self.b.geta());
@@ -773,21 +773,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i]
         }
-        let mut a = BIG::frombytes(&t);
+        let mut a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + mb]
         }
-        let mut b = BIG::frombytes(&t);
+        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.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 3 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         let mut d = FP2::new_bigs(&a, &b);
 
         let mut ea = FP4::new_fp2s(&c, &d);
@@ -795,21 +795,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 4 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 5 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 6 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 7 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         let mut eb = FP4::new_fp2s(&c, &d);
@@ -819,21 +819,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 8 * mb]
         }
-        let mut a = BIG::frombytes(&t);
+        let mut a = Big::frombytes(&t);
         for i in 0..mb {
             t[i] = w[i + 9 * mb]
         }
-        let mut b = BIG::frombytes(&t);
+        let mut b = Big::frombytes(&t);
         let mut c = FP2::new_bigs(&a, &b);
 
         for i in 0..mb {
             t[i] = w[i + 10 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 11 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         let mut d = FP2::new_bigs(&a, &b);
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -841,21 +841,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 12 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 13 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 14 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 15 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -867,21 +867,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 16 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 17 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 18 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 19 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -889,21 +889,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 20 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 21 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 22 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 23 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -913,21 +913,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 24 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 25 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 26 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 27 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -935,21 +935,21 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 28 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 29 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 30 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 31 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -961,22 +961,22 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 32 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 33 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 34 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 35 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -984,22 +984,22 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 36 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 37 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 38 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 39 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -1009,22 +1009,22 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 40 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 41 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 42 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 43 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         ea.copy(&FP4::new_fp2s(&c, &d));
@@ -1032,22 +1032,22 @@ impl FP48 {
         for i in 0..mb {
             t[i] = w[i + 44 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 45 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
 
         c.copy(&FP2::new_bigs(&a, &b));
 
         for i in 0..mb {
             t[i] = w[i + 46 * mb]
         }
-        a.copy(&BIG::frombytes(&t));
+        a.copy(&Big::frombytes(&t));
         for i in 0..mb {
             t[i] = w[i + 47 * mb]
         }
-        b.copy(&BIG::frombytes(&t));
+        b.copy(&Big::frombytes(&t));
         d.copy(&FP2::new_bigs(&a, &b));
 
         eb.copy(&FP4::new_fp2s(&c, &d));
@@ -1280,12 +1280,12 @@ impl FP48 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP48 {
+    pub fn pow(&self, e: &Big) -> FP48 {
         let mut r = FP48::new_copy(self);
         r.norm();
-        let mut e1 = BIG::new_copy(e);
+        let mut e1 = Big::new_copy(e);
         e1.norm();
-        let mut e3 = BIG::new_copy(&e1);
+        let mut e3 = Big::new_copy(&e1);
         e3.pmul(3);
         e3.norm();
         let mut w = FP48::new_copy(&r);
@@ -1322,20 +1322,20 @@ impl FP48 {
         self.copy(&r[0]);
     }
 
-    pub fn compow(&mut self, e: &BIG, r: &BIG) -> FP16 {
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::MODULUS);
+    pub fn compow(&mut self, e: &Big, r: &Big) -> FP16 {
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::MODULUS);
 
         let mut g1 = FP48::new_copy(self);
         let mut g2 = FP48::new_copy(self);
 
-        let mut m = BIG::new_copy(&q);
+        let mut m = Big::new_copy(&q);
         m.rmod(&r);
 
-        let mut a = BIG::new_copy(&e);
+        let mut a = Big::new_copy(&e);
         a.rmod(&mut m);
 
-        let mut b = BIG::new_copy(&e);
+        let mut b = Big::new_copy(&e);
         b.div(&mut m);
 
         let mut c = g1.trace();
@@ -1362,7 +1362,7 @@ impl FP48 {
     // Bos & Costello https://eprint.iacr.org/2013/458.pdf
     // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
     // Side channel attack secure
-    pub fn pow16(q: &[FP48], u: &[BIG]) -> FP48 {
+    pub fn pow16(q: &[FP48], u: &[Big]) -> FP48 {
         let mut g1: [FP48; 8] = [
             FP48::new(),
             FP48::new(),
@@ -1416,24 +1416,24 @@ impl FP48 {
         let mut w4: [i8; CT] = [0; CT];
         let mut s4: [i8; CT] = [0; CT];
 
-        let mut mt = BIG::new();
-        let mut t: [BIG; 16] = [
-            BIG::new_copy(&u[0]),
-            BIG::new_copy(&u[1]),
-            BIG::new_copy(&u[2]),
-            BIG::new_copy(&u[3]),
-            BIG::new_copy(&u[4]),
-            BIG::new_copy(&u[5]),
-            BIG::new_copy(&u[6]),
-            BIG::new_copy(&u[7]),
-            BIG::new_copy(&u[8]),
-            BIG::new_copy(&u[9]),
-            BIG::new_copy(&u[10]),
-            BIG::new_copy(&u[11]),
-            BIG::new_copy(&u[12]),
-            BIG::new_copy(&u[13]),
-            BIG::new_copy(&u[14]),
-            BIG::new_copy(&u[15]),
+        let mut mt = Big::new();
+        let mut t: [Big; 16] = [
+            Big::new_copy(&u[0]),
+            Big::new_copy(&u[1]),
+            Big::new_copy(&u[2]),
+            Big::new_copy(&u[3]),
+            Big::new_copy(&u[4]),
+            Big::new_copy(&u[5]),
+            Big::new_copy(&u[6]),
+            Big::new_copy(&u[7]),
+            Big::new_copy(&u[8]),
+            Big::new_copy(&u[9]),
+            Big::new_copy(&u[10]),
+            Big::new_copy(&u[11]),
+            Big::new_copy(&u[12]),
+            Big::new_copy(&u[13]),
+            Big::new_copy(&u[14]),
+            Big::new_copy(&u[15]),
         ];
 
         for i in 0..16 {
@@ -1464,7 +1464,7 @@ impl FP48 {
         g1[7].mul(&q[3]); // q[0].q[1].q[2].q[3]
 
         // Use Frobenius
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
         for i in 0..8 {
             g2[i].copy(&g1[i]);
             g2[i].frob(&f, 4);
diff --git a/src/fp8.rs b/src/fp8.rs
index dfc84d1..1fcc336 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -20,7 +20,7 @@ under the License.
 use super::fp::FP;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
+use super::big::Big;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -358,10 +358,10 @@ impl FP8 {
     }
 
     /* self=self^e */
-    pub fn pow(&self, e: &BIG) -> FP8 {
+    pub fn pow(&self, e: &Big) -> FP8 {
         let mut w = FP8::new_copy(self);
         w.norm();
-        let mut z = BIG::new_copy(&e);
+        let mut z = Big::new_copy(&e);
         let mut r = FP8::new_int(1);
         z.norm();
         loop {
@@ -411,7 +411,7 @@ impl FP8 {
     }
 
     /* r=x^n using XTR method on traces of FP24s */
-    pub fn xtr_pow(&self, n: &BIG) -> FP8 {
+    pub fn xtr_pow(&self, n: &Big) -> FP8 {
         let mut sf = FP8::new_copy(self);
         sf.norm();
         let mut a = FP8::new_int(3);
@@ -422,7 +422,7 @@ impl FP8 {
         let mut r = FP8::new();
 
         let par = n.parity();
-        let mut v = BIG::new_copy(n);
+        let mut v = Big::new_copy(n);
         v.norm();
         v.fshr(1);
         if par == 0 {
@@ -460,10 +460,10 @@ impl FP8 {
     }
 
     /* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
-    pub fn xtr_pow2(&mut self, ck: &FP8, ckml: &FP8, ckm2l: &FP8, a: &BIG, b: &BIG) -> FP8 {
-        let mut e = BIG::new_copy(a);
-        let mut d = BIG::new_copy(b);
-        let mut w = BIG::new();
+    pub fn xtr_pow2(&mut self, ck: &FP8, ckml: &FP8, ckm2l: &FP8, a: &Big, b: &Big) -> FP8 {
+        let mut e = Big::new_copy(a);
+        let mut d = Big::new_copy(b);
+        let mut w = Big::new();
         e.norm();
         d.norm();
 
@@ -481,12 +481,12 @@ impl FP8 {
             f2 += 1;
         }
 
-        while BIG::comp(&d, &e) != 0 {
-            if BIG::comp(&d, &e) > 0 {
+        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 {
+                if Big::comp(&d, &w) <= 0 {
                     w.copy(&d);
                     d.copy(&e);
                     e.rsub(&w);
@@ -541,11 +541,11 @@ impl FP8 {
                     }
                 }
             }
-            if BIG::comp(&d, &e) < 0 {
+            if Big::comp(&d, &e) < 0 {
                 w.copy(&d);
                 w.imul(4);
                 w.norm();
-                if BIG::comp(&e, &w) <= 0 {
+                if Big::comp(&e, &w) <= 0 {
                     e.sub(&d);
                     e.norm();
                     t.copy(&cv);
diff --git a/src/mpin.rs b/src/mpin.rs
index 6d7e9ca..ba272d1 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -25,7 +25,7 @@ use super::ecp::ECP;
 use super::ecp2::ECP2;
 use super::fp4::FP4;
 use super::fp12::FP12;
-use super::big::BIG;
+use super::big::Big;
 use super::pair;
 use super::big;
 use super::rom;
@@ -193,10 +193,10 @@ pub fn today() -> usize {
 /* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
 /* maps a random u to a point on the curve */
 #[allow(non_snake_case)]
-fn emap(u: &BIG, cb: isize) -> ECP {
+fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = BIG::new_copy(u);
-    let mut p = BIG::new_ints(&rom::MODULUS);
+    let mut x = Big::new_copy(u);
+    let mut p = Big::new_ints(&rom::MODULUS);
     x.rmod(&mut p);
     loop {
         P = ECP::new_bigint(&x, cb);
@@ -211,7 +211,7 @@ fn emap(u: &BIG, cb: isize) -> ECP {
 
 /* returns u derived from P. Random value in range 1 to return value should then be added to u */
 #[allow(non_snake_case)]
-fn unmap(u: &mut BIG, P: &mut ECP) -> isize {
+fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
     let mut R: ECP;
     let mut r = 0;
@@ -243,19 +243,19 @@ pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = e[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = e[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let mut P = ECP::new_bigs(&u, &v);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let p = BIG::new_ints(&rom::MODULUS);
-    u = BIG::randomnum(&p, rng);
+    let p = Big::new_ints(&rom::MODULUS);
+    u = Big::randomnum(&p, rng);
 
     let mut su = rng.getbyte() as isize;
     su %= 2;
@@ -291,11 +291,11 @@ pub fn decoding(d: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = d[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = d[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let su = (d[0] & 1) as isize;
     let sv = ((d[0] >> 1) & 1) as isize;
@@ -351,8 +351,8 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
-    let mut sc = BIG::randomnum(&r, rng);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
+    let mut sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -362,7 +362,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP2::generator();
 
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     Q = pair::g2mul(&mut Q, &mut sc);
     Q.tobytes(sst);
     return 0;
@@ -382,14 +382,14 @@ pub fn get_g1_multiple(
     g: &[u8],
     w: &mut [u8],
 ) -> isize {
-    let mut sx: BIG;
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sx: Big;
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
     let mut P: ECP;
 
@@ -501,7 +501,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     hashit(sha, date, cid, &mut h);
     let mut P = ECP::mapit(&h);
 
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     pair::g1mul(&mut P, &mut sc).tobytes(ctt, false);
     return 0;
 }
@@ -521,15 +521,15 @@ pub fn client_1(
     xcid: Option<&mut [u8]>,
     permit: Option<&[u8]>,
 ) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut sx: BIG;
+    let mut sx: Big;
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
 
     const RM: usize = big::MODBYTES as usize;
@@ -604,14 +604,14 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
 /* Implement step 2 on client side of MPin protocol */
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
     let mut P = ECP::frombytes(sec);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let mut px = BIG::frombytes(x);
-    let py = BIG::frombytes(y);
+    let mut px = Big::frombytes(x);
+    let py = Big::frombytes(y);
     px.add(&py);
     px.rmod(&mut r);
 
@@ -637,8 +637,8 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
 
     hashit(sha, timevalue, xcid, &mut h);
 
-    let mut sy = BIG::frombytes(&h);
-    let mut q = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sy = Big::frombytes(&h);
+    let mut q = Big::new_ints(&rom::CURVE_ORDER);
     sy.rmod(&mut q);
     sy.tobytes(y);
 }
@@ -682,7 +682,7 @@ pub fn server_2(
         return INVALID_POINT;
     }
 
-    let mut sy = BIG::frombytes(&y);
+    let mut sy = Big::frombytes(&y);
     let mut P: ECP;
     if date != 0 {
         if let Some(rhtid) = htid {
@@ -864,9 +864,9 @@ pub fn client_key(
 ) -> isize {
     let mut g1 = FP12::frombytes(&g1);
     let mut g2 = FP12::frombytes(&g2);
-    let mut z = BIG::frombytes(&r);
-    let mut x = BIG::frombytes(&x);
-    let h = BIG::frombytes(&h);
+    let mut z = Big::frombytes(&r);
+    let mut x = Big::frombytes(&x);
+    let h = Big::frombytes(&h);
 
     let mut W = ECP::frombytes(&wcid);
     if W.is_infinity() {
@@ -875,7 +875,7 @@ pub fn client_key(
 
     W = pair::g1mul(&mut W, &mut x);
 
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
 
     z.add(&h); //new
     z.rmod(&mut r);
@@ -928,8 +928,8 @@ pub fn server_key(
         return INVALID_POINT;
     }
 
-    let mut w = BIG::frombytes(&w);
-    let mut h = BIG::frombytes(&h);
+    let mut w = Big::frombytes(&w);
+    let mut h = Big::frombytes(&h);
     A = pair::g1mul(&mut A, &mut h); // new
     R.add(&mut A);
 
diff --git a/src/mpin192.rs b/src/mpin192.rs
index 276a560..e133dcd 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -25,7 +25,7 @@ use super::ecp::ECP;
 use super::ecp4::ECP4;
 use super::fp8::FP8;
 use super::fp24::FP24;
-use super::big::BIG;
+use super::big::Big;
 use super::pair192;
 use super::big;
 use super::rom;
@@ -209,10 +209,10 @@ pub fn today() -> usize {
 /* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
 /* maps a random u to a point on the curve */
 #[allow(non_snake_case)]
-fn emap(u: &BIG, cb: isize) -> ECP {
+fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = BIG::new_copy(u);
-    let mut p = BIG::new_ints(&rom::MODULUS);
+    let mut x = Big::new_copy(u);
+    let mut p = Big::new_ints(&rom::MODULUS);
     x.rmod(&mut p);
     loop {
         P = ECP::new_bigint(&x, cb);
@@ -227,7 +227,7 @@ fn emap(u: &BIG, cb: isize) -> ECP {
 
 /* returns u derived from P. Random value in range 1 to return value should then be added to u */
 #[allow(non_snake_case)]
-fn unmap(u: &mut BIG, P: &mut ECP) -> isize {
+fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
     let mut R: ECP;
     let mut r = 0;
@@ -259,19 +259,19 @@ pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = e[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = e[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let mut P = ECP::new_bigs(&u, &v);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let p = BIG::new_ints(&rom::MODULUS);
-    u = BIG::randomnum(&p, rng);
+    let p = Big::new_ints(&rom::MODULUS);
+    u = Big::randomnum(&p, rng);
 
     let mut su = rng.getbyte() as isize;
     su %= 2;
@@ -307,11 +307,11 @@ pub fn decoding(d: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = d[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = d[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let su = (d[0] & 1) as isize;
     let sv = ((d[0] >> 1) & 1) as isize;
@@ -367,8 +367,8 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
-    let mut sc = BIG::randomnum(&r, rng);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
+    let mut sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -377,7 +377,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
 #[allow(non_snake_case)]
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP4::generator();
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     Q = pair192::g2mul(&mut Q, &mut sc);
     Q.tobytes(sst);
     return 0;
@@ -397,14 +397,14 @@ pub fn get_g1_multiple(
     g: &[u8],
     w: &mut [u8],
 ) -> isize {
-    let mut sx: BIG;
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sx: Big;
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
     let mut P: ECP;
 
@@ -516,7 +516,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     hashit(sha, date, cid, &mut h);
     let mut P = ECP::mapit(&h);
 
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     pair192::g1mul(&mut P, &mut sc).tobytes(ctt, false);
     return 0;
 }
@@ -536,15 +536,15 @@ pub fn client_1(
     xcid: Option<&mut [u8]>,
     permit: Option<&[u8]>,
 ) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut sx: BIG;
+    let mut sx: Big;
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
 
     const RM: usize = big::MODBYTES as usize;
@@ -619,14 +619,14 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
 /* Implement step 2 on client side of MPin protocol */
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
     let mut P = ECP::frombytes(sec);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let mut px = BIG::frombytes(x);
-    let py = BIG::frombytes(y);
+    let mut px = Big::frombytes(x);
+    let py = Big::frombytes(y);
     px.add(&py);
     px.rmod(&mut r);
 
@@ -652,8 +652,8 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
 
     hashit(sha, timevalue, xcid, &mut h);
 
-    let mut sy = BIG::frombytes(&h);
-    let mut q = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sy = Big::frombytes(&h);
+    let mut q = Big::new_ints(&rom::CURVE_ORDER);
     sy.rmod(&mut q);
     sy.tobytes(y);
 }
@@ -697,7 +697,7 @@ pub fn server_2(
         return INVALID_POINT;
     }
 
-    let mut sy = BIG::frombytes(&y);
+    let mut sy = Big::frombytes(&y);
     let mut P: ECP;
     if date != 0 {
         if let Some(rhtid) = htid {
@@ -879,9 +879,9 @@ pub fn client_key(
 ) -> isize {
     let mut g1 = FP24::frombytes(&g1);
     let mut g2 = FP24::frombytes(&g2);
-    let mut z = BIG::frombytes(&r);
-    let mut x = BIG::frombytes(&x);
-    let h = BIG::frombytes(&h);
+    let mut z = Big::frombytes(&r);
+    let mut x = Big::frombytes(&x);
+    let h = Big::frombytes(&h);
 
     let mut W = ECP::frombytes(&wcid);
     if W.is_infinity() {
@@ -890,7 +890,7 @@ pub fn client_key(
 
     W = pair192::g1mul(&mut W, &mut x);
 
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
 
     z.add(&h); //new
     z.rmod(&mut r);
@@ -943,8 +943,8 @@ pub fn server_key(
         return INVALID_POINT;
     }
 
-    let mut w = BIG::frombytes(&w);
-    let mut h = BIG::frombytes(&h);
+    let mut w = Big::frombytes(&w);
+    let mut h = Big::frombytes(&h);
     A = pair192::g1mul(&mut A, &mut h); // new
     R.add(&mut A);
 
diff --git a/src/mpin256.rs b/src/mpin256.rs
index b4928e9..4892ff5 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -25,7 +25,7 @@ use super::ecp::ECP;
 use super::ecp8::ECP8;
 use super::fp16::FP16;
 use super::fp48::FP48;
-use super::big::BIG;
+use super::big::Big;
 use super::pair256;
 use super::big;
 use super::rom;
@@ -241,10 +241,10 @@ pub fn today() -> usize {
 /* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
 /* maps a random u to a point on the curve */
 #[allow(non_snake_case)]
-fn emap(u: &BIG, cb: isize) -> ECP {
+fn emap(u: &Big, cb: isize) -> ECP {
     let mut P: ECP;
-    let mut x = BIG::new_copy(u);
-    let mut p = BIG::new_ints(&rom::MODULUS);
+    let mut x = Big::new_copy(u);
+    let mut p = Big::new_ints(&rom::MODULUS);
     x.rmod(&mut p);
     loop {
         P = ECP::new_bigint(&x, cb);
@@ -259,7 +259,7 @@ fn emap(u: &BIG, cb: isize) -> ECP {
 
 /* returns u derived from P. Random value in range 1 to return value should then be added to u */
 #[allow(non_snake_case)]
-fn unmap(u: &mut BIG, P: &mut ECP) -> isize {
+fn unmap(u: &mut Big, P: &mut ECP) -> isize {
     let s = P.gets();
     let mut R: ECP;
     let mut r = 0;
@@ -291,19 +291,19 @@ pub fn encoding(rng: &mut RAND, e: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = e[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = e[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let mut P = ECP::new_bigs(&u, &v);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let p = BIG::new_ints(&rom::MODULUS);
-    u = BIG::randomnum(&p, rng);
+    let p = Big::new_ints(&rom::MODULUS);
+    u = Big::randomnum(&p, rng);
 
     let mut su = rng.getbyte() as isize;
     su %= 2;
@@ -339,11 +339,11 @@ pub fn decoding(d: &mut [u8]) -> isize {
     for i in 0..EFS {
         t[i] = d[i + 1]
     }
-    let mut u = BIG::frombytes(&t);
+    let mut u = Big::frombytes(&t);
     for i in 0..EFS {
         t[i] = d[i + EFS + 1]
     }
-    let mut v = BIG::frombytes(&t);
+    let mut v = Big::frombytes(&t);
 
     let su = (d[0] & 1) as isize;
     let sv = ((d[0] >> 1) & 1) as isize;
@@ -399,8 +399,8 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
-    let mut sc = BIG::randomnum(&r, rng);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
+    let mut sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -410,7 +410,7 @@ pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
 pub fn get_server_secret(s: &[u8], sst: &mut [u8]) -> isize {
     let mut Q = ECP8::generator();
 
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     Q = pair256::g2mul(&mut Q, &mut sc);
     Q.tobytes(sst);
     return 0;
@@ -430,14 +430,14 @@ pub fn get_g1_multiple(
     g: &[u8],
     w: &mut [u8],
 ) -> isize {
-    let mut sx: BIG;
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sx: Big;
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
     let mut P: ECP;
 
@@ -549,7 +549,7 @@ pub fn get_client_permit(sha: usize, date: usize, s: &[u8], cid: &[u8], ctt: &mu
     hashit(sha, date, cid, &mut h);
     let mut P = ECP::mapit(&h);
 
-    let mut sc = BIG::frombytes(s);
+    let mut sc = Big::frombytes(s);
     pair256::g1mul(&mut P, &mut sc).tobytes(ctt, false);
     return 0;
 }
@@ -569,15 +569,15 @@ pub fn client_1(
     xcid: Option<&mut [u8]>,
     permit: Option<&[u8]>,
 ) -> isize {
-    let r = BIG::new_ints(&rom::CURVE_ORDER);
+    let r = Big::new_ints(&rom::CURVE_ORDER);
 
-    let mut sx: BIG;
+    let mut sx: Big;
 
     if let Some(rd) = rng {
-        sx = BIG::randomnum(&r, rd);
+        sx = Big::randomnum(&r, rd);
         sx.tobytes(x);
     } else {
-        sx = BIG::frombytes(x);
+        sx = Big::frombytes(x);
     }
 
     const RM: usize = big::MODBYTES as usize;
@@ -652,14 +652,14 @@ pub fn server_1(sha: usize, date: usize, cid: &[u8], hid: &mut [u8], htid: Optio
 /* Implement step 2 on client side of MPin protocol */
 #[allow(non_snake_case)]
 pub fn client_2(x: &[u8], y: &[u8], sec: &mut [u8]) -> isize {
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
     let mut P = ECP::frombytes(sec);
     if P.is_infinity() {
         return INVALID_POINT;
     }
 
-    let mut px = BIG::frombytes(x);
-    let py = BIG::frombytes(y);
+    let mut px = Big::frombytes(x);
+    let py = Big::frombytes(y);
     px.add(&py);
     px.rmod(&mut r);
 
@@ -685,8 +685,8 @@ pub fn get_y(sha: usize, timevalue: usize, xcid: &[u8], y: &mut [u8]) {
 
     hashit(sha, timevalue, xcid, &mut h);
 
-    let mut sy = BIG::frombytes(&h);
-    let mut q = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut sy = Big::frombytes(&h);
+    let mut q = Big::new_ints(&rom::CURVE_ORDER);
     sy.rmod(&mut q);
     sy.tobytes(y);
 }
@@ -730,7 +730,7 @@ pub fn server_2(
         return INVALID_POINT;
     }
 
-    let mut sy = BIG::frombytes(&y);
+    let mut sy = Big::frombytes(&y);
     let mut P: ECP;
     if date != 0 {
         if let Some(rhtid) = htid {
@@ -912,9 +912,9 @@ pub fn client_key(
 ) -> isize {
     let mut g1 = FP48::frombytes(&g1);
     let mut g2 = FP48::frombytes(&g2);
-    let mut z = BIG::frombytes(&r);
-    let mut x = BIG::frombytes(&x);
-    let h = BIG::frombytes(&h);
+    let mut z = Big::frombytes(&r);
+    let mut x = Big::frombytes(&x);
+    let h = Big::frombytes(&h);
 
     let mut W = ECP::frombytes(&wcid);
     if W.is_infinity() {
@@ -923,7 +923,7 @@ pub fn client_key(
 
     W = pair256::g1mul(&mut W, &mut x);
 
-    let mut r = BIG::new_ints(&rom::CURVE_ORDER);
+    let mut r = Big::new_ints(&rom::CURVE_ORDER);
 
     z.add(&h); //new
     z.rmod(&mut r);
@@ -976,8 +976,8 @@ pub fn server_key(
         return INVALID_POINT;
     }
 
-    let mut w = BIG::frombytes(&w);
-    let mut h = BIG::frombytes(&h);
+    let mut w = Big::frombytes(&w);
+    let mut h = Big::frombytes(&h);
     A = pair256::g1mul(&mut A, &mut h); // new
     R.add(&mut A);
 
diff --git a/src/pair.rs b/src/pair.rs
index 2050296..b85efaa 100644
--- a/src/pair.rs
+++ b/src/pair.rs
@@ -25,8 +25,8 @@ use super::ecp2::ECP2;
 use super::fp4::FP4;
 use super::fp12;
 use super::fp12::FP12;
-use super::big::BIG;
-use super::dbig::DBIG;
+use super::big::Big;
+use super::dbig::DBig;
 use super::ecp;
 use super::rom;
 use types::{SexticTwist, CurvePairingType, SignOfX};
@@ -139,8 +139,8 @@ fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
-    n.copy(&BIG::new_ints(&rom::CURVE_BNX));
+fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+    n.copy(&Big::new_ints(&rom::CURVE_BNX));
     if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
         n.pmul(6);
         if ecp::SIGN_OF_X==SignOfX::POSITIVEX {
@@ -180,9 +180,9 @@ pub fn miller(r:&[FP12]) -> FP12 {
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
 pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
-    let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut n = Big::new();
+    let mut n3 = Big::new();
     let mut K = ECP2::new();
 
 
@@ -240,15 +240,15 @@ pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
         let lv2=lineadd(&mut A,&K,&qx,&qy);
         lv.smul(&lv2);
 	r[0].ssmul(&lv);
-    } 
+    }
 }
 
 #[allow(non_snake_case)]
 /* Optimal R-ate pairing */
 pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
-    let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut n = Big::new();
+    let mut n3 = Big::new();
     let mut K = ECP2::new();
 
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
@@ -256,7 +256,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
             f.inverse();
             f.norm();
         }
-    } 
+    }
     let mut P = ECP2::new();
     P.copy(P1);
     P.affine();
@@ -320,9 +320,9 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
 #[allow(non_snake_case)]
 /* Optimal R-ate double pairing e(P,Q).e(R,S) */
 pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
-    let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut n = Big::new();
+    let mut n3 = Big::new();
     let mut K = ECP2::new();
 
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
@@ -330,7 +330,7 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
             f.inverse();
             f.norm();
         }
-    } 
+    }
 
     let mut P = ECP2::new();
     P.copy(P1);
@@ -425,8 +425,8 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
 
 /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
 pub fn fexp(m: &FP12) -> FP12 {
-    let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut x = BIG::new_ints(&rom::CURVE_BNX);
+    let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut x = Big::new_ints(&rom::CURVE_BNX);
     let mut r = FP12::new_copy(m);
 
     /* Easy part of final exp */
@@ -560,32 +560,32 @@ pub fn fexp(m: &FP12) -> FP12 {
 
 #[allow(non_snake_case)]
 /* GLV method */
-fn glv(e: &BIG) -> [BIG; 2] {
-    let mut u: [BIG; 2] = [BIG::new(), BIG::new()];
+fn glv(e: &Big) -> [Big; 2] {
+    let mut u: [Big; 2] = [Big::new(), Big::new()];
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        let mut t = BIG::new();
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut v: [BIG; 2] = [BIG::new(), BIG::new()];
+        let mut t = Big::new();
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut v: [Big; 2] = [Big::new(), Big::new()];
 
         for i in 0..2 {
-            t.copy(&BIG::new_ints(&rom::CURVE_W[i])); // why not just t=new BIG(ROM.CURVE_W[i]);
-            let mut d: DBIG = BIG::mul(&t, e);
+            t.copy(&Big::new_ints(&rom::CURVE_W[i])); // why not just t=new Big(ROM.CURVE_W[i]);
+            let mut d: DBig = Big::mul(&t, e);
             v[i].copy(&d.div(&q));
         }
         u[0].copy(&e);
         for i in 0..2 {
             for j in 0..2 {
-                t = BIG::new_ints(&rom::CURVE_SB[j][i]);
-                t = BIG::modmul(&mut v[j], &mut t, &q);
+                t = Big::new_ints(&rom::CURVE_SB[j][i]);
+                t = Big::modmul(&mut v[j], &mut t, &q);
                 u[i].add(&q);
                 u[i].sub(&t);
                 u[i].rmod(&q);
             }
         }
     } else {
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let x = BIG::new_ints(&rom::CURVE_BNX);
-        let x2 = BIG::smul(&x, &x);
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let x = Big::new_ints(&rom::CURVE_BNX);
+        let x2 = Big::smul(&x, &x);
         u[0].copy(&e);
         u[0].rmod(&x2);
         u[1].copy(&e);
@@ -597,32 +597,32 @@ fn glv(e: &BIG) -> [BIG; 2] {
 
 #[allow(non_snake_case)]
 /* Galbraith & Scott Method */
-pub fn gs(e: &BIG) -> [BIG; 4] {
-    let mut u: [BIG; 4] = [BIG::new(), BIG::new(), BIG::new(), BIG::new()];
+pub fn gs(e: &Big) -> [Big; 4] {
+    let mut u: [Big; 4] = [Big::new(), Big::new(), Big::new(), Big::new()];
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
-        let mut t = BIG::new();
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
+        let mut t = Big::new();
+        let q = Big::new_ints(&rom::CURVE_ORDER);
 
-        let mut v: [BIG; 4] = [BIG::new(), BIG::new(), BIG::new(), BIG::new()];
+        let mut v: [Big; 4] = [Big::new(), Big::new(), Big::new(), Big::new()];
         for i in 0..4 {
-            t.copy(&BIG::new_ints(&rom::CURVE_WB[i]));
-            let mut d: DBIG = BIG::mul(&t, e);
+            t.copy(&Big::new_ints(&rom::CURVE_WB[i]));
+            let mut d: DBig = Big::mul(&t, e);
             v[i].copy(&d.div(&q));
         }
         u[0].copy(&e);
         for i in 0..4 {
             for j in 0..4 {
-                t = BIG::new_ints(&rom::CURVE_BB[j][i]);
-                t = BIG::modmul(&mut v[j], &mut t, &q);
+                t = Big::new_ints(&rom::CURVE_BB[j][i]);
+                t = Big::modmul(&mut v[j], &mut t, &q);
                 u[i].add(&q);
                 u[i].sub(&t);
                 u[i].rmod(&q);
             }
         }
     } else {
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let x = BIG::new_ints(&rom::CURVE_BNX);
-        let mut w = BIG::new_copy(&e);
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let x = Big::new_ints(&rom::CURVE_BNX);
+        let mut w = Big::new_copy(&e);
         for i in 0..3 {
             u[i].copy(&w);
             u[i].rmod(&x);
@@ -630,10 +630,10 @@ pub fn gs(e: &BIG) -> [BIG; 4] {
         }
         u[3].copy(&w);
         if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
-            let mut t = BIG::new();
-            t.copy(&BIG::modneg(&mut u[1], &q));
+            let mut t = Big::new();
+            t.copy(&Big::modneg(&mut u[1], &q));
             u[1].copy(&t);
-            t.copy(&BIG::modneg(&mut u[3], &q));
+            t.copy(&Big::modneg(&mut u[3], &q));
             u[3].copy(&t);
         }
     }
@@ -642,20 +642,20 @@ pub fn gs(e: &BIG) -> [BIG; 4] {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G1 */
-pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
+pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
     let mut R = ECP::new();
     if rom::USE_GLV {
         R.copy(P);
         let mut Q = ECP::new();
         Q.copy(P);
         Q.affine();
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut cru = FP::new_big(&BIG::new_ints(&rom::CURVE_CRU));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut cru = FP::new_big(&Big::new_ints(&rom::CURVE_CRU));
         let mut u = glv(e);
         Q.mulx(&mut cru);
 
         let mut np = u[0].nbits();
-        let mut t: BIG = BIG::modneg(&mut u[0], &q);
+        let mut t: Big = Big::modneg(&mut u[0], &q);
         let mut nn = t.nbits();
         if nn < np {
             u[0].copy(&t);
@@ -663,7 +663,7 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
         }
 
         np = u[1].nbits();
-        t = BIG::modneg(&mut u[1], &q);
+        t = Big::modneg(&mut u[1], &q);
         nn = t.nbits();
         if nn < np {
             u[1].copy(&t);
@@ -680,12 +680,12 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G2 */
-pub fn g2mul(P: &ECP2, e: &BIG) -> ECP2 {
+pub fn g2mul(P: &ECP2, e: &Big) -> ECP2 {
     let mut R = ECP2::new();
     if rom::USE_GS_G2 {
         let mut Q: [ECP2; 4] = [ECP2::new(), ECP2::new(), ECP2::new(), ECP2::new()];
-        let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
+        let mut f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
         let mut u = gs(e);
         let mut T = ECP2::new();
 
@@ -694,7 +694,7 @@ pub fn g2mul(P: &ECP2, e: &BIG) -> ECP2 {
             f.norm();
         }
 
-        let mut t = BIG::new();
+        let mut t = Big::new();
         Q[0].copy(&P);
         for i in 1..4 {
             T.copy(&Q[i - 1]);
@@ -703,7 +703,7 @@ pub fn g2mul(P: &ECP2, e: &BIG) -> ECP2 {
         }
         for i in 0..4 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
@@ -721,13 +721,13 @@ pub fn g2mul(P: &ECP2, e: &BIG) -> ECP2 {
 
 /* f=f^e */
 /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
-pub fn gtpow(d: &FP12, e: &BIG) -> FP12 {
+pub fn gtpow(d: &FP12, e: &Big) -> FP12 {
     let mut r = FP12::new();
     if rom::USE_GS_GT {
         let mut g: [FP12; 4] = [FP12::new(), FP12::new(), FP12::new(), FP12::new()];
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut t = BIG::new();
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut t = Big::new();
         let mut u = gs(e);
         let mut w = FP12::new();
 
@@ -739,7 +739,7 @@ pub fn gtpow(d: &FP12, e: &BIG) -> FP12 {
         }
         for i in 0..4 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
diff --git a/src/pair192.rs b/src/pair192.rs
index 4310b6b..a7c2993 100644
--- a/src/pair192.rs
+++ b/src/pair192.rs
@@ -26,7 +26,7 @@ use super::fp4::FP4;
 use super::fp8::FP8;
 use super::fp24;
 use super::fp24::FP24;
-use super::big::BIG;
+use super::big::Big;
 use super::ecp;
 use super::rom;
 use types::{SexticTwist, SignOfX};
@@ -137,8 +137,8 @@ fn lineadd(A: &mut ECP4, B: &ECP4, qx: &FP, qy: &FP) -> FP24 {
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
-    n.copy(&BIG::new_ints(&rom::CURVE_BNX));
+fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+    n.copy(&Big::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
     n3.norm();
@@ -169,9 +169,9 @@ pub fn miller(r:&[FP24]) -> FP24 {
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
 pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
-    
+    let mut n = Big::new();
+    let mut n3 = Big::new();
+
 // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP4::new();
     P.copy(P1);
@@ -210,8 +210,8 @@ pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
 #[allow(non_snake_case)]
 /* Optimal R-ate pairing */
 pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut n = Big::new();
+    let mut n3 = Big::new();
 
     let mut P = ECP4::new();
     P.copy(P1);
@@ -260,8 +260,8 @@ pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
 #[allow(non_snake_case)]
 /* Optimal R-ate double pairing e(P,Q).e(R,S) */
 pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) -> FP24 {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut n = Big::new();
+    let mut n3 = Big::new();
 
     let mut P = ECP4::new();
     P.copy(P1);
@@ -328,8 +328,8 @@ pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) -> FP24 {
 
 /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
 pub fn fexp(m: &FP24) -> FP24 {
-    let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut x = BIG::new_ints(&rom::CURVE_BNX);
+    let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut x = Big::new_ints(&rom::CURVE_BNX);
     let mut r = FP24::new_copy(m);
 
     /* Easy part of final exp */
@@ -426,12 +426,12 @@ pub fn fexp(m: &FP24) -> FP24 {
 
 #[allow(non_snake_case)]
 /* GLV method */
-fn glv(e: &BIG) -> [BIG; 2] {
-    let mut u: [BIG; 2] = [BIG::new(), BIG::new()];
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
-    let mut x = BIG::new_ints(&rom::CURVE_BNX);
-    let x2 = BIG::smul(&x, &x);
-    x.copy(&BIG::smul(&x2, &x2));
+fn glv(e: &Big) -> [Big; 2] {
+    let mut u: [Big; 2] = [Big::new(), Big::new()];
+    let q = Big::new_ints(&rom::CURVE_ORDER);
+    let mut x = Big::new_ints(&rom::CURVE_BNX);
+    let x2 = Big::smul(&x, &x);
+    x.copy(&Big::smul(&x2, &x2));
     u[0].copy(&e);
     u[0].rmod(&x);
     u[1].copy(&e);
@@ -443,20 +443,20 @@ fn glv(e: &BIG) -> [BIG; 2] {
 
 #[allow(non_snake_case)]
 /* Galbraith & Scott Method */
-pub fn gs(e: &BIG) -> [BIG; 8] {
-    let mut u: [BIG; 8] = [
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
+pub fn gs(e: &Big) -> [Big; 8] {
+    let mut u: [Big; 8] = [
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
     ];
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
-    let x = BIG::new_ints(&rom::CURVE_BNX);
-    let mut w = BIG::new_copy(&e);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
+    let x = Big::new_ints(&rom::CURVE_BNX);
+    let mut w = Big::new_copy(&e);
     for i in 0..7 {
         u[i].copy(&w);
         u[i].rmod(&x);
@@ -464,14 +464,14 @@ pub fn gs(e: &BIG) -> [BIG; 8] {
     }
     u[7].copy(&w);
     if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
-        let mut t = BIG::new();
-        t.copy(&BIG::modneg(&mut u[1], &q));
+        let mut t = Big::new();
+        t.copy(&Big::modneg(&mut u[1], &q));
         u[1].copy(&t);
-        t.copy(&BIG::modneg(&mut u[3], &q));
+        t.copy(&Big::modneg(&mut u[3], &q));
         u[3].copy(&t);
-        t.copy(&BIG::modneg(&mut u[5], &q));
+        t.copy(&Big::modneg(&mut u[5], &q));
         u[5].copy(&t);
-        t.copy(&BIG::modneg(&mut u[7], &q));
+        t.copy(&Big::modneg(&mut u[7], &q));
         u[7].copy(&t);
     }
     return u;
@@ -479,20 +479,20 @@ pub fn gs(e: &BIG) -> [BIG; 8] {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G1 */
-pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
+pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
     let mut R = ECP::new();
     if rom::USE_GLV {
         R.copy(P);
         let mut Q = ECP::new();
         Q.copy(P);
         Q.affine();
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut cru = FP::new_big(&BIG::new_ints(&rom::CURVE_CRU));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut cru = FP::new_big(&Big::new_ints(&rom::CURVE_CRU));
         let mut u = glv(e);
         Q.mulx(&mut cru);
 
         let mut np = u[0].nbits();
-        let mut t: BIG = BIG::modneg(&mut u[0], &q);
+        let mut t: Big = Big::modneg(&mut u[0], &q);
         let mut nn = t.nbits();
         if nn < np {
             u[0].copy(&t);
@@ -500,7 +500,7 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
         }
 
         np = u[1].nbits();
-        t = BIG::modneg(&mut u[1], &q);
+        t = Big::modneg(&mut u[1], &q);
         nn = t.nbits();
         if nn < np {
             u[1].copy(&t);
@@ -517,7 +517,7 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G2 */
-pub fn g2mul(P: &ECP4, e: &BIG) -> ECP4 {
+pub fn g2mul(P: &ECP4, e: &Big) -> ECP4 {
     let mut R = ECP4::new();
     if rom::USE_GS_G2 {
         let mut Q: [ECP4; 8] = [
@@ -530,13 +530,13 @@ pub fn g2mul(P: &ECP4, e: &BIG) -> ECP4 {
             ECP4::new(),
             ECP4::new(),
         ];
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
+        let q = Big::new_ints(&rom::CURVE_ORDER);
         let mut u = gs(e);
         let mut T = ECP4::new();
 
         let f = ECP4::frob_constants();
 
-        let mut t = BIG::new();
+        let mut t = Big::new();
         Q[0].copy(&P);
         for i in 1..8 {
             T.copy(&Q[i - 1]);
@@ -545,7 +545,7 @@ pub fn g2mul(P: &ECP4, e: &BIG) -> ECP4 {
         }
         for i in 0..8 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
@@ -563,7 +563,7 @@ pub fn g2mul(P: &ECP4, e: &BIG) -> ECP4 {
 
 /* f=f^e */
 /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
-pub fn gtpow(d: &FP24, e: &BIG) -> FP24 {
+pub fn gtpow(d: &FP24, e: &Big) -> FP24 {
     let mut r = FP24::new();
     if rom::USE_GS_GT {
         let mut g: [FP24; 8] = [
@@ -576,9 +576,9 @@ pub fn gtpow(d: &FP24, e: &BIG) -> FP24 {
             FP24::new(),
             FP24::new(),
         ];
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut t = BIG::new();
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut t = Big::new();
         let mut u = gs(e);
         let mut w = FP24::new();
 
@@ -590,7 +590,7 @@ pub fn gtpow(d: &FP24, e: &BIG) -> FP24 {
         }
         for i in 0..8 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
diff --git a/src/pair256.rs b/src/pair256.rs
index 7cdca72..f25676c 100644
--- a/src/pair256.rs
+++ b/src/pair256.rs
@@ -26,7 +26,7 @@ use super::fp8::FP8;
 use super::fp16::FP16;
 use super::fp48;
 use super::fp48::FP48;
-use super::big::BIG;
+use super::big::Big;
 use super::ecp;
 use super::rom;
 use types::{SignOfX, SexticTwist};
@@ -137,8 +137,8 @@ fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
-    n.copy(&BIG::new_ints(&rom::CURVE_BNX));
+fn lbits(n3: &mut Big,n: &mut Big) -> usize {
+    n.copy(&Big::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
     n3.norm();
@@ -169,8 +169,8 @@ pub fn miller(r:&[FP48]) -> FP48 {
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
 pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut n = Big::new();
+    let mut n3 = Big::new();
 
 // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP8::new();
@@ -210,8 +210,8 @@ pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
 #[allow(non_snake_case)]
 /* Optimal R-ate pairing */
 pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut n = Big::new();
+    let mut n3 = Big::new();
 
     let mut P = ECP8::new();
     P.copy(P1);
@@ -258,8 +258,8 @@ pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
 #[allow(non_snake_case)]
 /* Optimal R-ate double pairing e(P,Q).e(R,S) */
 pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
-    let mut n = BIG::new();
-    let mut n3 = BIG::new();
+    let mut n = Big::new();
+    let mut n3 = Big::new();
 
     let mut P = ECP8::new();
     P.copy(P1);
@@ -326,8 +326,8 @@ pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
 
 /* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
 pub fn fexp(m: &FP48) -> FP48 {
-    let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-    let mut x = BIG::new_ints(&rom::CURVE_BNX);
+    let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+    let mut x = Big::new_ints(&rom::CURVE_BNX);
     let mut r = FP48::new_copy(m);
 
     /* Easy part of final exp */
@@ -509,13 +509,13 @@ pub fn fexp(m: &FP48) -> FP48 {
 
 #[allow(non_snake_case)]
 /* GLV method */
-fn glv(e: &BIG) -> [BIG; 2] {
-    let mut u: [BIG; 2] = [BIG::new(), BIG::new()];
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
-    let mut x = BIG::new_ints(&rom::CURVE_BNX);
-    let mut x2 = BIG::smul(&x, &x);
-    x.copy(&BIG::smul(&x2, &x2));
-    x2.copy(&BIG::smul(&x, &x));
+fn glv(e: &Big) -> [Big; 2] {
+    let mut u: [Big; 2] = [Big::new(), Big::new()];
+    let q = Big::new_ints(&rom::CURVE_ORDER);
+    let mut x = Big::new_ints(&rom::CURVE_BNX);
+    let mut x2 = Big::smul(&x, &x);
+    x.copy(&Big::smul(&x2, &x2));
+    x2.copy(&Big::smul(&x, &x));
     u[0].copy(&e);
     u[0].rmod(&x2);
     u[1].copy(&e);
@@ -527,28 +527,28 @@ fn glv(e: &BIG) -> [BIG; 2] {
 
 #[allow(non_snake_case)]
 /* Galbraith & Scott Method */
-pub fn gs(e: &BIG) -> [BIG; 16] {
-    let mut u: [BIG; 16] = [
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
-        BIG::new(),
+pub fn gs(e: &Big) -> [Big; 16] {
+    let mut u: [Big; 16] = [
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
+        Big::new(),
     ];
-    let q = BIG::new_ints(&rom::CURVE_ORDER);
-    let x = BIG::new_ints(&rom::CURVE_BNX);
-    let mut w = BIG::new_copy(&e);
+    let q = Big::new_ints(&rom::CURVE_ORDER);
+    let x = Big::new_ints(&rom::CURVE_BNX);
+    let mut w = Big::new_copy(&e);
     for i in 0..15 {
         u[i].copy(&w);
         u[i].rmod(&x);
@@ -556,22 +556,22 @@ pub fn gs(e: &BIG) -> [BIG; 16] {
     }
     u[15].copy(&w);
     if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
-        let mut t = BIG::new();
-        t.copy(&BIG::modneg(&mut u[1], &q));
+        let mut t = Big::new();
+        t.copy(&Big::modneg(&mut u[1], &q));
         u[1].copy(&t);
-        t.copy(&BIG::modneg(&mut u[3], &q));
+        t.copy(&Big::modneg(&mut u[3], &q));
         u[3].copy(&t);
-        t.copy(&BIG::modneg(&mut u[5], &q));
+        t.copy(&Big::modneg(&mut u[5], &q));
         u[5].copy(&t);
-        t.copy(&BIG::modneg(&mut u[7], &q));
+        t.copy(&Big::modneg(&mut u[7], &q));
         u[7].copy(&t);
-        t.copy(&BIG::modneg(&mut u[9], &q));
+        t.copy(&Big::modneg(&mut u[9], &q));
         u[9].copy(&t);
-        t.copy(&BIG::modneg(&mut u[11], &q));
+        t.copy(&Big::modneg(&mut u[11], &q));
         u[11].copy(&t);
-        t.copy(&BIG::modneg(&mut u[13], &q));
+        t.copy(&Big::modneg(&mut u[13], &q));
         u[13].copy(&t);
-        t.copy(&BIG::modneg(&mut u[15], &q));
+        t.copy(&Big::modneg(&mut u[15], &q));
         u[15].copy(&t);
     }
     return u;
@@ -579,20 +579,20 @@ pub fn gs(e: &BIG) -> [BIG; 16] {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G1 */
-pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
+pub fn g1mul(P: &ECP, e: &mut Big) -> ECP {
     let mut R = ECP::new();
     if rom::USE_GLV {
         R.copy(P);
         let mut Q = ECP::new();
         Q.copy(P);
         Q.affine();
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut cru = FP::new_big(&BIG::new_ints(&rom::CURVE_CRU));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut cru = FP::new_big(&Big::new_ints(&rom::CURVE_CRU));
         let mut u = glv(e);
         Q.mulx(&mut cru);
 
         let mut np = u[0].nbits();
-        let mut t: BIG = BIG::modneg(&mut u[0], &q);
+        let mut t: Big = Big::modneg(&mut u[0], &q);
         let mut nn = t.nbits();
         if nn < np {
             u[0].copy(&t);
@@ -600,7 +600,7 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
         }
 
         np = u[1].nbits();
-        t = BIG::modneg(&mut u[1], &q);
+        t = Big::modneg(&mut u[1], &q);
         nn = t.nbits();
         if nn < np {
             u[1].copy(&t);
@@ -617,7 +617,7 @@ pub fn g1mul(P: &ECP, e: &mut BIG) -> ECP {
 
 #[allow(non_snake_case)]
 /* Multiply P by e in group G2 */
-pub fn g2mul(P: &ECP8, e: &BIG) -> ECP8 {
+pub fn g2mul(P: &ECP8, e: &Big) -> ECP8 {
     let mut R = ECP8::new();
     if rom::USE_GS_G2 {
         let mut Q: [ECP8; 16] = [
@@ -638,13 +638,13 @@ pub fn g2mul(P: &ECP8, e: &BIG) -> ECP8 {
             ECP8::new(),
             ECP8::new(),
         ];
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
+        let q = Big::new_ints(&rom::CURVE_ORDER);
         let mut u = gs(e);
         let mut T = ECP8::new();
 
         let f = ECP8::frob_constants();
 
-        let mut t = BIG::new();
+        let mut t = Big::new();
         Q[0].copy(&P);
         for i in 1..16 {
             T.copy(&Q[i - 1]);
@@ -653,7 +653,7 @@ pub fn g2mul(P: &ECP8, e: &BIG) -> ECP8 {
         }
         for i in 0..16 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);
@@ -671,7 +671,7 @@ pub fn g2mul(P: &ECP8, e: &BIG) -> ECP8 {
 
 /* f=f^e */
 /* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
-pub fn gtpow(d: &FP48, e: &BIG) -> FP48 {
+pub fn gtpow(d: &FP48, e: &Big) -> FP48 {
     let mut r = FP48::new();
     if rom::USE_GS_GT {
         let mut g: [FP48; 16] = [
@@ -692,9 +692,9 @@ pub fn gtpow(d: &FP48, e: &BIG) -> FP48 {
             FP48::new(),
             FP48::new(),
         ];
-        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
-        let q = BIG::new_ints(&rom::CURVE_ORDER);
-        let mut t = BIG::new();
+        let f = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
+        let q = Big::new_ints(&rom::CURVE_ORDER);
+        let mut t = Big::new();
         let mut u = gs(e);
         let mut w = FP48::new();
 
@@ -706,7 +706,7 @@ pub fn gtpow(d: &FP48, e: &BIG) -> FP48 {
         }
         for i in 0..16 {
             let np = u[i].nbits();
-            t.copy(&BIG::modneg(&mut u[i], &q));
+            t.copy(&Big::modneg(&mut u[i], &q));
             let nn = t.nbits();
             if nn < np {
                 u[i].copy(&t);


[incubator-milagro-crypto-rust] 37/44: Merge develop and fix conflicts

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 40b9037be7d7fe1abe6d376b153997d68599285d
Merge: cab5914 d6bd914
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Apr 22 10:21:13 2020 +1000

    Merge develop and fix conflicts
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>

 Cargo.lock                                         | 662 +++++++++++++++++++++
 Cargo.toml                                         |  16 +-
 src/big.rs                                         |  11 +-
 src/bls381.rs                                      | 424 +++++++++++++
 src/bls381/iso.rs                                  | 335 +++++++++++
 src/dbig.rs                                        |  21 +-
 src/ecp.rs                                         |  23 +
 src/ecp2.rs                                        |  45 +-
 src/errors.rs                                      |   4 +
 src/fp.rs                                          |  74 ++-
 src/fp2.rs                                         |  23 +
 src/hash256.rs                                     | 266 ++++++++-
 src/hash384.rs                                     | 228 +++++--
 src/hash512.rs                                     | 296 ++++++++-
 src/hash_to_curve.rs                               | 307 ++++++++++
 src/lib.rs                                         |  45 +-
 src/roms/{rom_bls381_32.rs => rom_bls381g1_32.rs}  |  36 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g1_64.rs}  |  38 +-
 src/roms/{rom_bls381_32.rs => rom_bls381g2_32.rs}  |  38 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g2_64.rs}  |  38 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 src/test_utils/mod.rs                              |  20 +
 src/test_utils/test_vector_structs.rs              |  44 ++
 30 files changed, 3542 insertions(+), 148 deletions(-)

diff --cc src/bls381.rs
index 0000000,de56701..f03576d
mode 000000,100644..100644
--- a/src/bls381.rs
+++ b/src/bls381.rs
@@@ -1,0 -1,424 +1,424 @@@
+ /*
+ 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.
+ */
+ 
+ /// BLS12-381
+ ///
+ /// An implementation of BLS12-381 as specified by the following standard:
+ /// https://github.com/cfrg/draft-irtf-cfrg-bls-signature
+ pub mod iso;
+ 
+ use self::iso::{iso11_to_ecp, iso3_to_ecp2};
+ use super::big::Big;
+ use super::ecp::ECP;
+ use super::ecp2::ECP2;
+ use super::fp::FP;
+ use super::fp2::FP2;
+ use super::hash_to_curve::*;
+ use super::pair;
+ use super::rom::*;
+ 
+ use rand::RAND;
+ use sha3::SHA3;
+ use sha3::SHAKE256;
+ use std::str;
+ 
+ // BLS API Functions
+ pub const BFS: usize = MODBYTES as usize;
+ pub const BGS: usize = MODBYTES as usize;
+ pub const BLS_OK: isize = 0;
+ pub const BLS_FAIL: isize = -1;
+ 
+ // Hash a message to an ECP point, using SHA3
+ #[allow(non_snake_case)]
+ fn bls_hashit(m: &str) -> ECP {
+     let mut sh = SHA3::new(SHAKE256);
+     let mut hm: [u8; BFS] = [0; BFS];
+     let t = m.as_bytes();
+     for i in 0..m.len() {
+         sh.process(t[i]);
+     }
+     sh.shake(&mut hm, BFS);
+     let P = ECP::mapit(&hm);
+     P
+ }
+ 
+ /// Generate key pair, private key s, public key w
+ pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
+     let q = Big::new_ints(&CURVE_ORDER);
+     let g = ECP2::generator();
+     let sc = Big::randomnum(&q, &mut rng);
+     sc.tobytes(s);
+     pair::g2mul(&g, &sc).tobytes(w);
+     BLS_OK
+ }
+ 
+ /// Sign message m using private key s to produce signature sig.
+ pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
+     let d = bls_hashit(m);
+     let mut sc = Big::frombytes(&s);
+     pair::g1mul(&d, &mut sc).tobytes(sig, true);
+     BLS_OK
+ }
+ 
+ /// Verify signature given message m, the signature sig, and the public key w
+ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
+     let hm = bls_hashit(m);
+     let mut d = ECP::frombytes(&sig);
+     let g = ECP2::generator();
+     let pk = ECP2::frombytes(&w);
+     d.neg();
+ 
+     // Use new multi-pairing mechanism
+     let mut r = pair::initmp();
+     pair::another(&mut r, &g, &d);
+     pair::another(&mut r, &pk, &hm);
+     let mut v = pair::miller(&r);
+ 
+     //.. or alternatively
+     //    let mut v = pair::ate2(&g, &d, &pk, &hm);
+ 
+     v = pair::fexp(&v);
+     if v.isunity() {
+         return BLS_OK;
+     }
+     BLS_FAIL
+ }
+ 
+ /*************************************************************************************************
+ * Functions for hashing to curve when signatures are on ECP
+ *************************************************************************************************/
+ /// Hash to Curve
+ ///
+ /// Takes a message as input and converts it to a Curve Point
+ /// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+ pub fn hash_to_curve_g1(msg: &[u8]) -> ECP {
+     let u =
+         hash_to_field_fp(msg, 2, DST).expect("hash to field should not fail for given parameters");
 -    let mut q0 = map_to_curve_g1(u[0]);
 -    let q1 = map_to_curve_g1(u[1]);
++    let mut q0 = map_to_curve_g1(u[0].clone());
++    let q1 = map_to_curve_g1(u[1].clone());
+     q0.add(&q1);
+     let p = q0.mul(&H_EFF_G1);
+     p
+ }
+ 
+ // Simplified SWU for Pairing-Friendly Curves
+ //
+ // Take a field point and map it to a Curve Point.
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+ fn map_to_curve_g1(u: FP) -> ECP {
+     let (x, y) = simplified_swu_fp(u);
+     iso11_to_ecp(&x, &y)
+ }
+ 
+ /*************************************************************************************************
+ * Functions for hashing to curve when signatures are on ECP2
+ *************************************************************************************************/
+ /// Hash to Curve
+ ///
+ /// Takes a message as input and converts it to a Curve Point
+ /// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+ pub fn hash_to_curve_g2(msg: &[u8]) -> ECP2 {
+     let u =
+         hash_to_field_fp2(msg, 2, DST).expect("hash to field should not fail for given parameters");
 -    let mut q0 = map_to_curve_g2(u[0]);
 -    let q1 = map_to_curve_g2(u[1]);
++    let mut q0 = map_to_curve_g2(u[0].clone());
++    let q1 = map_to_curve_g2(u[1].clone());
+     q0.add(&q1);
+     q0.clear_cofactor();
+     q0
+ }
+ 
+ // Simplified SWU for Pairing-Friendly Curves
+ //
+ // Take a field point and map it to a Curve Point.
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+ fn map_to_curve_g2(u: FP2) -> ECP2 {
+     let (x, y) = simplified_swu_fp2(u);
+     iso3_to_ecp2(&x, &y)
+ }
+ 
+ #[cfg(test)]
+ mod tests {
+     use super::*;
+     use crate::test_utils::*;
+ 
+     // The following tests were exported from
+     // https://github.com/kwantam/bls_sigs_ref/tree/master/python-impl
+     // Format: [(input, output)]
+     // input: [u0_a, u0_b, u1_a, u1_b]
+     // output: [x_a, x_b, y_a, y_b]
+     pub const TESTS: [([&str; 4], [&str; 4]); 4] =
+         [
+             // Test 0
+             (
+                 // Input
+                 [
+                     "004ad233c619209060e40059b81e4c1f92796b05aa1bc6358d65e53dc0d657dfbc713d4030b0b6d9234a6634fd1944e7",
+                     "0e2386c82713441bc3b06a460bd81850f4bf376ea89c80b18c0881e855c58dc8e83b2fd23af983f4786508e30c42af01",
+                     "08a6a75e0a8d32f1e096f29047ea879dd34a5504218d7ce92c32c244786822fb73fbf708d167ad86537468249ec6df48",
+                     "07016d0e5e13cd65780042c6f7b4c74ae1c58da438c99582696818b5c229895b893318dcb87d2a65e557d4ebeb408b70"
+                 ],
+                 // Output
+                 [
+                     "04861c41efcc5fc56e62273692b48da25d950d2a0aaffb34eff80e8dbdc2d41ca38555ceb8554368436aea47d16056b5",
+                     "09db5217528c55d982cf05fc54242bdcd25f1ebb73372e00e16d8e0f19dc3aeabdeef2d42d693405a04c37d60961526a",
+                     "177d05b95e7879a7ddbd83c15114b5a4e9846fde72b2263072dc9e60db548ccbadaacb92cc4952d4f47425fe3c5e0172",
+                     "0fc82c99b928ed9df12a74f9215c3df8ae1e9a3fa54c00897889296890b23a0edcbb9653f9170bf715f882b35c0b4647"
+                 ]
+             ),
+             // Test 1
+             (
+                 // Input
+                 [
+                     "083c57b3ee2ecba5bbf874bb03897827f949096efceea00f002c979de7e5e9429fcf1f3323d4c8c548cd6f8ecb1a5c1d",
+                     "0344fdfe8e1401867a275b3bef7e6ec52450968ab8a1293938fe3d5712dda67c85afeb91d85ab83fcdbebba4dc913e44",
+                     "1361b5ee134c6bee4e287e63f852b6e48546dcf0684af7cf3e7653a3427a609f769ce4d9d99a638b6ae432130fa43104",
+                     "18425b12c2ab5de136eb493b88ca950a45cab942505b5dd59a8b3ae8ec34c40ada65ff2719b1fcda9769fb22882002f9"
+                 ],
+                 // Output
+                 [
+                     "15f7a5c1168ad5ab67ff285c80fa8dd932ca88d9f8b3803c6c7b1f525d2dd5d01f2418259ae167c17c514d55e4707ddb",
+                     "04378269c7364a6cefcdafdb87b004d3ebf6853f46687e46f29f23196d47a176c6f858be34c9f9a3608c74e804f6c686",
+                     "023d9d46abe82bc0ac7c104d9519c037ff72893b8371d72ab92378f60a2361d7171df6b33500828c88923ddb1aab7fa5",
+                     "1015adfeece3613836bf82541ea560c701e197b3d081e2c242b217d809f4ac0ca787b402537a66c0d1f6b76e1b19e94b"
+                 ]
+             ),
+             // Test 2
+             (
+                 // Input
+                 [
+                     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                     "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+                 ],
+                 // Output
+                 [
+                     "19da1b4d47efeeb154f8968b43da2125376e0999ba722141419b03fd857490562fa42a5d0973956d1932dd20c1e0a284",
+                     "18426da25dadd359adfda64fbaddac4414da2a841cb467935289877db450fac424361efb2e7fb141b7b98e6b2f888aef",
+                     "0c2f8d431770d9be9b087c36fc5b66bb83ce6372669f48294193ef646105e0f21d17b134e7d1ad9c18f54b81f6a3707b",
+                     "03257c3be77016e69b75905a97871008a6dfd2e324a6748c48d3304380156987bd0905991824936fcfe34ab25c3b6caa"
+                 ]
+             ),
+             // Test 3
+             (
+                 // Input
+                 [
+                     "05495a3dfa360cb809c1904530db1986aea4bf356e634b40b51e0ee5fcb6cb75085a72a0626873a426470067627c6418",
+                     "11e63b587bedb59c2140518565950bdf881d75c0cccdcedcd9f4b71f2cfede3e5fdbe0261b015562d5edeaa11b7b2b76",
+                     "116c87bbeece66871eb6c2a51bc4327b10ffe470b49c28ef8eef624da766caa2cc9ff6c7042b26b2efd3404f5a81a140",
+                     "010450a90c17ba2997b645ef340fb5b207d6c915b34a93d93e75ee905d6d203d4aac046e10bd4d94a215604ade7afa8e"
+                 ],
+                 // Output
+                 [
+                     "0f1614a6e91c3e00799098fded2f2cfd72cb585cbdaec41b478509913c6772266a764f00b24a7f99607948a4b69b4d8f",
+                     "13ca2148705ca7ba49c92ab8985d7babcc8afc6bf8e397fb829f5fe3f49e51c41332ba4389f5ba66667310b22bea16c9",
+                     "026a743ee00eec8c7ef63351f4a3b26b2f029c10130385efc56ce53d0788db32ff5296ab77f9c389bd196cce8fc1e888",
+                     "0d458d80897e922f3e7e15cfa66a0d3645d95788bddb7478af3f1b5ca662c348b0e9ffdb88fabfdb74f103fea0c2d793"
+                 ]
+             )
+         ];
+ 
+     #[test]
+     fn test_map_to_curve_g2() {
+         // Only run when signatures are on G2
+         if BLS_SIG_G1 {
+             return;
+         }
+ 
+         for test in &TESTS {
+             // Input u0 and u1
+             let a = Big::frombytes(&hex::decode(test.0[0]).unwrap());
+             let b = Big::frombytes(&hex::decode(test.0[1]).unwrap());
 -            let u0 = FP2::new_bigs(&a, &b);
++            let u0 = FP2::new_bigs(a, b);
+             let a = Big::frombytes(&hex::decode(test.0[2]).unwrap());
+             let b = Big::frombytes(&hex::decode(test.0[3]).unwrap());
 -            let u1 = FP2::new_bigs(&a, &b);
++            let u1 = FP2::new_bigs(a, b);
+ 
+             // Map to Curve
+             let (iso3_0_x, iso3_0_y) = simplified_swu_fp2(u0);
+             let (iso3_1_x, iso3_1_y) = simplified_swu_fp2(u1);
+ 
+             // 3-Isogeny Map
+             let mut q0 = iso3_to_ecp2(&iso3_0_x, &iso3_0_y);
+             let q1 = iso3_to_ecp2(&iso3_1_x, &iso3_1_y);
+             q0.add(&q1);
+ 
+             // Clear Cofactor
+             q0.clear_cofactor();
+ 
+             // Check expected values
+             let a = Big::frombytes(&hex::decode(test.1[0]).unwrap());
+             let b = Big::frombytes(&hex::decode(test.1[1]).unwrap());
 -            let check_x = FP2::new_bigs(&a, &b);
++            let check_x = FP2::new_bigs(a, b);
+             let a = Big::frombytes(&hex::decode(test.1[2]).unwrap());
+             let b = Big::frombytes(&hex::decode(test.1[3]).unwrap());
 -            let check_y = FP2::new_bigs(&a, &b);
 -            let check_e = ECP2::new_fp2s(&check_x, &check_y);
++            let check_y = FP2::new_bigs(a, b);
++            let check_e = ECP2::new_fp2s(check_x, check_y);
+ 
+             assert!(q0.equals(&check_e));
+         }
+     }
+ 
+     #[test]
+     #[cfg(feature = "bls381g2")]
+     fn test_hash_to_curve_g2() {
+         // Only run when signatures are on G2
+         if BLS_SIG_G1 {
+             return;
+         }
+ 
+         // Read hash to curve test vector
+         let reader = json_reader(H2C_SUITE);
+         let test_vectors: Bls12381Ro = serde_json::from_reader(reader).unwrap();
+ 
+         // Iterate through each individual case
+         for case in test_vectors.vectors {
+             // Execute hash to curve
+             let u = hash_to_field_fp2(case.msg.as_bytes(), 2, test_vectors.dst.as_bytes()).unwrap();
 -            let q0 = map_to_curve_g2(u[0]);
 -            let q1 = map_to_curve_g2(u[1]);
++            let q0 = map_to_curve_g2(u[0].clone());
++            let q1 = map_to_curve_g2(u[1].clone());
+             let mut r = q0.clone();
+             r.add(&q1);
+             let mut p = r.clone();
+             p.clear_cofactor();
+ 
+             // Verify hash to curve outputs
+             // Check u
+             assert_eq!(case.u.len(), u.len());
+             for (i, u_str) in case.u.iter().enumerate() {
+                 // Convert case 'u[i]' to FP2
+                 let u_str_parts: Vec<&str> = u_str.split(',').collect();
+                 let a = Big::frombytes(&hex::decode(&u_str_parts[0].get(2..).unwrap()).unwrap());
+                 let b = Big::frombytes(&hex::decode(&u_str_parts[1].get(2..).unwrap()).unwrap());
 -                let expected_u_i = FP2::new_bigs(&a, &b);
++                let expected_u_i = FP2::new_bigs(a, b);
+ 
+                 // Verify u[i]
+                 assert_eq!(expected_u_i, u[i]);
+             }
+ 
+             // Check Q0
+             let x_str_parts: Vec<&str> = case.Q0.x.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_x = FP2::new_bigs(&a, &b);
++            let expected_x = FP2::new_bigs(a, b);
+ 
+             let y_str_parts: Vec<&str> = case.Q0.y.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_y = FP2::new_bigs(&a, &b);
++            let expected_y = FP2::new_bigs(a, b);
+ 
 -            let expected_q0 = ECP2::new_fp2s(&expected_x, &expected_y);
++            let expected_q0 = ECP2::new_fp2s(expected_x, expected_y);
+             assert_eq!(expected_q0, q0);
+ 
+             // Check Q1
+             let x_str_parts: Vec<&str> = case.Q1.x.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_x = FP2::new_bigs(&a, &b);
++            let expected_x = FP2::new_bigs(a, b);
+ 
+             let y_str_parts: Vec<&str> = case.Q1.y.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_y = FP2::new_bigs(&a, &b);
++            let expected_y = FP2::new_bigs(a, b);
+ 
 -            let expected_q1 = ECP2::new_fp2s(&expected_x, &expected_y);
++            let expected_q1 = ECP2::new_fp2s(expected_x, expected_y);
+             assert_eq!(expected_q1, q1);
+ 
+             // Check P
+             let x_str_parts: Vec<&str> = case.P.x.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_x = FP2::new_bigs(&a, &b);
++            let expected_x = FP2::new_bigs(a, b);
+ 
+             let y_str_parts: Vec<&str> = case.P.y.split(',').collect();
+             let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+             let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
 -            let expected_y = FP2::new_bigs(&a, &b);
++            let expected_y = FP2::new_bigs(a, b);
+ 
 -            let expected_p = ECP2::new_fp2s(&expected_x, &expected_y);
++            let expected_p = ECP2::new_fp2s(expected_x, expected_y);
+             assert_eq!(expected_p, p);
+         }
+     }
+ 
+     #[test]
+     #[cfg(feature = "bls381g1")]
+     fn test_hash_to_curve_g1() {
+         // Only run when signatures are on G2
+         if !BLS_SIG_G1 {
+             return;
+         }
+ 
+         // Read hash to curve test vector
+         let reader = json_reader(H2C_SUITE);
+         let test_vectors: Bls12381Ro = serde_json::from_reader(reader).unwrap();
+ 
+         // Iterate through each individual case
+         for case in test_vectors.vectors {
+             // Execute hash to curve
+             let u = hash_to_field_fp(case.msg.as_bytes(), 2, test_vectors.dst.as_bytes()).unwrap();
 -            let q0 = map_to_curve_g1(u[0]);
 -            let q1 = map_to_curve_g1(u[1]);
++            let q0 = map_to_curve_g1(u[0].clone());
++            let q1 = map_to_curve_g1(u[1].clone());
+             let mut r = q0.clone();
+             r.add(&q1);
+             let p = r.mul(&H_EFF_G1);
+ 
+             // Verify hash to curve outputs
+             // Check u
+             assert_eq!(case.u.len(), u.len());
+             for (i, u_str) in case.u.iter().enumerate() {
+                 // Convert case 'u[i]' to FP
+                 let a = Big::frombytes(&hex::decode(&u_str.get(2..).unwrap()).unwrap());
 -                let expected_u_i = FP::new_big(&a);
++                let expected_u_i = FP::new_big(a);
+ 
+                 // Verify u[i]
+                 assert_eq!(expected_u_i, u[i]);
+             }
+ 
+             // Check Q0
+             let a = Big::frombytes(&hex::decode(&case.Q0.x.get(2..).unwrap()).unwrap());
 -            let expected_x = FP::new_big(&a);
++            let expected_x = FP::new_big(a);
+ 
+             let a = Big::frombytes(&hex::decode(&case.Q0.y.get(2..).unwrap()).unwrap());
 -            let expected_y = FP::new_big(&a);
++            let expected_y = FP::new_big(a);
+ 
+             let expected_q0 = ECP::new_fps(expected_x, expected_y);
+             assert_eq!(expected_q0, q0);
+ 
+             // Check Q1
+             let a = Big::frombytes(&hex::decode(&case.Q1.x.get(2..).unwrap()).unwrap());
 -            let expected_x = FP::new_big(&a);
++            let expected_x = FP::new_big(a);
+ 
+             let a = Big::frombytes(&hex::decode(&case.Q1.y.get(2..).unwrap()).unwrap());
 -            let expected_y = FP::new_big(&a);
++            let expected_y = FP::new_big(a);
+ 
+             let expected_q1 = ECP::new_fps(expected_x, expected_y);
+             assert_eq!(expected_q1, q1);
+ 
+             // Check P
+             let a = Big::frombytes(&hex::decode(&case.P.x.get(2..).unwrap()).unwrap());
 -            let expected_x = FP::new_big(&a);
++            let expected_x = FP::new_big(a);
+ 
+             let a = Big::frombytes(&hex::decode(&case.P.y.get(2..).unwrap()).unwrap());
 -            let expected_y = FP::new_big(&a);
++            let expected_y = FP::new_big(a);
+ 
+             let expected_p = ECP::new_fps(expected_x, expected_y);
+             assert_eq!(expected_p, p);
+         }
+     }
+ }
diff --cc src/bls381/iso.rs
index 0000000,b00fb3d..bbf4f82
mode 000000,100644..100644
--- a/src/bls381/iso.rs
+++ b/src/bls381/iso.rs
@@@ -1,0 -1,335 +1,335 @@@
+ /*
+ 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 super::super::big::Big;
+ use super::super::ecp::ECP;
+ use super::super::ecp2::ECP2;
+ use super::super::fp::FP;
+ use super::super::fp2::FP2;
+ 
+ /**************************************************
+ * 3-Isogeny Constants
+ **************************************************/
+ lazy_static! {
+     // ISO-3 Mapping values
+     pub static ref ISO3_XNUM: [FP2; 4] = [
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap()),
 -            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap())
++            Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap()),
++            Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::new(),
 -            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a").unwrap())
++            Big::new(),
++            Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e").unwrap()),
 -            &Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d").unwrap())
++            Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e").unwrap()),
++            Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1").unwrap()),
 -            &Big::new()
++            Big::frombytes(&hex::decode("171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1").unwrap()),
++            Big::new()
+         )
+     ];
+     pub static ref ISO3_XDEN: [FP2; 4] = [
+         FP2::new_bigs(
 -            &Big::new(),
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63").unwrap())
++            Big::new(),
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::new_int(12),
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f").unwrap())
++            Big::new_int(12),
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f").unwrap())
+         ),
+         FP2::new_int(1),
+         FP2::new(),
+     ];
+     pub static ref ISO3_YNUM: [FP2; 4] = [
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap()),
 -            &Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap())
++            Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap()),
++            Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::new(),
 -            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be").unwrap())
++            Big::new(),
++            Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c").unwrap()),
 -            &Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f").unwrap())
++            Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c").unwrap()),
++            Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10").unwrap()),
 -            &Big::new()
++            Big::frombytes(&hex::decode("124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10").unwrap()),
++            Big::new()
+         )
+     ];
+     pub static ref ISO3_YDEN: [FP2; 4] = [
+         FP2::new_bigs(
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap()),
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap())
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap()),
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::new(),
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3").unwrap())
++            Big::new(),
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3").unwrap())
+         ),
+         FP2::new_bigs(
 -            &Big::new_int(18),
 -            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99").unwrap())
++            Big::new_int(18),
++            Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99").unwrap())
+         ),
+         FP2::new_ints(1, 0)
+     ];
+ 
+     // ISO-11 Mapping values
+     pub static ref ISO11_XNUM: [FP; 12] = [
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7").unwrap()),
++            Big::frombytes(&hex::decode("11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb").unwrap())
++            Big::frombytes(&hex::decode("17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0d54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0").unwrap()),
++            Big::frombytes(&hex::decode("0d54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861").unwrap()),
++            Big::frombytes(&hex::decode("1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0e99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9").unwrap()),
++            Big::frombytes(&hex::decode("0e99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983").unwrap()),
++            Big::frombytes(&hex::decode("1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0d6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84").unwrap()),
++            Big::frombytes(&hex::decode("0d6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e").unwrap()),
++            Big::frombytes(&hex::decode("17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("080d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317").unwrap()),
++            Big::frombytes(&hex::decode("080d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e").unwrap()),
++            Big::frombytes(&hex::decode("169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b").unwrap()),
++            Big::frombytes(&hex::decode("10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("06e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229").unwrap()),
++            Big::frombytes(&hex::decode("06e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229").unwrap()),
+         ),
+     ];
+     pub static ref ISO11_XDEN: [FP; 11] = [
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("08ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c").unwrap())
++            Big::frombytes(&hex::decode("08ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff").unwrap())
++            Big::frombytes(&hex::decode("12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0b2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19").unwrap())
++            Big::frombytes(&hex::decode("0b2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("03425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8").unwrap())
++            Big::frombytes(&hex::decode("03425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e").unwrap())
++            Big::frombytes(&hex::decode("13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0e7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5").unwrap())
++            Big::frombytes(&hex::decode("0e7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a").unwrap())
++            Big::frombytes(&hex::decode("0772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e").unwrap())
++            Big::frombytes(&hex::decode("14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0a10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641").unwrap())
++            Big::frombytes(&hex::decode("0a10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641").unwrap())
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("095fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a").unwrap())
++            Big::frombytes(&hex::decode("095fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a").unwrap())
+         ),
+         FP::new_int(1),
+     ];
+     pub static ref ISO11_YNUM: [FP; 16] = [
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("090d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33").unwrap()),
++            Big::frombytes(&hex::decode("090d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696").unwrap()),
++            Big::frombytes(&hex::decode("134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("00cc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6").unwrap()),
++            Big::frombytes(&hex::decode("00cc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("01f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb").unwrap()),
++            Big::frombytes(&hex::decode("01f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("08cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb").unwrap()),
++            Big::frombytes(&hex::decode("08cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0").unwrap()),
++            Big::frombytes(&hex::decode("16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("04ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2").unwrap()),
++            Big::frombytes(&hex::decode("04ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29").unwrap()),
++            Big::frombytes(&hex::decode("0987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("09fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587").unwrap()),
++            Big::frombytes(&hex::decode("09fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0e1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30").unwrap()),
++            Big::frombytes(&hex::decode("0e1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132").unwrap()),
++            Big::frombytes(&hex::decode("19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e").unwrap()),
++            Big::frombytes(&hex::decode("18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0b182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8").unwrap()),
++            Big::frombytes(&hex::decode("0b182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133").unwrap()),
++            Big::frombytes(&hex::decode("0245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("05c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b").unwrap()),
++            Big::frombytes(&hex::decode("05c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604").unwrap()),
++            Big::frombytes(&hex::decode("15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604").unwrap()),
+         ),
+     ];
+     pub static ref ISO11_YDEN: [FP; 16] = [
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1").unwrap()),
++            Big::frombytes(&hex::decode("16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d").unwrap()),
++            Big::frombytes(&hex::decode("1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("058df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2").unwrap()),
++            Big::frombytes(&hex::decode("058df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416").unwrap()),
++            Big::frombytes(&hex::decode("16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0be0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d").unwrap()),
++            Big::frombytes(&hex::decode("0be0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("08d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac").unwrap()),
++            Big::frombytes(&hex::decode("08d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c").unwrap()),
++            Big::frombytes(&hex::decode("166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9").unwrap()),
++            Big::frombytes(&hex::decode("16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a").unwrap()),
++            Big::frombytes(&hex::decode("1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55").unwrap()),
++            Big::frombytes(&hex::decode("167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("04d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8").unwrap()),
++            Big::frombytes(&hex::decode("04d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0accbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092").unwrap()),
++            Big::frombytes(&hex::decode("0accbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0ad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc").unwrap()),
++            Big::frombytes(&hex::decode("0ad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("02660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7").unwrap()),
++            Big::frombytes(&hex::decode("02660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7").unwrap()),
+         ),
+         FP::new_big(
 -            &Big::frombytes(&hex::decode("0e0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f").unwrap()),
++            Big::frombytes(&hex::decode("0e0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f").unwrap()),
+         ),
+         FP::new_int(1),
+     ];
+ }
+ 
+ /// Mapping from 11-Isogeny Curve to BLS12-381 ECP
+ ///
+ /// Adjusted from https://eprint.iacr.org/2019/403
+ /// to convert projectives to (XZ, YZ, Z)
+ pub fn iso11_to_ecp(iso_x: &FP, iso_y: &FP) -> ECP {
+     let polynomials_coefficients: [&[FP]; 4] =
+         [&*ISO11_XNUM, &*ISO11_XDEN, &*ISO11_YNUM, &*ISO11_YDEN];
+ 
+     // x-num, x-den, y-num, y-den
+     let mut mapped_vals: [FP; 4] = [FP::new(), FP::new(), FP::new(), FP::new()];
+ 
+     // Horner caculation for evaluating polynomials
+     for (i, coefficients) in polynomials_coefficients[..].iter().enumerate() {
+         mapped_vals[i] = coefficients[coefficients.len() - 1].clone();
+         for k in coefficients.iter().rev().skip(1) {
+             mapped_vals[i].mul(&iso_x);
+             mapped_vals[i].add(&k);
+         }
+     }
+ 
+     // y-num multiplied by y
+     mapped_vals[2].mul(&iso_y);
+ 
+     let mut z = mapped_vals[1].clone(); // x-den
+     z.mul(&mapped_vals[3]); // x-den * y-den
+ 
+     let mut x = mapped_vals[0].clone(); // x-num
+     x.mul(&mapped_vals[3]); // x-num * y-den
+ 
+     let mut y = mapped_vals[2].clone(); // y-num
+     y.mul(&mapped_vals[1]); // y-num * x-den
+ 
+     ECP::new_projective(x, y, z)
+ }
+ 
+ /// Mapping from 3-Isogeny Curve to BLS12-381 ECP2
+ ///
+ /// Adjusted from https://eprint.iacr.org/2019/403
+ /// to convert projectives to (XZ, YZ, Z)
+ pub fn iso3_to_ecp2(iso_x: &FP2, iso_y: &FP2) -> ECP2 {
+     let polynomials_coefficients: [&[FP2; 4]; 4] =
+         [&*ISO3_XNUM, &*ISO3_XDEN, &*ISO3_YNUM, &*ISO3_YDEN];
+ 
+     // x-num, x-den, y-num, y-den
+     let mut mapped_vals: [FP2; 4] = [FP2::new(), FP2::new(), FP2::new(), FP2::new()];
+ 
+     // Horner caculation for evaluating polynomials
+     for (i, coefficients) in polynomials_coefficients[..].iter().enumerate() {
+         mapped_vals[i] = coefficients[coefficients.len() - 1].clone();
+         for k in coefficients.iter().rev().skip(1) {
+             mapped_vals[i].mul(&iso_x);
+             mapped_vals[i].add(&k);
+         }
+     }
+ 
+     // y-num multiplied by y
+     mapped_vals[2].mul(&iso_y);
+ 
+     let mut z = mapped_vals[1].clone(); // x-den
+     z.mul(&mapped_vals[3]); // x-den * y-den
+ 
+     let mut x = mapped_vals[0].clone(); // x-num
+     x.mul(&mapped_vals[3]); // x-num * y-den
+ 
+     let mut y = mapped_vals[2].clone(); // y-num
+     y.mul(&mapped_vals[1]); // y-num * x-den
+ 
+     ECP2::new_projective(x, y, z)
+ }
diff --cc src/dbig.rs
index 6201d72,26b29bd..4fb5f64
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@@ -20,9 -20,9 +20,9 @@@ under the License
  use super::super::arch;
  use super::super::arch::Chunk;
  use super::big;
- use super::big::Big;
+ use super::big::{Big, MODBYTES};
  
 -#[derive(Copy)]
 +#[derive(Clone)]
  pub struct DBig {
      pub w: [Chunk; big::DNLEN],
  }
diff --cc src/ecp2.rs
index f86a005,25f7175..7c18d3c
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@@ -696,7 -727,12 +701,12 @@@ impl ECP2 
              x.inc(1);
              x.norm();
          }
+         Q.clear_cofactor();
+         Q
+     }
+ 
+     pub fn clear_cofactor(&mut self) {
 -        let mut X = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
 +        let mut X = FP2::new_bigs(Big::new_ints(&rom::FRA), Big::new_ints(&rom::FRB));
          if ecp::SEXTIC_TWIST == SexticTwist::MType {
              X.inverse();
              X.norm();
diff --cc src/fp.rs
index 4437d21,f1454c5..058d7a4
--- a/src/fp.rs
+++ b/src/fp.rs
@@@ -116,11 -124,10 +116,10 @@@ impl FP 
              let mut d = DBig::new_scopy(&(self.x));
              return FP::modulo(&mut d);
          }
 -        Big::new_copy(&(self.x))
 +        self.x.clone()
      }
  
-     // reduce a DBig to a Big using the appropriate form of the modulus
-     // dd
+     /// reduce a DBig to a Big using the appropriate form of the modulus
      pub fn modulo(d: &mut DBig) -> Big {
          if MODTYPE == ModType::PseudoMersenne {
              let mut b = Big::new();
@@@ -195,10 -202,10 +194,10 @@@
          self.redc().tostring()
      }
  
-     // reduce this mod Modulus
+     /// reduce this mod Modulus
      pub fn reduce(&mut self) {
          let mut m = Big::new_ints(&rom::MODULUS);
 -        let mut r = Big::new_copy(&m);
 +        let mut r = m.clone();
          let mut sb: usize;
          self.x.norm();
          if self.xes > 16 {
@@@ -222,16 -229,22 +221,16 @@@
          self.xes = 1;
      }
  
-     // test this=0?
+     /// test this=0?
      pub fn iszilch(&self) -> bool {
 -        let mut a = FP::new_copy(self);
 +        let mut a = self.clone();
          a.reduce();
          a.x.iszilch()
      }
  
-     // copy from Big b
 -    /// copy from FP b
 -    pub fn copy(&mut self, b: &FP) {
 -        self.x.copy(&(b.x));
 -        self.xes = b.xes;
 -    }
 -
+     /// copy from Big b
      pub fn bcopy(&mut self, b: &Big) {
 -        self.x.copy(&b);
 +        self.x = b.clone();
          self.nres();
      }
  
@@@ -381,9 -395,9 +381,9 @@@
          }
      }
  
-     // self-=b
+     /// self-=b
      pub fn sub(&mut self, b: &FP) {
 -        let mut n = FP::new_copy(b);
 +        let mut n = b.clone();
          n.neg();
          self.add(&n);
      }
@@@ -578,10 -596,10 +580,10 @@@
          }
      }
  
-     // return TRUE if self==a
+     /// return TRUE if self==a
      pub fn equals(&self, a: &FP) -> bool {
 -        let mut f = FP::new_copy(self);
 -        let mut s = FP::new_copy(a);
 +        let mut f = self.clone();
 +        let mut s = a.clone();
          f.reduce();
          s.reduce();
          if Big::comp(&(f.x), &(s.x)) == 0 {
diff --cc src/fp2.rs
index 84a6c85,12920f4..82a10a9
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@@ -58,32 -58,52 +58,39 @@@ impl FP2 
      }
  
      pub fn new_int(a: isize) -> FP2 {
 -        let mut f = FP2::new();
 -        f.a.copy(&FP::new_int(a));
 -        f.b.zero();
 -        return f;
 +        FP2 {
 +            a: FP::new_int(a),
 +            b: FP::new(),
 +        }
      }
  
+     pub fn new_ints(a: isize, b: isize) -> FP2 {
 -        let mut f = FP2::new();
 -        f.a.copy(&FP::new_int(a));
 -        f.b.copy(&FP::new_int(b));
 -        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;
++        FP2 {
++            a: FP::new_int(a),
++            b: FP::new_int(b),
++        }
+     }
+ 
 -    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_fps(a: FP, b: FP) -> FP2 {
 +        FP2 { a, b }
      }
  
 -    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_bigs(c: Big, d: Big) -> FP2 {
 +        FP2 {
 +            a: FP::new_big(c),
 +            b: FP::new_big(d),
 +        }
      }
  
 -    pub fn new_fp(c: &FP) -> FP2 {
 -        let mut f = FP2::new();
 -        f.a.copy(c);
 -        f.b.zero();
 -        return f;
 +    pub fn new_fp(a: FP) -> FP2 {
 +        FP2 { a, b: FP::new() }
      }
  
 -    pub fn new_big(c: &Big) -> FP2 {
 -        let mut f = FP2::new();
 -        f.a.copy(&FP::new_big(c));
 -        f.b.zero();
 -        return f;
 +    pub fn new_big(c: Big) -> FP2 {
 +        FP2 {
 +            a: FP::new_big(c),
 +            b: FP::new(),
 +        }
      }
  
      /* reduce components mod Modulus */
@@@ -377,12 -405,28 +384,28 @@@
      pub fn div_ip(&mut self) {
          let mut t = FP2::new();
          self.norm();
 -        t.a.copy(&self.a);
 +        t.a = self.a.clone();
          t.a.add(&self.b);
 -        t.b.copy(&self.b);
 +        t.b = self.b.clone();
          t.b.sub(&self.a);
          t.norm();
 -        self.copy(&t);
 +        *self = t;
          self.div2();
      }
+ 
+     // ((a + b) , (a - b))
+     pub fn spmt(&mut self) {
+         let b = self.b.clone();
+         self.b = self.a.clone();
+         self.a.add(&b);
+         self.b.sub(&b);
+     }
+ 
+     // b > -b OR if b is 0 then a > -a
+     pub fn is_neg(&mut self) -> bool {
+         if self.b.iszilch() {
+             return self.a.is_neg();
+         }
+         self.b.is_neg()
+     }
  }
diff --cc src/hash_to_curve.rs
index 0000000,fe8d962..8adf370
mode 000000,100644..100644
--- a/src/hash_to_curve.rs
+++ b/src/hash_to_curve.rs
@@@ -1,0 -1,307 +1,307 @@@
+ use super::big::Big;
+ use super::dbig::DBig;
+ use super::fp::FP;
+ use super::fp2::FP2;
+ use super::rom::{
+     HASH_ALGORITHM, HASH_TYPE, L, MODULUS, SSWU_A1, SSWU_A2, SSWU_B1, SSWU_B2, SSWU_Z1, SSWU_Z2,
+     Z_PAD,
+ };
+ 
+ use errors::AmclError;
+ use hash256::HASH256;
+ use hash384::HASH384;
+ use hash512::HASH512;
+ 
+ /// Oversized DST padding
+ pub const OVERSIZED_DST: &[u8] = b"H2C-OVERSIZE-DST-";
+ 
+ #[derive(Copy, Clone)]
+ pub enum HashAlgorithm {
+     Sha256,
+     Sha384,
+     Sha512,
+ }
+ 
+ /// Hash a message
+ pub fn hash(msg: &[u8], hash_function: HashAlgorithm) -> Vec<u8> {
+     match hash_function {
+         HashAlgorithm::Sha256 => {
+             let mut hash = HASH256::new();
+             hash.init();
+             hash.process_array(msg);
+             hash.hash().to_vec()
+         }
+         HashAlgorithm::Sha384 => {
+             let mut hash = HASH384::new();
+             hash.init();
+             hash.process_array(msg);
+             hash.hash().to_vec()
+         }
+         HashAlgorithm::Sha512 => {
+             let mut hash = HASH512::new();
+             hash.init();
+             hash.process_array(msg);
+             hash.hash().to_vec()
+         }
+     }
+ }
+ 
+ // Hash To Field - Fp
+ //
+ // Take a message as bytes and convert it to a Field Point
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+ pub fn hash_to_field_fp(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP>, AmclError> {
+     let m = 1;
+     let p = Big::new_ints(&MODULUS);
+ 
+     let len_in_bytes = count * m * L;
+     let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+ 
+     let mut u: Vec<FP> = Vec::with_capacity(count as usize);
+     for i in 0..count as usize {
+         let elm_offset = L as usize * i * m as usize;
+         let mut dbig = DBig::frombytes(&pseudo_random_bytes[elm_offset..elm_offset + L as usize]);
+         let e: Big = dbig.dmod(&p);
 -        u.push(FP::new_big(&e));
++        u.push(FP::new_big(e));
+     }
+     Ok(u)
+ }
+ 
+ // Hash To Field - Fp2
+ //
+ // Take a message as bytes and convert it to a vector of Field Points with extension degree 2.
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+ pub fn hash_to_field_fp2(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP2>, AmclError> {
+     let m = 2;
+     let p = Big::new_ints(&MODULUS);
+ 
+     let len_in_bytes = count * m * L;
+ 
+     let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+ 
+     let mut u: Vec<FP2> = Vec::with_capacity(count as usize);
+     for i in 0..count as usize {
+         let mut e: Vec<Big> = Vec::with_capacity(m as usize);
+         for j in 0..m as usize {
+             let elm_offset = L as usize * (j + i * m as usize);
+             let mut big =
+                 DBig::frombytes(&pseudo_random_bytes[elm_offset..elm_offset + L as usize]);
+             e.push(big.dmod(&p));
+         }
 -        u.push(FP2::new_bigs(&e[0], &e[1]));
++        u.push(FP2::new_bigs(e[0].clone(), e[1].clone()));
+     }
+     Ok(u)
+ }
+ 
+ // Expand Message XMD
+ //
+ // Take a message and convert it to pseudo random bytes of specified length
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.3.1
+ pub fn expand_message_xmd(
+     msg: &[u8],
+     len_in_bytes: usize,
+     dst: &[u8],
+     hash_algorithm: HashAlgorithm,
+ ) -> Result<Vec<u8>, AmclError> {
+     // ell = ceiling(len_in_bytes / b_in_bytes)
+     let ell = (len_in_bytes + HASH_TYPE - 1) / HASH_TYPE;
+ 
+     // Error if length of output less than 255 bytes
+     if ell >= 255 {
+         return Err(AmclError::HashToFieldError);
+     }
+ 
+     // Create DST prime as (dst.len() || dst)
+     let dst_prime = if dst.len() > 256 {
+         // DST too long, shorten to H("H2C-OVERSIZE-DST-" || dst)
+         let mut tmp = OVERSIZED_DST.to_vec();
+         tmp.extend_from_slice(dst);
+         let mut prime = vec![32u8; 1];
+         prime.append(&mut hash(&tmp, hash_algorithm));
+         prime
+     } else {
+         // DST correct size, prepend length as a single byte
+         let mut prime = vec![dst.len() as u8; 1];
+         prime.extend_from_slice(dst);
+         prime
+     };
+ 
+     let mut pseudo_random_bytes: Vec<u8> = vec![];
+     let mut b: Vec<Vec<u8>> = vec![vec![]; 2];
+ 
+     // Set b[0] to H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime)
+     let mut tmp = Z_PAD.to_vec();
+     tmp.extend_from_slice(msg);
+     let l_i_b_str: &[u8] = &(len_in_bytes as u16).to_be_bytes();
+     tmp.extend_from_slice(l_i_b_str);
+     tmp.push(0u8);
+     tmp.extend_from_slice(&dst_prime);
+     b[0] = hash(&tmp, hash_algorithm);
+ 
+     // Set b[1] to H(b_0 || I2OSP(1, 1) || DST_prime)
+     tmp = b[0].clone();
+     tmp.push(1u8);
+     tmp.extend_from_slice(&dst_prime);
+     b[1] = hash(&tmp, hash_algorithm);
+ 
+     pseudo_random_bytes.extend_from_slice(&b[1]);
+ 
+     for i in 2..=ell {
+         // Set b[i] to H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
+         tmp = b[0]
+             .iter()
+             .enumerate()
+             .map(|(j, b_0)| {
+                 // Perform strxor(b[0], b[i-1])
+                 b_0 ^ b[i - 1][j] // b[i].len() will all be 32 bytes as they are SHA256 output.
+             })
+             .collect();
+         tmp.push(i as u8); // i < 256
+         tmp.extend_from_slice(&dst_prime);
+         b.push(hash(&tmp, hash_algorithm));
+ 
+         pseudo_random_bytes.extend_from_slice(&b[i]);
+     }
+ 
+     // Take required length
+     Ok(pseudo_random_bytes[..len_in_bytes as usize].to_vec())
+ }
+ 
+ // Simplified Shallue-van de Woestijne-Ulas Method - Fp
+ //
+ // Returns projectives as (XZ, YZ, Z)
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+ pub fn simplified_swu_fp(u: FP) -> (FP, FP) {
+     // tmp1 = Z * u^2
+     // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
+     let mut tmp1 = u.clone();
+     let is_neg_u = tmp1.is_neg();
+     tmp1.sqr();
+     tmp1.mul(&SSWU_Z1);
+     let mut tv1 = tmp1.clone();
+     tv1.sqr();
+     tv1.add(&tmp1);
+     tv1.inverse();
+ 
+     // x = (-B / A) * (1 + tv1)
+     let mut x = tv1.clone();
+     x.add(&FP::new_int(1));
+     x.mul(&SSWU_B1); // b * (Z^2 * u^4 + Z * u^2 + 1)
+     x.neg();
+     let mut a_inverse = SSWU_A1.clone();
+     a_inverse.inverse();
+     x.mul(&a_inverse);
+ 
+     // Deal with case where Z^2 * u^4 + Z * u^2 == 0
+     if tv1.iszilch() {
+         // x = B / (Z * A)
+         x = SSWU_Z1.clone();
+         x.inverse();
+         x.mul(&SSWU_B1);
+         x.mul(&a_inverse);
+     }
+ 
+     // gx = x^3 + A * x + B
+     let mut gx = x.clone();
+     gx.sqr();
+     gx.add(&SSWU_A1);
+     gx.mul(&x);
+     gx.add(&SSWU_B1);
+ 
+     // y = sqrt(gx)
+     let mut y = gx.clone();
+     let mut y = y.sqrt();
+ 
+     // Check y is valid square root
+     let mut y2 = y.clone();
+     y2.sqr();
+     if !gx.equals(&y2) {
+         // x = x * Z^2 * u
+         x.mul(&tmp1);
+ 
+         // gx = x^3 + A * x + B
+         let mut gx = x.clone();
+         gx.sqr();
+         gx.add(&SSWU_A1);
+         gx.mul(&x);
+         gx.add(&SSWU_B1);
+ 
+         y = gx.sqrt();
+         y2 = y.clone();
+         y2.sqr();
+         assert_eq!(gx, y2, "Hash to Curve SSWU failure - no square roots");
+     }
+ 
+     // Negate y if y and t are opposite in sign
+     if is_neg_u != y.is_neg() {
+         y.neg();
+     }
+ 
+     (x, y)
+ }
+ 
+ // Simplified Shallue-van de Woestijne-Ulas Method - Fp2
+ //
+ // Returns projectives as (X, Y)
+ // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+ pub fn simplified_swu_fp2(u: FP2) -> (FP2, FP2) {
+     // tmp1 = Z * u^2
+     // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
+     let mut tmp1 = u.clone();
+     let is_neg_u = tmp1.is_neg();
+     tmp1.sqr();
+     tmp1.mul(&SSWU_Z2);
+     let mut tv1 = tmp1.clone();
+     tv1.sqr();
+     tv1.add(&tmp1);
+     tv1.inverse();
+ 
+     // x = (-B / A) * (1 + tv1)
+     let mut x = tv1.clone();
+     x.add(&FP2::new_ints(1, 0));
+     x.mul(&SSWU_B2); // b * (Z^2 * u^4 + Z * u^2 + 1)
+     x.neg();
+     let mut a_inverse = SSWU_A2.clone();
+     a_inverse.inverse();
+     x.mul(&a_inverse);
+ 
+     // Deal with case where Z^2 * u^4 + Z * u^2 == 0
+     if tv1.iszilch() {
+         // x = B / (Z * A)
+         x = SSWU_Z2.clone();
+         x.inverse();
+         x.mul(&SSWU_B2);
+         x.mul(&a_inverse);
+     }
+ 
+     // gx = x^3 + A * x + B
+     let mut gx = x.clone();
+     gx.sqr();
+     gx.add(&SSWU_A2);
+     gx.mul(&x);
+     gx.add(&SSWU_B2);
+ 
+     // y = sqrt(gx)
+     let mut y = gx.clone();
+     if !y.sqrt() {
+         // x = x * Z^2 * u
+         x.mul(&tmp1);
+ 
+         // gx = x^3 + A * x + B
+         let mut gx = x.clone();
+         gx.sqr();
+         gx.add(&SSWU_A2);
+         gx.mul(&x);
+         gx.add(&SSWU_B2);
+ 
+         y = gx;
+         assert!(y.sqrt(), "Hash to Curve SSWU failure - no square roots");
+     }
+ 
+     // Negate y if y and t are opposite in sign
+     if is_neg_u != y.is_neg() {
+         y.neg();
+     }
+ 
+     (x, y)
+ }
diff --cc src/roms/rom_bls381g1_32.rs
index e282e9d,f72806d..0add498
--- a/src/roms/rom_bls381g1_32.rs
+++ b/src/roms/rom_bls381g1_32.rs
@@@ -205,5 -208,34 +208,34 @@@ pub const CURVE_PAIRING_TYPE: CurvePair
  pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
  pub const ATE_BITS: usize = 65;
  pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
- pub const HASH_TYPE: usize = 32;
+ pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+ pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
  pub const AESKEY: usize = 16;
+ 
+ /// Signatures on G1: true, Signatures on G2: false
+ pub const BLS_SIG_G1: bool = true;
+ 
+ // BLS Standard Constants
+ /// L = ceil(ceil(log2(Q) + 128) / 8)
+ pub const L: usize = 64;
+ /// Hash to Curve Suite
+ pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
+ /// Domain Separation Tag
+ pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
+ /// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+ pub const Z_PAD: [u8; 64] = [0u8; 64];
+ 
+ lazy_static! {
+     // G1 h_eff
+     pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
 -    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
 -    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
++    pub static ref SSWU_A1: FP = FP::new_big(Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
++    pub static ref SSWU_B1: FP = FP::new_big(Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+     pub static ref SSWU_Z1: FP = FP::new_int(11);
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+     pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+     pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+     pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+ }
diff --cc src/roms/rom_bls381g1_64.rs
index 4d95fdb,51bd4b9..7032be0
--- a/src/roms/rom_bls381g1_64.rs
+++ b/src/roms/rom_bls381g1_64.rs
@@@ -207,5 -210,36 +210,36 @@@ pub const CURVE_PAIRING_TYPE: CurvePair
  pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
  pub const ATE_BITS: usize = 65;
  pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
- pub const HASH_TYPE: usize = 32;
+ pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+ pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
  pub const AESKEY: usize = 16;
+ 
+ /// Signatures on G1: true, Signatures on G2: false
+ pub const BLS_SIG_G1: bool = true;
+ 
+ // BLS Standard Constants
+ /// L = ceil(ceil(log2(Q) + 128) / 8)
+ pub const L: usize = 64;
+ /// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+ pub const B_IN_BYTES: usize = 32;
+ /// Hash to Curve Suite
+ pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
+ /// Domain Separation Tag
+ pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
+ /// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+ pub const Z_PAD: [u8; 64] = [0u8; 64];
+ 
+ lazy_static! {
+     // G1 h_eff
+     pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
 -    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
 -    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
++    pub static ref SSWU_A1: FP = FP::new_big(Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
++    pub static ref SSWU_B1: FP = FP::new_big(Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+     pub static ref SSWU_Z1: FP = FP::new_int(11);
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+     pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+     pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+     pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+ }
diff --cc src/roms/rom_bls381g2_32.rs
index e282e9d,af198a8..538e470
--- a/src/roms/rom_bls381g2_32.rs
+++ b/src/roms/rom_bls381g2_32.rs
@@@ -205,5 -208,36 +208,36 @@@ pub const CURVE_PAIRING_TYPE: CurvePair
  pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
  pub const ATE_BITS: usize = 65;
  pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
- pub const HASH_TYPE: usize = 32;
+ pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+ pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
  pub const AESKEY: usize = 16;
+ 
+ /// Signatures on G1: true, Signatures on G2: false
+ pub const BLS_SIG_G1: bool = false;
+ 
+ // BLS Standard Constants
+ /// L = ceil(ceil(log2(Q) + 128) / 8)
+ pub const L: usize = 64;
+ /// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+ pub const B_IN_BYTES: usize = 32;
+ /// Hash to Curve Suite
+ pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
+ /// Domain Separation Tag
+ pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
+ /// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+ pub const Z_PAD: [u8; 64] = [0u8; 64];
+ 
+ lazy_static! {
+     // G1 h_eff
+     pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
 -    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
 -    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
++    pub static ref SSWU_A1: FP = FP::new_big(Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
++    pub static ref SSWU_B1: FP = FP::new_big(Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+     pub static ref SSWU_Z1: FP = FP::new_int(11);
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+     pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+     pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+     pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+ }
diff --cc src/roms/rom_bls381g2_64.rs
index 4d95fdb,e3d6815..5b8968a
--- a/src/roms/rom_bls381g2_64.rs
+++ b/src/roms/rom_bls381g2_64.rs
@@@ -207,5 -210,36 +210,36 @@@ pub const CURVE_PAIRING_TYPE: CurvePair
  pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
  pub const ATE_BITS: usize = 65;
  pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
- pub const HASH_TYPE: usize = 32;
+ pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+ pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
  pub const AESKEY: usize = 16;
+ 
+ /// Signatures on G1: true, Signatures on G2: false
+ pub const BLS_SIG_G1: bool = false;
+ 
+ // BLS Standard Constants
+ /// L = ceil(ceil(log2(Q) + 128) / 8)
+ pub const L: usize = 64;
+ /// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+ pub const B_IN_BYTES: usize = 32;
+ /// Hash to Curve Suite
+ pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
+ /// Domain Separation Tag
+ pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
+ /// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+ pub const Z_PAD: [u8; 64] = [0u8; 64];
+ 
+ lazy_static! {
+     // G1 h_eff
+     pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
 -    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
 -    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
++    pub static ref SSWU_A1: FP = FP::new_big(Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
++    pub static ref SSWU_B1: FP = FP::new_big(Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+     pub static ref SSWU_Z1: FP = FP::new_int(11);
+ 
+     // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+     pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+     pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+     pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+ }


[incubator-milagro-crypto-rust] 23/44: Tidy up mutability requirements

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit dfdf99b5bb5ed2e8901ac4429e9c75ae317521a3
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Jan 24 17:21:51 2020 +1100

    Tidy up mutability requirements
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/big.rs  |  6 +++---
 src/fp.rs   | 12 +++++-------
 src/fp12.rs | 24 +++++++++---------------
 src/fp16.rs |  4 ++--
 src/fp2.rs  |  6 +++---
 src/fp24.rs | 16 +++++-----------
 src/fp4.rs  |  4 ++--
 src/fp48.rs | 16 +++++-----------
 src/fp8.rs  |  4 ++--
 9 files changed, 36 insertions(+), 56 deletions(-)

diff --git a/src/big.rs b/src/big.rs
index 8136873..0af6458 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -421,7 +421,7 @@ impl Big {
     /// To Byte Array
     ///
     /// Convert this Big to byte array from index `n`
-    pub fn tobytearray(&mut self, b: &mut [u8], n: usize) {
+    pub fn tobytearray(&self, b: &mut [u8], n: usize) {
         let mut c = Big::new_copy(self);
         c.norm();
 
@@ -446,7 +446,7 @@ impl Big {
     /// To Bytes
     ///
     /// Convert to bytes from index 0
-    pub fn tobytes(&mut self, b: &mut [u8]) {
+    pub fn tobytes(&self, b: &mut [u8]) {
         self.tobytearray(b, 0)
     }
 
@@ -470,7 +470,7 @@ impl Big {
     }
 
     /// self*=c and catch overflow in DBig
-    pub fn pxmul(&mut self, c: isize) -> DBig {
+    pub fn pxmul(&self, c: isize) -> DBig {
         let mut m = DBig::new();
         let mut carry = 0 as Chunk;
         for j in 0..NLEN {
diff --git a/src/fp.rs b/src/fp.rs
index 54eff31..45a828c 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -115,13 +115,11 @@ impl FP {
     }
 
     pub fn to_hex(&self) -> String {
-        let x = self.x;
-        let big = x.tostring();
-        format!("{} {}", self.xes, big)
+        format!("{} {}", self.xes, self.x.tostring())
     }
 
     // convert back to regular form
-    pub fn redc(&mut self) -> Big {
+    pub fn redc(&self) -> Big {
         if MODTYPE != ModType::PseudoMersenne && MODTYPE != ModType::GeneralisedMersenne {
             let mut d = DBig::new_scopy(&(self.x));
             return FP::modulo(&mut d);
@@ -201,7 +199,7 @@ impl FP {
     }
 
     // convert to string
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         self.redc().tostring()
     }
 
@@ -424,7 +422,7 @@ impl FP {
 
     // See eprint paper https://eprint.iacr.org/2018/1038
     // return this^(p-3)/4 or this^(p-5)/8
-    pub fn fpow(&mut self) -> FP {
+    pub fn fpow(&self) -> FP {
         let ac: [isize; 11] = [1, 2, 3, 6, 12, 15, 30, 60, 120, 240, 255];
         let mut xp: [FP; 11] = [
             FP::new(),
@@ -705,7 +703,7 @@ impl FP {
         }
     }
     // return jacobi symbol (this/Modulus)
-    pub fn jacobi(&mut self) -> isize {
+    pub fn jacobi(&self) -> isize {
         let p = Big::new_ints(&rom::MODULUS);
         let mut w = self.redc();
         return w.jacobi(&p);
diff --git a/src/fp12.rs b/src/fp12.rs
index 0ba5fc1..e0dc648 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -165,30 +165,24 @@ impl FP12 {
     /* test self=1 ? */
     pub fn isunity(&self) -> bool {
         let one = FP4::new_int(1);
-        return self.a.equals(&one) && self.b.iszilch() && self.c.iszilch();
+        self.a.equals(&one) && self.b.iszilch() && self.c.iszilch()
     }
 
     /* test self=x */
     pub fn equals(&self, x: &FP12) -> bool {
-        return self.a.equals(&x.a) && self.b.equals(&x.b) && self.c.equals(&x.c);
+        self.a.equals(&x.a) && self.b.equals(&x.b) && self.c.equals(&x.c)
     }
 
-    pub fn geta(&mut self) -> FP4 {
-        return self.a;
-        //        let f = FP4::new_copy(&self.a);
-        //        return f;
+    pub fn geta(&self) -> FP4 {
+        self.a
     }
 
-    pub fn getb(&mut self) -> FP4 {
-        return self.b;
-        //        let f = FP4::new_copy(&self.b);
-        //        return f;
+    pub fn getb(&self) -> FP4 {
+        self.b
     }
 
     pub fn getc(&mut self) -> FP4 {
-        return self.c;
-        //        let f = FP4::new_copy(&self.c);
-        //        return f;
+        self.c
     }
 
     /* copy self=x */
@@ -887,7 +881,7 @@ impl FP12 {
     }
 
     /* convert this to byte array */
-    pub fn tobytes(&mut self, w: &mut [u8]) {
+    pub fn tobytes(&self, w: &mut [u8]) {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
 
@@ -944,7 +938,7 @@ impl FP12 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!(
             "[{},{},{}]",
             self.a.tostring(),
diff --git a/src/fp16.rs b/src/fp16.rs
index 55dd573..d650771 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -108,7 +108,7 @@ impl FP16 {
     }
 
     /* test is w real? That is in a+ib test b is zero */
-    pub fn isreal(&mut self) -> bool {
+    pub fn isreal(&self) -> bool {
         return self.b.iszilch();
     }
     /* extract real part a */
@@ -294,7 +294,7 @@ impl FP16 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!("[{},{}]", self.a.tostring(), self.b.tostring());
     }
 
diff --git a/src/fp2.rs b/src/fp2.rs
index 7ed108b..87a0db1 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -133,12 +133,12 @@ impl FP2 {
     }
 
     /* extract a */
-    pub fn geta(&mut self) -> Big {
+    pub fn geta(&self) -> Big {
         return self.a.redc();
     }
 
     /* extract b */
-    pub fn getb(&mut self) -> Big {
+    pub fn getb(&self) -> Big {
         return self.b.redc();
     }
 
@@ -322,7 +322,7 @@ impl FP2 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!("[{},{}]", self.a.tostring(), self.b.tostring());
     }
 
diff --git a/src/fp24.rs b/src/fp24.rs
index 93c1266..12cd1ab 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -167,22 +167,16 @@ impl FP24 {
         return self.a.equals(&x.a) && self.b.equals(&x.b) && self.c.equals(&x.c);
     }
 
-    pub fn geta(&mut self) -> FP8 {
+    pub fn geta(&self) -> FP8 {
         return self.a;
-        //        let f = FP8::new_copy(&self.a);
-        //        return f;
     }
 
-    pub fn getb(&mut self) -> FP8 {
+    pub fn getb(&self) -> FP8 {
         return self.b;
-        //	let f = FP8::new_copy(&self.b);
-        //        return f;
     }
 
-    pub fn getc(&mut self) -> FP8 {
+    pub fn getc(&self) -> FP8 {
         return self.c;
-        //        let f = FP8::new_copy(&self.c);
-        //        return f;
     }
 
     /* copy self=x */
@@ -962,7 +956,7 @@ impl FP24 {
     }
 
     /* convert this to byte array */
-    pub fn tobytes(&mut self, w: &mut [u8]) {
+    pub fn tobytes(&self, w: &mut [u8]) {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
 
@@ -1070,7 +1064,7 @@ impl FP24 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!(
             "[{},{},{}]",
             self.a.tostring(),
diff --git a/src/fp4.rs b/src/fp4.rs
index 3fda179..88b5d03 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -114,7 +114,7 @@ impl FP4 {
     }
 
     /* test is w real? That is in a+ib test b is zero */
-    pub fn isreal(&mut self) -> bool {
+    pub fn isreal(&self) -> bool {
         return self.b.iszilch();
     }
     /* extract real part a */
@@ -302,7 +302,7 @@ impl FP4 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!("[{},{}]", self.a.tostring(), self.b.tostring());
     }
 
diff --git a/src/fp48.rs b/src/fp48.rs
index 8ab6063..ad1cf53 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -168,22 +168,16 @@ impl FP48 {
         return self.a.equals(&x.a) && self.b.equals(&x.b) && self.c.equals(&x.c);
     }
 
-    pub fn geta(&mut self) -> FP16 {
+    pub fn geta(&self) -> FP16 {
         return self.a;
-        //        let f = FP16::new_copy(&self.a);
-        //        return f;
     }
 
-    pub fn getb(&mut self) -> FP16 {
+    pub fn getb(&self) -> FP16 {
         return self.b;
-        //        let f = FP16::new_copy(&self.b);
-        //        return f;
     }
 
-    pub fn getc(&mut self) -> FP16 {
+    pub fn getc(&self) -> FP16 {
         return self.c;
-        //        let f = FP16::new_copy(&self.c);
-        //        return f;
     }
 
     /* copy self=x */
@@ -1112,7 +1106,7 @@ impl FP48 {
     }
 
     /* convert this to byte array */
-    pub fn tobytes(&mut self, w: &mut [u8]) {
+    pub fn tobytes(&self, w: &mut [u8]) {
         let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
         let mb = big::MODBYTES as usize;
 
@@ -1322,7 +1316,7 @@ impl FP48 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!(
             "[{},{},{}]",
             self.a.tostring(),
diff --git a/src/fp8.rs b/src/fp8.rs
index 38515a8..ab4bedf 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -109,7 +109,7 @@ impl FP8 {
     }
 
     /* test is w real? That is in a+ib test b is zero */
-    pub fn isreal(&mut self) -> bool {
+    pub fn isreal(&self) -> bool {
         return self.b.iszilch();
     }
     /* extract real part a */
@@ -304,7 +304,7 @@ impl FP8 {
     }
 
     /* output to hex string */
-    pub fn tostring(&mut self) -> String {
+    pub fn tostring(&self) -> String {
         return format!("[{},{}]", self.a.tostring(), self.b.tostring());
     }
 


[incubator-milagro-crypto-rust] 11/44: Fix minor bug with compilation

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 032e9f99e9cfbee5c210d59c15f63a9c589b981d
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Dec 13 15:08:35 2019 +1100

    Fix minor bug with compilation
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/roms/rom_bn254CX_64.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/roms/rom_bn254CX_64.rs b/src/roms/rom_bn254CX_64.rs
index 75d4c28..097e205 100644
--- a/src/roms/rom_bn254CX_64.rs
+++ b/src/roms/rom_bn254CX_64.rs
@@ -230,7 +230,7 @@ pub const BASEBITS: usize = 56;
 pub const MODBITS: usize = 254;
 pub const MOD8: usize = 3;
 pub const MODTYPE: ModType = ModType::NotSpecial;
-pub const SH: usize = 64;
+pub const SH: usize = 26;
 
 pub const CURVETYPE: CurveType = CurveType::Weierstrass;
 pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bn;


[incubator-milagro-crypto-rust] 03/44: Merge pull request #2 from kirk-baird/formatting

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 176c3f5d305bd5127e50a461c78f9b3456b3676d
Merge: 3948f75 a665a5c
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Wed Jul 3 07:21:41 2019 +0100

    Merge pull request #2 from kirk-baird/formatting
    
    Formatting and gitignore

 .gitignore                    |   1 +
 src/aes.rs                    |  50 +++---
 src/big.rs                    |  14 +-
 src/bls.rs                    |  18 +-
 src/bls192.rs                 |  20 +--
 src/bls256.rs                 |  18 +-
 src/dbig.rs                   |   6 +-
 src/ecdh.rs                   |  11 +-
 src/ecp.rs                    |  31 ++--
 src/ecp2.rs                   |  35 ++--
 src/ecp4.rs                   |   4 +-
 src/ecp8.rs                   |   6 +-
 src/ff.rs                     |   4 +-
 src/fp.rs                     |  38 ++---
 src/fp12.rs                   | 381 ++++++++++++++++++++++++------------------
 src/fp16.rs                   |  22 +--
 src/fp2.rs                    |  26 +--
 src/fp24.rs                   | 360 ++++++++++++++++++++++-----------------
 src/fp4.rs                    |  32 ++--
 src/fp48.rs                   | 362 ++++++++++++++++++++++-----------------
 src/fp8.rs                    |  23 ++-
 src/lib.rs                    | 182 ++++++++++----------
 src/mpin.rs                   |   9 +-
 src/mpin192.rs                |   9 +-
 src/mpin256.rs                |   6 +-
 src/pair.rs                   | 101 ++++++-----
 src/pair192.rs                |  67 ++++----
 src/pair256.rs                |  65 ++++---
 src/roms/rom_anssi_32.rs      |   4 +-
 src/roms/rom_anssi_64.rs      |   4 +-
 src/roms/rom_bls24_32.rs      |   4 +-
 src/roms/rom_bls24_64.rs      |   4 +-
 src/roms/rom_bls381_32.rs     |   4 +-
 src/roms/rom_bls381_64.rs     |   4 +-
 src/roms/rom_bls383_32.rs     |   4 +-
 src/roms/rom_bls383_64.rs     |   4 +-
 src/roms/rom_bls461_32.rs     |   4 +-
 src/roms/rom_bls461_64.rs     |   4 +-
 src/roms/rom_bls48_32.rs      |   4 +-
 src/roms/rom_bls48_64.rs      |   4 +-
 src/roms/rom_bn254CX_32.rs    |   4 +-
 src/roms/rom_bn254CX_64.rs    |   5 +-
 src/roms/rom_bn254_32.rs      |   4 +-
 src/roms/rom_bn254_64.rs      |   6 +-
 src/roms/rom_brainpool_32.rs  |   4 +-
 src/roms/rom_brainpool_64.rs  |   4 +-
 src/roms/rom_c25519_32.rs     |   4 +-
 src/roms/rom_c25519_64.rs     |   4 +-
 src/roms/rom_c41417_32.rs     |   4 +-
 src/roms/rom_c41417_64.rs     |   4 +-
 src/roms/rom_ed25519_32.rs    |   4 +-
 src/roms/rom_ed25519_64.rs    |   4 +-
 src/roms/rom_fp256bn_32.rs    |   5 +-
 src/roms/rom_fp256bn_64.rs    |   4 +-
 src/roms/rom_fp512bn_32.rs    |   4 +-
 src/roms/rom_fp512bn_64.rs    |   4 +-
 src/roms/rom_goldilocks_32.rs |   4 +-
 src/roms/rom_goldilocks_64.rs |   4 +-
 src/roms/rom_hifive_32.rs     |   4 +-
 src/roms/rom_hifive_64.rs     |   4 +-
 src/roms/rom_nist256_32.rs    |   7 +-
 src/roms/rom_nist256_64.rs    |   4 +-
 src/roms/rom_nist384_32.rs    |   4 +-
 src/roms/rom_nist384_64.rs    |   5 +-
 src/roms/rom_nist521_32.rs    |   4 +-
 src/roms/rom_nist521_64.rs    |   4 +-
 src/roms/rom_nums256e_32.rs   |   5 +-
 src/roms/rom_nums256e_64.rs   |   5 +-
 src/roms/rom_nums256w_32.rs   |   4 +-
 src/roms/rom_nums256w_64.rs   |   4 +-
 src/roms/rom_nums384e_32.rs   |   5 +-
 src/roms/rom_nums384e_64.rs   |   5 +-
 src/roms/rom_nums384w_32.rs   |   5 +-
 src/roms/rom_nums384w_64.rs   |   5 +-
 src/roms/rom_nums512e_32.rs   |   4 +-
 src/roms/rom_nums512e_64.rs   |   4 +-
 src/roms/rom_nums512w_32.rs   |   4 +-
 src/roms/rom_nums512w_64.rs   |   4 +-
 src/roms/rom_rsa2048_32.rs    |   2 +-
 src/roms/rom_rsa2048_64.rs    |   2 +-
 src/roms/rom_rsa3072_32.rs    |   2 +-
 src/roms/rom_rsa3072_64.rs    |   2 +-
 src/roms/rom_rsa4096_32.rs    |   2 +-
 src/roms/rom_rsa4096_64.rs    |   2 +-
 src/roms/rom_secp256k1_32.rs  |   4 +-
 src/roms/rom_secp256k1_64.rs  |   4 +-
 src/types.rs                  |   1 -
 87 files changed, 1146 insertions(+), 990 deletions(-)


[incubator-milagro-crypto-rust] 25/44: Cleaup tests and compiler warnings

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit df62cee823941598acede260afb074bf19b4aed0
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Mar 25 18:40:57 2020 +1100

    Cleaup tests and compiler warnings
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 Cargo.toml                                        |    4 +-
 TestALL.rs                                        | 1459 --------------------
 TestBLS.rs                                        |  190 ---
 TestNHS.rs                                        |   77 --
 readme.md                                         |    2 +-
 src/bls.rs                                        |   40 +-
 src/bls192.rs                                     |   38 +
 src/bls256.rs                                     |   38 +
 src/ecdh.rs                                       |  156 +++
 src/ecp.rs                                        |    2 +-
 src/gcm.rs                                        |    2 -
 src/lib.rs                                        |   11 +-
 src/mpin.rs                                       |  226 +++-
 src/mpin192.rs                                    |  227 +++-
 src/mpin256.rs                                    |  227 +++-
 src/nhs.rs                                        |   50 +
 src/roms/{rom_bn254CX_32.rs => rom_bn254cx_32.rs} |    6 +-
 src/roms/{rom_bn254CX_64.rs => rom_bn254cx_64.rs} |    6 +-
 src/rsa.rs                                        |   71 +
 src/test_utils/mod.rs                             |   21 +
 tests/test_all.rs                                 | 1473 ---------------------
 tests/test_bls.rs                                 |  190 ---
 tests/test_nhs.rs                                 |   71 -
 23 files changed, 1107 insertions(+), 3480 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 259e89f..834aa83 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@ path = "src/lib.rs"
 [features]
 default = ["bn254"]
 all = [
-  "anssi","bls24","bls48","bls381","bls383","bls461","bn254","bn254CX",
+  "anssi","bls24","bls48","bls381","bls383","bls461","bn254","bn254cx",
   "brainpool","c25519","c41417","ed25519","fp256BN","fp512BN","goldilocks","hifive",
   "nist256","nist384","nist521","nums256e","nums256w","nums384e","nums384w","nums512e",
   "nums512w","rsa2048","rsa3072","rsa4096","secp256k1",
@@ -28,7 +28,7 @@ bls381 = []
 bls383 = []
 bls461 = []
 bn254 = []
-bn254CX = []
+bn254cx = []
 brainpool = []
 c25519 = []
 c41417 = []
diff --git a/TestALL.rs b/TestALL.rs
deleted file mode 100644
index 9c3e1d0..0000000
--- a/TestALL.rs
+++ /dev/null
@@ -1,1459 +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.
-*/
-
-extern crate amcl;
-
-use std::io;
-use std::str;
-
-use amcl::rand::RAND;
-use amcl::types::CurveType;
-
-pub fn printbinary(array: &[u8]) {
-    for i in 0..array.len() {
-        print!("{:02X}", array[i])
-    }
-    println!("")
-}
-
-fn ecdh_ed25519(mut rng: &mut RAND) {
-    //use amcl::ed25519;
-    use amcl::ed25519::ecdh;
-    use amcl::ed25519::ecp;
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-fn ecdh_nist256(mut rng: &mut RAND) {
-    //use amcl::nist256;
-    use amcl::nist256::ecdh;
-    use amcl::nist256::ecp;
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-fn ecdh_goldilocks(mut rng: &mut RAND) {
-    //use amcl::goldilocks;
-    use amcl::goldilocks::ecdh;
-    use amcl::goldilocks::ecp;
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-fn mpin_bn254(mut rng: &mut RAND) {
-    //use amcl::bn254;
-    use amcl::bn254::ecp;
-    use amcl::bn254::mpin;
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin::EFS;
-    const EGS: usize = mpin::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hcid);
-        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hsid);
-        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-fn mpin_bls383(mut rng: &mut RAND) {
-    //use amcl::bls383;
-    use amcl::bls383::ecp;
-    use amcl::bls383::mpin;
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin::EFS;
-    const EGS: usize = mpin::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hcid);
-        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hsid);
-        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-fn mpin_bls24(mut rng: &mut RAND) {
-    //use amcl::bls24;
-    use amcl::bls24::ecp;
-    use amcl::bls24::mpin192;
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin192::EFS;
-    const EGS: usize = mpin192::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 8 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut g2: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut f: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin192::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin192::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin192::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin192::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin192::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin192::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin192::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin192::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin192::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin192::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin192::hash_id(sha, &client_id, &mut hcid);
-        mpin192::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin192::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin192::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin192::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin192::hash_id(sha, &client_id, &mut hsid);
-        mpin192::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin192::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin192::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin192::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin192::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin192::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin192::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin192::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin192::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin192::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-fn mpin_bls48(mut rng: &mut RAND) {
-    //use amcl::bls48;
-    use amcl::bls48::ecp;
-    use amcl::bls48::mpin256;
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin256::EFS;
-    const EGS: usize = mpin256::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 16 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin256::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin256::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin256::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin256::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin256::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin256::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin256::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin256::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin256::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin256::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin256::hash_id(sha, &client_id, &mut hcid);
-        mpin256::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin256::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin256::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin256::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin256::hash_id(sha, &client_id, &mut hsid);
-        mpin256::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin256::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin256::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin256::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin256::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin256::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin256::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin256::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin256::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin256::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-fn rsa_2048(mut rng: &mut RAND) {
-    //use amcl::rsa2048;
-    use amcl::rsa2048::ff;
-    use amcl::rsa2048::rsa;
-
-    let sha = rsa::HASH_TYPE;
-    let message: &[u8] = b"Hello World\n";
-    const RFS: usize = rsa::RFS;
-
-    let mut pbc = rsa::new_public_key(ff::FFLEN);
-    let mut prv = rsa::new_private_key(ff::HFLEN);
-
-    let mut ml: [u8; RFS] = [0; RFS];
-    let mut ms: [u8; RFS] = [0; RFS];
-    let mut c: [u8; RFS] = [0; RFS];
-    let mut s: [u8; RFS] = [0; RFS];
-    let mut e: [u8; RFS] = [0; RFS];
-
-    println!("\nTesting RSA");
-    println!("Generating public/private key pair");
-    rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
-
-    println!("Encrypting test string\n");
-    rsa::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E  */
-
-    rsa::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */
-    print!("Ciphertext= 0x");
-    printbinary(&c);
-
-    println!("Decrypting test string");
-    rsa::decrypt(&prv, &c, &mut ml);
-    let mlen = rsa::oaep_decode(sha, None, &mut ml); /* OAEP decode message  */
-
-    let mess = str::from_utf8(&ml[0..mlen]).unwrap();
-    print!("{}", &mess);
-
-    println!("Signing message");
-    rsa::pkcs15(sha, message, &mut c);
-
-    rsa::decrypt(&prv, &c, &mut s); /* create signature in S */
-
-    print!("Signature= 0x");
-    printbinary(&s);
-
-    rsa::encrypt(&pbc, &s, &mut ms);
-
-    let mut cmp = true;
-    if c.len() != ms.len() {
-        cmp = false;
-    } else {
-        for j in 0..c.len() {
-            if c[j] != ms[j] {
-                cmp = false
-            }
-        }
-    }
-    if cmp {
-        println!("Signature is valid");
-    } else {
-        println!("Signature is INVALID");
-    }
-
-    rsa::private_key_kill(&mut prv);
-}
-
-//#[test]
-fn main() {
-    let mut raw: [u8; 100] = [0; 100];
-
-    let mut rng = RAND::new();
-    rng.clean();
-    for i in 0..100 {
-        raw[i] = i as u8
-    }
-
-    rng.seed(100, &raw);
-
-    ecdh_ed25519(&mut rng);
-    ecdh_nist256(&mut rng);
-    ecdh_goldilocks(&mut rng);
-    mpin_bn254(&mut rng);
-    mpin_bls383(&mut rng);
-    mpin_bls24(&mut rng);
-    mpin_bls48(&mut rng);
-    rsa_2048(&mut rng);
-}
diff --git a/TestBLS.rs b/TestBLS.rs
deleted file mode 100644
index 1a54ee4..0000000
--- a/TestBLS.rs
+++ /dev/null
@@ -1,190 +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.
-*/
-
-extern crate amcl;
-
-use amcl::rand::RAND;
-
-pub fn printbinary(array: &[u8]) {
-    for i in 0..array.len() {
-        print!("{:02X}", array[i])
-    }
-    println!("")
-}
-
-fn bls_bn254(mut rng: &mut RAND) {
-    use amcl::bn254::bls;
-
-    const BFS: usize = bls::BFS;
-    const BGS: usize = bls::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-fn bls_bls383(mut rng: &mut RAND) {
-    use amcl::bls383::bls;
-
-    const BFS: usize = bls::BFS;
-    const BGS: usize = bls::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-fn bls_bls24(mut rng: &mut RAND) {
-    use amcl::bls24::bls192;
-
-    const BFS: usize = bls192::BFS;
-    const BGS: usize = bls192::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 8 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls192::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls192::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls192::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-fn bls_bls48(mut rng: &mut RAND) {
-    use amcl::bls48::bls256;
-
-    const BFS: usize = bls256::BFS;
-    const BGS: usize = bls256::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 16 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls256::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls256::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls256::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-fn main() {
-    use amcl::arch;
-
-    let mut raw: [u8; 100] = [0; 100];
-
-    let mut rng = RAND::new();
-    rng.clean();
-    for i in 0..100 {
-        raw[i] = i as u8
-    }
-
-    rng.seed(100, &raw);
-
-    println!("{} bit build", arch::CHUNK);
-
-    println!("Testing BLS signature for curve BN254");
-    bls_bn254(&mut rng);
-    println!("\nTesting BLS signature for curve BLS383");
-    bls_bls383(&mut rng);
-    println!("\nTesting BLS signature for curve BLS24");
-    bls_bls24(&mut rng);
-    println!("\nTesting BLS signature for curve BLS48");
-    bls_bls48(&mut rng);
-}
diff --git a/TestNHS.rs b/TestNHS.rs
deleted file mode 100644
index 4e7ed02..0000000
--- a/TestNHS.rs
+++ /dev/null
@@ -1,77 +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.
-*/
-
-//  TestNHS.rs - Tests NewHope Simple API
-
-// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe)
-
-// rustc TestNHS.rs --extern amcl=libamcl.rlib
-
-extern crate amcl;
-
-//use std::str;
-//use std::io;
-
-use amcl::rand::RAND;
-//use amcl::aes;
-use amcl::nhs;
-
-//#[test]
-fn main()
-{
-	let mut raw:[u8;100]=[0;100];	
-
-	let mut srng=RAND::new();
-	srng.clean();
-	for i in 0..100 {raw[i]=(i+1) as u8}
-
-	srng.seed(100,&raw);	
-
-
-									let mut crng=RAND::new();
-									crng.clean();
-									for i in 0..100 {raw[i]=(i+2) as u8}
-
-									crng.seed(100,&raw);	
-
-
-	let mut ss:[u8;1792]=[0;1792];
-					let mut sb:[u8;1824]=[0;1824];
-					let mut uc:[u8;2176]=[0;2176];
-
-	let mut keya:[u8;32]=[0;32];
-									let mut keyb:[u8;32]=[0;32];
-
-	nhs::server_1(&mut srng,&mut sb,&mut ss);
-
-									nhs::client(&mut crng,&sb,&mut uc,&mut keyb);
-
-	nhs::server_2(&ss,&uc,&mut keya);
-
-	for i in 0..keya.len() {
-		print!("{:02X}", keya[i]);
-	}
-	println!("");	
-
-									for i in 0..keyb.len() {
-										print!("{:02X}", keyb[i]);
-									}
-									println!("");		
-
-}
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 036defc..17091d5 100644
--- a/readme.md
+++ b/readme.md
@@ -76,7 +76,7 @@ Full list of features:
   * secp256k1
 * Pairing-Friendly Elliptic Curves
   * bn254
-  * bn254CX
+  * bn254cx
   * bls383
   * bls381
   * fp256BN
diff --git a/src/bls.rs b/src/bls.rs
index 07b8353..98c9a8b 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -54,7 +54,7 @@ fn bls_hashit(m: &str) -> ECP {
 pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
     let q = Big::new_ints(&rom::CURVE_ORDER);
     let g = ECP2::generator();
-    let mut sc = Big::randomnum(&q, &mut rng);
+    let sc = Big::randomnum(&q, &mut rng);
     sc.tobytes(s);
     pair::g2mul(&g, &sc).tobytes(w);
     BLS_OK
@@ -91,3 +91,41 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     }
     BLS_FAIL
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+
+    #[test]
+    fn test_bls() {
+        let mut rng = create_rng();
+
+        let mut s: [u8; BGS] = [0; BGS];
+
+        const G1S: usize = BFS + 1; /* Group 1 Size */
+        const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+        let mut w: [u8; G2S] = [0; G2S];
+        let mut sig: [u8; G1S] = [0; G1S];
+
+        let m = String::from("This is a test message");
+
+        key_pair_generate(&mut rng, &mut s, &mut w);
+        print!("Private key : 0x");
+        printbinary(&s);
+        print!("Public  key : 0x");
+        printbinary(&w);
+
+        sign(&mut sig, &m, &s);
+        print!("Signature : 0x");
+        printbinary(&sig);
+
+        let res = verify(&sig, &m, &w);
+        if res == 0 {
+            println!("Signature is OK");
+        } else {
+            println!("Signature is *NOT* OK");
+        }
+    }
+}
diff --git a/src/bls192.rs b/src/bls192.rs
index 3654452..fb8e836 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -93,3 +93,41 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     }
     BLS_FAIL
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+
+    #[test]
+    fn test_bls() {
+        let mut rng = create_rng();
+
+        let mut s: [u8; BGS] = [0; BGS];
+
+        const G1S: usize = BFS + 1; /* Group 1 Size */
+        const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+        let mut w: [u8; G2S] = [0; G2S];
+        let mut sig: [u8; G1S] = [0; G1S];
+
+        let m = String::from("This is a test message");
+
+        key_pair_generate(&mut rng, &mut s, &mut w);
+        print!("Private key : 0x");
+        printbinary(&s);
+        print!("Public  key : 0x");
+        printbinary(&w);
+
+        sign(&mut sig, &m, &s);
+        print!("Signature : 0x");
+        printbinary(&sig);
+
+        let res = verify(&sig, &m, &w);
+        if res == 0 {
+            println!("Signature is OK");
+        } else {
+            println!("Signature is *NOT* OK");
+        }
+    }
+}
diff --git a/src/bls256.rs b/src/bls256.rs
index c3722f3..b36566c 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -91,3 +91,41 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     }
     BLS_FAIL
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+
+    #[test]
+    fn test_bls() {
+        let mut rng = create_rng();
+
+        let mut s: [u8; BGS] = [0; BGS];
+
+        const G1S: usize = BFS + 1; /* Group 1 Size */
+        const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+        let mut w: [u8; G2S] = [0; G2S];
+        let mut sig: [u8; G1S] = [0; G1S];
+
+        let m = String::from("This is a test message");
+
+        key_pair_generate(&mut rng, &mut s, &mut w);
+        print!("Private key : 0x");
+        printbinary(&s);
+        print!("Public  key : 0x");
+        printbinary(&w);
+
+        sign(&mut sig, &m, &s);
+        print!("Signature : 0x");
+        printbinary(&sig);
+
+        let res = verify(&sig, &m, &w);
+        if res == 0 {
+            println!("Signature is OK");
+        } else {
+            println!("Signature is *NOT* OK");
+        }
+    }
+}
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 12aa34e..7a84d6b 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -745,3 +745,159 @@ pub fn ecies_decrypt(
 
     m
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+    use crate::types::CurveType;
+
+    #[test]
+    fn test_ecdh() {
+
+        let mut rng = create_rng();
+
+        let pw = "M0ng00se";
+        let pp: &[u8] = b"M0ng00se";
+        const EAS: usize = ecp::AESKEY;
+
+        let sha = ecp::HASH_TYPE;
+        let mut salt: [u8; 8] = [0; 8];
+        let mut s1: [u8; EGS] = [0; EGS];
+        let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+        let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+        let mut z0: [u8; EFS] = [0; EFS];
+        let mut z1: [u8; EFS] = [0; EFS];
+        let mut key: [u8; EAS] = [0; EAS];
+        let mut cs: [u8; EGS] = [0; EGS];
+        let mut ds: [u8; EGS] = [0; EGS];
+        let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+        let mut p1: [u8; 3] = [0; 3];
+        let mut p2: [u8; 4] = [0; 4];
+        let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+        let mut t: [u8; 12] = [0; 12];
+
+        for i in 0..8 {
+            salt[i] = (i + 1) as u8
+        } // set Salt
+
+        println!("\nTesting ECDH/ECDSA/ECIES");
+        println!("Alice's Passphrase= {}", pw);
+
+        let mut s0: [u8; EFS] = [0; EGS];
+        pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+        print!("Alice's private key= 0x");
+        printbinary(&s0);
+
+        /* Generate Key pair S/W */
+        key_pair_generate(None, &mut s0, &mut w0);
+
+        print!("Alice's public key= 0x");
+        printbinary(&w0);
+
+        let mut res = public_key_validate(&w0);
+        if res != 0 {
+            println!("ECP Public Key is invalid!");
+            return;
+        }
+
+        /* Random private key for other party */
+        key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+        print!("Servers private key= 0x");
+        printbinary(&s1);
+
+        print!("Servers public key= 0x");
+        printbinary(&w1);
+
+        res = public_key_validate(&w1);
+        if res != 0 {
+            println!("ECP Public Key is invalid!");
+            return;
+        }
+        /* Calculate common key using DH - IEEE 1363 method */
+
+        ecpsvdp_dh(&s0, &w1, &mut z0);
+        ecpsvdp_dh(&s1, &w0, &mut z1);
+
+        let mut same = true;
+        for i in 0..EFS {
+            if z0[i] != z1[i] {
+                same = false
+            }
+        }
+
+        if !same {
+            println!("*** ECPSVDP-DH Failed");
+            return;
+        }
+
+        kdf2(sha, &z0, None, EAS, &mut key);
+
+        print!("Alice's DH Key=  0x");
+        printbinary(&key);
+        print!("Servers DH Key=  0x");
+        printbinary(&key);
+
+        if ecp::CURVETYPE != CurveType::Montgomery {
+            for i in 0..17 {
+                m[i] = i as u8
+            }
+
+            println!("Testing ECIES");
+
+            p1[0] = 0x0;
+            p1[1] = 0x1;
+            p1[2] = 0x2;
+            p2[0] = 0x0;
+            p2[1] = 0x1;
+            p2[2] = 0x2;
+            p2[3] = 0x3;
+
+            let cc = ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+            if let Some(mut c) = cc {
+                println!("Ciphertext= ");
+                print!("V= 0x");
+                printbinary(&v);
+                print!("C= 0x");
+                printbinary(&c);
+                print!("T= 0x");
+                printbinary(&t);
+
+                let mm = ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+                if let Some(rm) = mm {
+                    println!("Decryption succeeded");
+                    print!("Message is 0x");
+                    printbinary(&rm);
+                } else {
+                    println!("*** ECIES Decryption Failed");
+                    return;
+                }
+            } else {
+                println!("*** ECIES Encryption Failed");
+                return;
+            }
+
+            println!("Testing ECDSA");
+
+            if ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+                println!("***ECDSA Signature Failed");
+                return;
+            }
+            println!("Signature= ");
+            print!("C= 0x");
+            printbinary(&cs);
+            print!("D= 0x");
+            printbinary(&ds);
+
+            if ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+                println!("***ECDSA Verification Failed");
+                return;
+            } else {
+                println!("ECDSA Signature/Verification succeeded ")
+            }
+        }
+    }
+}
diff --git a/src/ecp.rs b/src/ecp.rs
index b779e2d..07e19be 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -77,7 +77,7 @@ impl ECP {
         E.y.bcopy(iy);
         E.z.one();
         E.x.norm();
-        let mut rhs = ECP::rhs(&E.x);
+        let rhs = ECP::rhs(&E.x);
         if CURVETYPE == CurveType::Montgomery {
             if rhs.jacobi() != 1 {
                 E.inf();
diff --git a/src/gcm.rs b/src/gcm.rs
index b2c293f..6642781 100644
--- a/src/gcm.rs
+++ b/src/gcm.rs
@@ -22,8 +22,6 @@ const GCM_ACCEPTING_HEADER: usize = 0;
 const GCM_ACCEPTING_CIPHER: usize = 1;
 const GCM_NOT_ACCEPTING_MORE: usize = 2;
 const GCM_FINISHED: usize = 3;
-const GCM_ENCRYPTING: usize = 0;
-const GCM_DECRYPTING: usize = 1;
 
 use crate::aes;
 use crate::aes::AES;
diff --git a/src/lib.rs b/src/lib.rs
index c68a165..9849b2b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -467,14 +467,14 @@ pub mod ed25519 {
     pub mod fp;
 }
 
-#[cfg(feature = "bn254CX")]
+#[cfg(feature = "bn254cx")]
 #[path = "./"]
-pub mod bn254CX {
+pub mod bn254cx {
     #[cfg(target_pointer_width = "32")]
-    #[path = "roms/rom_bn254CX_32.rs"]
+    #[path = "roms/rom_bn254cx_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
-    #[path = "roms/rom_bn254CX_64.rs"]
+    #[path = "roms/rom_bn254cx_64.rs"]
     pub mod rom;
 
     pub mod big;
@@ -559,3 +559,6 @@ pub mod rsa4096 {
     mod rom;
     pub mod rsa;
 }
+
+#[cfg(test)]
+pub mod test_utils;
diff --git a/src/mpin.rs b/src/mpin.rs
index 425d03e..795fc50 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -351,7 +351,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
-    let mut sc = Big::randomnum(&r, rng);
+    let sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -942,3 +942,227 @@ pub fn server_key(
 
     return 0;
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+    use std::io;
+
+    #[test]
+    fn test_mpin() {
+        let mut rng = create_rng();
+
+        pub const PERMITS: bool = true;
+        pub const PINERROR: bool = true;
+        pub const FULL: bool = true;
+
+        let mut s: [u8; EGS] = [0; EGS];
+        const RM: usize = EFS as usize;
+        let mut hcid: [u8; RM] = [0; RM];
+        let mut hsid: [u8; RM] = [0; RM];
+
+        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+        const G2S: usize = 4 * EFS; /* Group 2 Size */
+        const EAS: usize = ecp::AESKEY;
+
+        let mut sst: [u8; G2S] = [0; G2S];
+        let mut token: [u8; G1S] = [0; G1S];
+        let mut permit: [u8; G1S] = [0; G1S];
+        let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
+        let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
+        let mut xid: [u8; G1S] = [0; G1S];
+        let mut xcid: [u8; G1S] = [0; G1S];
+        let mut x: [u8; EGS] = [0; EGS];
+        let mut y: [u8; EGS] = [0; EGS];
+        let mut sec: [u8; G1S] = [0; G1S];
+        let mut r: [u8; EGS] = [0; EGS];
+        let mut z: [u8; G1S] = [0; G1S];
+        let mut hid: [u8; G1S] = [0; G1S];
+        let mut htid: [u8; G1S] = [0; G1S];
+        let mut rhid: [u8; G1S] = [0; G1S];
+        let mut w: [u8; EGS] = [0; EGS];
+        let mut t: [u8; G1S] = [0; G1S];
+        let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
+        let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
+        let mut h: [u8; RM] = [0; RM];
+        let mut ck: [u8; EAS] = [0; EAS];
+        let mut sk: [u8; EAS] = [0; EAS];
+
+        let sha = ecp::HASH_TYPE;
+
+        println!("\nTesting MPIN - PIN is 1234");
+        /* Trusted Authority set-up */
+
+        random_generate(&mut rng, &mut s);
+        print!("Master Secret s: 0x");
+        printbinary(&s);
+
+        /* Create Client Identity */
+        let name = "testUser@miracl.com";
+        let client_id = name.as_bytes();
+
+        print!("Client ID= ");
+        printbinary(&client_id);
+
+        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+        /* Client and Server are issued secrets by DTA */
+        get_server_secret(&s, &mut sst);
+        print!("Server Secret SS: 0x");
+        printbinary(&sst);
+
+        get_client_secret(&mut s, &hcid, &mut token);
+        print!("Client Secret CS: 0x");
+        printbinary(&token);
+
+        /* Client extracts PIN from secret to create Token */
+        let pin: i32 = 1234;
+        println!("Client extracts PIN= {}", pin);
+        let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
+        if rtn != 0 {
+            println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+        }
+
+        print!("Client Token TK: 0x");
+        printbinary(&token);
+
+        if FULL {
+            precompute(&token, &hcid, &mut g1, &mut g2);
+        }
+
+        let mut date = 0;
+        if PERMITS {
+            date = today();
+            /* Client gets "Time Token" permit from DTA */
+
+            get_client_permit(sha, date, &s, &hcid, &mut permit);
+            print!("Time Permit TP: 0x");
+            printbinary(&permit);
+
+            /* This encoding makes Time permit look random - Elligator squared */
+            encoding(&mut rng, &mut permit);
+            print!("Encoded Time Permit TP: 0x");
+            printbinary(&permit);
+            decoding(&mut permit);
+            print!("Decoded Time Permit TP: 0x");
+            printbinary(&permit);
+        }
+
+        print!("\nPIN= ");
+        let _ = io::Write::flush(&mut io::stdout());
+        let mut input_text = String::new();
+        let _ = io::stdin().read_line(&mut input_text);
+
+        let pin = input_text.trim().parse::<usize>().unwrap();
+
+        println!("MPIN Multi Pass");
+        /* Send U=x.ID to server, and recreate secret from token and pin */
+        rtn = client_1(
+            sha,
+            date,
+            &client_id,
+            Some(&mut rng),
+            &mut x,
+            pin,
+            &token,
+            &mut sec,
+            Some(&mut xid[..]),
+            Some(&mut xcid[..]),
+            Some(&permit[..]),
+        );
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+        }
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hcid);
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+        }
+
+        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+        server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+        if date != 0 {
+            rhid.clone_from_slice(&htid[..]);
+        } else {
+            rhid.clone_from_slice(&hid[..]);
+        }
+
+        /* Server generates Random number Y and sends it to Client */
+        random_generate(&mut rng, &mut y);
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hsid);
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+        }
+
+        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        rtn = client_2(&x, &y, &mut sec);
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+        }
+
+        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+        /* If PIN error not required, set E and F = null */
+
+        if !PINERROR {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                None,
+                None,
+            );
+        } else {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                Some(&mut e),
+                Some(&mut f),
+            );
+        }
+
+        if rtn == BAD_PIN {
+            println!("Server says - Bad Pin. I don't know you. Feck off.");
+            if PINERROR {
+                let err = kangaroo(&e, &f);
+                if err != 0 {
+                    println!("(Client PIN is out by {})", err)
+                }
+            }
+            return;
+        } else {
+            println!("Server says - PIN is good! You really are {}", name);
+        }
+
+        if FULL {
+            let mut pxcid = None;
+            if PERMITS {
+                pxcid = Some(&xcid[..])
+            };
+
+            hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+            print!("Client Key =  0x");
+            printbinary(&ck);
+
+            hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+            print!("Server Key =  0x");
+            printbinary(&sk);
+        }
+    }
+}
diff --git a/src/mpin192.rs b/src/mpin192.rs
index 63970d1..d2ed7b9 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -367,7 +367,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
-    let mut sc = Big::randomnum(&r, rng);
+    let sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -957,3 +957,228 @@ pub fn server_key(
 
     return 0;
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+    use std::io;
+
+    #[test]
+    fn test_mpin192() {
+        let mut rng = create_rng();
+
+        pub const PERMITS: bool = true;
+        pub const PINERROR: bool = true;
+        pub const FULL: bool = true;
+        //pub const SINGLE_PASS:bool=false;
+
+        let mut s: [u8; EGS] = [0; EGS];
+        const RM: usize = EFS as usize;
+        let mut hcid: [u8; RM] = [0; RM];
+        let mut hsid: [u8; RM] = [0; RM];
+
+        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+        const G2S: usize = 16 * EFS; /* Group 2 Size */
+        const EAS: usize = ecp::AESKEY;
+
+        let mut sst: [u8; G2S] = [0; G2S];
+        let mut token: [u8; G1S] = [0; G1S];
+        let mut permit: [u8; G1S] = [0; G1S];
+        let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut xid: [u8; G1S] = [0; G1S];
+        let mut xcid: [u8; G1S] = [0; G1S];
+        let mut x: [u8; EGS] = [0; EGS];
+        let mut y: [u8; EGS] = [0; EGS];
+        let mut sec: [u8; G1S] = [0; G1S];
+        let mut r: [u8; EGS] = [0; EGS];
+        let mut z: [u8; G1S] = [0; G1S];
+        let mut hid: [u8; G1S] = [0; G1S];
+        let mut htid: [u8; G1S] = [0; G1S];
+        let mut rhid: [u8; G1S] = [0; G1S];
+        let mut w: [u8; EGS] = [0; EGS];
+        let mut t: [u8; G1S] = [0; G1S];
+        let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut h: [u8; RM] = [0; RM];
+        let mut ck: [u8; EAS] = [0; EAS];
+        let mut sk: [u8; EAS] = [0; EAS];
+
+        let sha = ecp::HASH_TYPE;
+
+        println!("\nTesting MPIN - PIN is 1234");
+        /* Trusted Authority set-up */
+
+        random_generate(&mut rng, &mut s);
+        print!("Master Secret s: 0x");
+        printbinary(&s);
+
+        /* Create Client Identity */
+        let name = "testUser@miracl.com";
+        let client_id = name.as_bytes();
+
+        print!("Client ID= ");
+        printbinary(&client_id);
+
+        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+        /* Client and Server are issued secrets by DTA */
+        get_server_secret(&s, &mut sst);
+        print!("Server Secret SS: 0x");
+        printbinary(&sst);
+
+        get_client_secret(&mut s, &hcid, &mut token);
+        print!("Client Secret CS: 0x");
+        printbinary(&token);
+
+        /* Client extracts PIN from secret to create Token */
+        let pin: i32 = 1234;
+        println!("Client extracts PIN= {}", pin);
+        let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
+        if rtn != 0 {
+            println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+        }
+
+        print!("Client Token TK: 0x");
+        printbinary(&token);
+
+        if FULL {
+            precompute(&token, &hcid, &mut g1, &mut g2);
+        }
+
+        let mut date = 0;
+        if PERMITS {
+            date = today();
+            /* Client gets "Time Token" permit from DTA */
+
+            get_client_permit(sha, date, &s, &hcid, &mut permit);
+            print!("Time Permit TP: 0x");
+            printbinary(&permit);
+
+            /* This encoding makes Time permit look random - Elligator squared */
+            encoding(&mut rng, &mut permit);
+            print!("Encoded Time Permit TP: 0x");
+            printbinary(&permit);
+            decoding(&mut permit);
+            print!("Decoded Time Permit TP: 0x");
+            printbinary(&permit);
+        }
+
+        print!("\nPIN= ");
+        let _ = io::Write::flush(&mut io::stdout());
+        let mut input_text = String::new();
+        let _ = io::stdin().read_line(&mut input_text);
+
+        let pin = input_text.trim().parse::<usize>().unwrap();
+
+        println!("MPIN Multi Pass");
+        /* Send U=x.ID to server, and recreate secret from token and pin */
+        rtn = client_1(
+            sha,
+            date,
+            &client_id,
+            Some(&mut rng),
+            &mut x,
+            pin,
+            &token,
+            &mut sec,
+            Some(&mut xid[..]),
+            Some(&mut xcid[..]),
+            Some(&permit[..]),
+        );
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+        }
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hcid);
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+        }
+
+        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+        server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+        if date != 0 {
+            rhid.clone_from_slice(&htid[..]);
+        } else {
+            rhid.clone_from_slice(&hid[..]);
+        }
+
+        /* Server generates Random number Y and sends it to Client */
+        random_generate(&mut rng, &mut y);
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hsid);
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+        }
+
+        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        rtn = client_2(&x, &y, &mut sec);
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+        }
+
+        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+        /* If PIN error not required, set E and F = null */
+
+        if !PINERROR {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                None,
+                None,
+            );
+        } else {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                Some(&mut e),
+                Some(&mut f),
+            );
+        }
+
+        if rtn == BAD_PIN {
+            println!("Server says - Bad Pin. I don't know you. Feck off.");
+            if PINERROR {
+                let err = kangaroo(&e, &f);
+                if err != 0 {
+                    println!("(Client PIN is out by {})", err)
+                }
+            }
+            return;
+        } else {
+            println!("Server says - PIN is good! You really are {}", name);
+        }
+
+        if FULL {
+            let mut pxcid = None;
+            if PERMITS {
+                pxcid = Some(&xcid[..])
+            };
+
+            hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+            print!("Client Key =  0x");
+            printbinary(&ck);
+
+            hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+            print!("Server Key =  0x");
+            printbinary(&sk);
+        }
+    }
+}
diff --git a/src/mpin256.rs b/src/mpin256.rs
index 5f9cee9..65a06d9 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -400,7 +400,7 @@ pub fn recombine_g2(w1: &[u8], w2: &[u8], w: &mut [u8]) -> isize {
 /* create random secret S */
 pub fn random_generate(rng: &mut RAND, s: &mut [u8]) -> isize {
     let r = Big::new_ints(&rom::CURVE_ORDER);
-    let mut sc = Big::randomnum(&r, rng);
+    let sc = Big::randomnum(&r, rng);
     sc.tobytes(s);
     return 0;
 }
@@ -991,3 +991,228 @@ pub fn server_key(
 
     return 0;
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+    use std::io;
+
+    #[test]
+    fn test_mpin256() {
+        let mut rng = create_rng();
+
+        pub const PERMITS: bool = true;
+        pub const PINERROR: bool = true;
+        pub const FULL: bool = true;
+        //pub const SINGLE_PASS:bool=false;
+
+        let mut s: [u8; EGS] = [0; EGS];
+        const RM: usize = EFS as usize;
+        let mut hcid: [u8; RM] = [0; RM];
+        let mut hsid: [u8; RM] = [0; RM];
+
+        const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+        const G2S: usize = 16 * EFS; /* Group 2 Size */
+        const EAS: usize = ecp::AESKEY;
+
+        let mut sst: [u8; G2S] = [0; G2S];
+        let mut token: [u8; G1S] = [0; G1S];
+        let mut permit: [u8; G1S] = [0; G1S];
+        let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut xid: [u8; G1S] = [0; G1S];
+        let mut xcid: [u8; G1S] = [0; G1S];
+        let mut x: [u8; EGS] = [0; EGS];
+        let mut y: [u8; EGS] = [0; EGS];
+        let mut sec: [u8; G1S] = [0; G1S];
+        let mut r: [u8; EGS] = [0; EGS];
+        let mut z: [u8; G1S] = [0; G1S];
+        let mut hid: [u8; G1S] = [0; G1S];
+        let mut htid: [u8; G1S] = [0; G1S];
+        let mut rhid: [u8; G1S] = [0; G1S];
+        let mut w: [u8; EGS] = [0; EGS];
+        let mut t: [u8; G1S] = [0; G1S];
+        let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
+        let mut h: [u8; RM] = [0; RM];
+        let mut ck: [u8; EAS] = [0; EAS];
+        let mut sk: [u8; EAS] = [0; EAS];
+
+        let sha = ecp::HASH_TYPE;
+
+        println!("\nTesting MPIN - PIN is 1234");
+        /* Trusted Authority set-up */
+
+        random_generate(&mut rng, &mut s);
+        print!("Master Secret s: 0x");
+        printbinary(&s);
+
+        /* Create Client Identity */
+        let name = "testUser@miracl.com";
+        let client_id = name.as_bytes();
+
+        print!("Client ID= ");
+        printbinary(&client_id);
+
+        hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+        /* Client and Server are issued secrets by DTA */
+        get_server_secret(&s, &mut sst);
+        print!("Server Secret SS: 0x");
+        printbinary(&sst);
+
+        get_client_secret(&mut s, &hcid, &mut token);
+        print!("Client Secret CS: 0x");
+        printbinary(&token);
+
+        /* Client extracts PIN from secret to create Token */
+        let pin: i32 = 1234;
+        println!("Client extracts PIN= {}", pin);
+        let mut rtn = extract_pin(sha, &client_id, pin, &mut token);
+        if rtn != 0 {
+            println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+        }
+
+        print!("Client Token TK: 0x");
+        printbinary(&token);
+
+        if FULL {
+            precompute(&token, &hcid, &mut g1, &mut g2);
+        }
+
+        let mut date = 0;
+        if PERMITS {
+            date = today();
+            /* Client gets "Time Token" permit from DTA */
+
+            get_client_permit(sha, date, &s, &hcid, &mut permit);
+            print!("Time Permit TP: 0x");
+            printbinary(&permit);
+
+            /* This encoding makes Time permit look random - Elligator squared */
+            encoding(&mut rng, &mut permit);
+            print!("Encoded Time Permit TP: 0x");
+            printbinary(&permit);
+            decoding(&mut permit);
+            print!("Decoded Time Permit TP: 0x");
+            printbinary(&permit);
+        }
+
+        print!("\nPIN= ");
+        let _ = io::Write::flush(&mut io::stdout());
+        let mut input_text = String::new();
+        let _ = io::stdin().read_line(&mut input_text);
+
+        let pin = input_text.trim().parse::<usize>().unwrap();
+
+        println!("MPIN Multi Pass");
+        /* Send U=x.ID to server, and recreate secret from token and pin */
+        rtn = client_1(
+            sha,
+            date,
+            &client_id,
+            Some(&mut rng),
+            &mut x,
+            pin,
+            &token,
+            &mut sec,
+            Some(&mut xid[..]),
+            Some(&mut xcid[..]),
+            Some(&permit[..]),
+        );
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+        }
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hcid);
+            get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+        }
+
+        /* Server calculates H(ID) and H(T|H(ID)) (if time PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+        server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+        if date != 0 {
+            rhid.clone_from_slice(&htid[..]);
+        } else {
+            rhid.clone_from_slice(&hid[..]);
+        }
+
+        /* Server generates Random number Y and sends it to Client */
+        random_generate(&mut rng, &mut y);
+
+        if FULL {
+            hash_id(sha, &client_id, &mut hsid);
+            get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+        }
+
+        /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+        rtn = client_2(&x, &y, &mut sec);
+        if rtn != 0 {
+            println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+        }
+
+        /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+        /* If PIN error not required, set E and F = null */
+
+        if !PINERROR {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                None,
+                None,
+            );
+        } else {
+            rtn = server_2(
+                date,
+                &hid,
+                Some(&htid[..]),
+                &y,
+                &sst,
+                Some(&xid[..]),
+                Some(&xcid[..]),
+                &sec,
+                Some(&mut e),
+                Some(&mut f),
+            );
+        }
+
+        if rtn == BAD_PIN {
+            println!("Server says - Bad Pin. I don't know you. Feck off.");
+            if PINERROR {
+                let err = kangaroo(&e, &f);
+                if err != 0 {
+                    println!("(Client PIN is out by {})", err)
+                }
+            }
+            return;
+        } else {
+            println!("Server says - PIN is good! You really are {}", name);
+        }
+
+        if FULL {
+            let mut pxcid = None;
+            if PERMITS {
+                pxcid = Some(&xcid[..])
+            };
+
+            hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+            print!("Client Key =  0x");
+            printbinary(&ck);
+
+            hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+            server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+            print!("Server Key =  0x");
+            printbinary(&sk);
+        }
+    }
+}
diff --git a/src/nhs.rs b/src/nhs.rs
index dda49b0..cf0f9c2 100644
--- a/src/nhs.rs
+++ b/src/nhs.rs
@@ -703,3 +703,53 @@ fn main() {
 
 }
 */
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_nhs() {
+        let mut raw: [u8; 100] = [0; 100];
+
+        let mut srng = RAND::new();
+        srng.clean();
+        for i in 0..100 {
+            raw[i] = (i + 1) as u8
+        }
+
+        srng.seed(100, &raw);
+
+        let mut crng = RAND::new();
+        crng.clean();
+        for i in 0..100 {
+            raw[i] = (i + 2) as u8
+        }
+
+        crng.seed(100, &raw);
+
+        let mut ss: [u8; 1792] = [0; 1792];
+        let mut sb: [u8; 1824] = [0; 1824];
+        let mut uc: [u8; 2176] = [0; 2176];
+
+        let mut keya: [u8; 32] = [0; 32];
+        let mut keyb: [u8; 32] = [0; 32];
+
+        server_1(&mut srng, &mut sb, &mut ss);
+
+        client(&mut crng, &sb, &mut uc, &mut keyb);
+
+        server_2(&ss, &uc, &mut keya);
+
+        for i in 0..keya.len() {
+            print!("{:02X}", keya[i]);
+        }
+        println!("");
+
+        for i in 0..keyb.len() {
+            print!("{:02X}", keyb[i]);
+        }
+        println!("");
+    }
+
+}
diff --git a/src/roms/rom_bn254CX_32.rs b/src/roms/rom_bn254cx_32.rs
similarity index 99%
rename from src/roms/rom_bn254CX_32.rs
rename to src/roms/rom_bn254cx_32.rs
index a6e7ef8..8884db3 100644
--- a/src/roms/rom_bn254CX_32.rs
+++ b/src/roms/rom_bn254cx_32.rs
@@ -18,11 +18,11 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bn254CX::big::NLEN;
+use bn254cx::big::NLEN;
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
-// bn254CX Modulus
+// bn254cx Modulus
 pub const MODULUS: [Chunk; NLEN] = [
     0xC1B55B3, 0x6623EF5, 0x93EE1BE, 0xD6EE180, 0x6D3243F, 0x647A636, 0xDB0BDDF, 0x8702A0,
     0x4000000, 0x2,
@@ -41,7 +41,7 @@ pub const FRB: [Chunk; NLEN] = [
     0xA6F7D0, 0x1,
 ];
 
-// bn254CX Curve
+// bn254cx Curve
 pub const CURVE_COF_I: isize = 1;
 pub const CURVE_A: isize = 0;
 pub const CURVE_B_I: isize = 2;
diff --git a/src/roms/rom_bn254CX_64.rs b/src/roms/rom_bn254cx_64.rs
similarity index 99%
rename from src/roms/rom_bn254CX_64.rs
rename to src/roms/rom_bn254cx_64.rs
index 097e205..8aa4f06 100644
--- a/src/roms/rom_bn254CX_64.rs
+++ b/src/roms/rom_bn254cx_64.rs
@@ -18,11 +18,11 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bn254CX::big::NLEN;
+use bn254cx::big::NLEN;
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
-// bn254CX Modulus
+// bn254cx Modulus
 pub const MODULUS: [Chunk; NLEN] = [
     0x6623EF5C1B55B3,
     0xD6EE18093EE1BE,
@@ -53,7 +53,7 @@ pub const FRB: [Chunk; NLEN] = [
     0x10A6F7D0,
 ];
 
-// bn254CX Curve
+// bn254cx Curve
 pub const CURVE_COF_I: isize = 1;
 pub const CURVE_A: isize = 0;
 pub const CURVE_B_I: isize = 2;
diff --git a/src/rsa.rs b/src/rsa.rs
index 1a59f7a..a3022e0 100644
--- a/src/rsa.rs
+++ b/src/rsa.rs
@@ -467,3 +467,74 @@ pub fn decrypt(prv: &RsaPrivateKey, g: &[u8], f: &mut [u8]) {
 
     r.tobytes(f);
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+    use std::str;
+
+    #[test]
+    fn test_rsa() {
+        let mut rng = create_rng();
+
+        let sha = super::HASH_TYPE;
+        let message: &[u8] = b"Hello World\n";
+        const RFS: usize = super::RFS;
+
+        let mut pbc = super::new_public_key(ff::FFLEN);
+        let mut prv = super::new_private_key(ff::HFLEN);
+
+        let mut ml: [u8; RFS] = [0; RFS];
+        let mut ms: [u8; RFS] = [0; RFS];
+        let mut c: [u8; RFS] = [0; RFS];
+        let mut s: [u8; RFS] = [0; RFS];
+        let mut e: [u8; RFS] = [0; RFS];
+
+        println!("\nTesting RSA");
+        println!("Generating public/private key pair");
+        super::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
+
+        println!("Encrypting test string\n");
+        super::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E  */
+
+        super::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */
+        print!("Ciphertext= 0x");
+        printbinary(&c);
+
+        println!("Decrypting test string");
+        super::decrypt(&prv, &c, &mut ml);
+        let mlen = super::oaep_decode(sha, None, &mut ml); /* OAEP decode message  */
+
+        let mess = str::from_utf8(&ml[0..mlen]).unwrap();
+        print!("{}", &mess);
+
+        println!("Signing message");
+        super::pkcs15(sha, message, &mut c);
+
+        super::decrypt(&prv, &c, &mut s); /* create signature in S */
+
+        print!("Signature= 0x");
+        printbinary(&s);
+
+        super::encrypt(&pbc, &s, &mut ms);
+
+        let mut cmp = true;
+        if c.len() != ms.len() {
+            cmp = false;
+        } else {
+            for j in 0..c.len() {
+                if c[j] != ms[j] {
+                    cmp = false
+                }
+            }
+        }
+        if cmp {
+            println!("Signature is valid");
+        } else {
+            println!("Signature is INVALID");
+        }
+
+        super::private_key_kill(&mut prv);
+    }
+}
diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs
new file mode 100644
index 0000000..4c85c50
--- /dev/null
+++ b/src/test_utils/mod.rs
@@ -0,0 +1,21 @@
+use crate::rand::RAND;
+
+pub fn printbinary(array: &[u8]) {
+    for i in 0..array.len() {
+        print!("{:02X}", array[i])
+    }
+    println!("")
+}
+
+pub fn create_rng() -> RAND {
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut rng = RAND::new();
+    rng.clean();
+    for i in 0..100 {
+        raw[i] = i as u8
+    }
+
+    rng.seed(100, &raw);
+    rng
+}
diff --git a/tests/test_all.rs b/tests/test_all.rs
deleted file mode 100644
index c543dac..0000000
--- a/tests/test_all.rs
+++ /dev/null
@@ -1,1473 +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.
-*/
-
-extern crate amcl;
-
-use std::io;
-use std::str;
-
-use amcl::rand::RAND;
-use amcl::types::CurveType;
-
-pub fn printbinary(array: &[u8]) {
-    for i in 0..array.len() {
-        print!("{:02X}", array[i])
-    }
-    println!("")
-}
-
-fn create_rng() -> RAND {
-    let mut raw: [u8; 100] = [0; 100];
-
-    let mut rng = RAND::new();
-    rng.clean();
-    for i in 0..100 {
-        raw[i] = i as u8
-    }
-
-    rng.seed(100, &raw);
-    rng
-}
-
-#[test]
-fn ecdh_ed25519() {
-    //use amcl::ed25519;
-    use amcl::ed25519::ecdh;
-    use amcl::ed25519::ecp;
-
-    let mut rng = create_rng();
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-#[test]
-fn ecdh_nist256() {
-    use amcl::nist256::ecdh;
-    use amcl::nist256::ecp;
-
-    let mut rng = create_rng();
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-#[test]
-fn ecdh_goldilocks() {
-    use amcl::goldilocks::ecdh;
-    use amcl::goldilocks::ecp;
-
-    let mut rng = create_rng();
-
-    let pw = "M0ng00se";
-    let pp: &[u8] = b"M0ng00se";
-    const EFS: usize = ecdh::EFS;
-    const EGS: usize = ecdh::EGS;
-    const EAS: usize = ecp::AESKEY;
-
-    let sha = ecp::HASH_TYPE;
-    let mut salt: [u8; 8] = [0; 8];
-    let mut s1: [u8; EGS] = [0; EGS];
-    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut z0: [u8; EFS] = [0; EFS];
-    let mut z1: [u8; EFS] = [0; EFS];
-    let mut key: [u8; EAS] = [0; EAS];
-    let mut cs: [u8; EGS] = [0; EGS];
-    let mut ds: [u8; EGS] = [0; EGS];
-    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
-    let mut p1: [u8; 3] = [0; 3];
-    let mut p2: [u8; 4] = [0; 4];
-    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
-    let mut t: [u8; 12] = [0; 12];
-
-    for i in 0..8 {
-        salt[i] = (i + 1) as u8
-    } // set Salt
-
-    println!("\nTesting ECDH/ECDSA/ECIES");
-    println!("Alice's Passphrase= {}", pw);
-
-    let mut s0: [u8; EFS] = [0; EGS];
-    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
-
-    print!("Alice's private key= 0x");
-    printbinary(&s0);
-
-    /* Generate Key pair S/W */
-    ecdh::key_pair_generate(None, &mut s0, &mut w0);
-
-    print!("Alice's public key= 0x");
-    printbinary(&w0);
-
-    let mut res = ecdh::public_key_validate(&w0);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-
-    /* Random private key for other party */
-    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
-
-    print!("Servers private key= 0x");
-    printbinary(&s1);
-
-    print!("Servers public key= 0x");
-    printbinary(&w1);
-
-    res = ecdh::public_key_validate(&w1);
-    if res != 0 {
-        println!("ECP Public Key is invalid!");
-        return;
-    }
-    /* Calculate common key using DH - IEEE 1363 method */
-
-    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
-    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
-
-    let mut same = true;
-    for i in 0..EFS {
-        if z0[i] != z1[i] {
-            same = false
-        }
-    }
-
-    if !same {
-        println!("*** ECPSVDP-DH Failed");
-        return;
-    }
-
-    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
-
-    print!("Alice's DH Key=  0x");
-    printbinary(&key);
-    print!("Servers DH Key=  0x");
-    printbinary(&key);
-
-    if ecp::CURVETYPE != CurveType::Montgomery {
-        for i in 0..17 {
-            m[i] = i as u8
-        }
-
-        println!("Testing ECIES");
-
-        p1[0] = 0x0;
-        p1[1] = 0x1;
-        p1[2] = 0x2;
-        p2[0] = 0x0;
-        p2[1] = 0x1;
-        p2[2] = 0x2;
-        p2[3] = 0x3;
-
-        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
-
-        if let Some(mut c) = cc {
-            println!("Ciphertext= ");
-            print!("V= 0x");
-            printbinary(&v);
-            print!("C= 0x");
-            printbinary(&c);
-            print!("T= 0x");
-            printbinary(&t);
-
-            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
-            if let Some(rm) = mm {
-                println!("Decryption succeeded");
-                print!("Message is 0x");
-                printbinary(&rm);
-            } else {
-                println!("*** ECIES Decryption Failed");
-                return;
-            }
-        } else {
-            println!("*** ECIES Encryption Failed");
-            return;
-        }
-
-        println!("Testing ECDSA");
-
-        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
-            println!("***ECDSA Signature Failed");
-            return;
-        }
-        println!("Signature= ");
-        print!("C= 0x");
-        printbinary(&cs);
-        print!("D= 0x");
-        printbinary(&ds);
-
-        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
-            println!("***ECDSA Verification Failed");
-            return;
-        } else {
-            println!("ECDSA Signature/Verification succeeded ")
-        }
-    }
-}
-
-#[test]
-fn mpin_bn254() {
-    use amcl::bn254::ecp;
-    use amcl::bn254::mpin;
-
-    let mut rng = create_rng();
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin::EFS;
-    const EGS: usize = mpin::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hcid);
-        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hsid);
-        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-#[test]
-fn mpin_bls383() {
-    //use amcl::bls383;
-    use amcl::bls383::ecp;
-    use amcl::bls383::mpin;
-
-    let mut rng = create_rng();
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin::EFS;
-    const EGS: usize = mpin::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hcid);
-        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin::hash_id(sha, &client_id, &mut hsid);
-        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-#[test]
-fn mpin_bls24() {
-    //use amcl::bls24;
-    use amcl::bls24::ecp;
-    use amcl::bls24::mpin192;
-
-    let mut rng = create_rng();
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin192::EFS;
-    const EGS: usize = mpin192::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 8 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut g2: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut f: [u8; 24 * EFS] = [0; 24 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin192::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin192::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin192::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin192::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin192::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin192::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin192::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin192::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin192::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin192::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin192::hash_id(sha, &client_id, &mut hcid);
-        mpin192::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin192::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin192::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin192::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin192::hash_id(sha, &client_id, &mut hsid);
-        mpin192::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin192::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin192::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin192::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin192::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin192::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin192::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin192::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin192::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin192::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-#[test]
-fn mpin_bls48() {
-    //use amcl::bls48;
-    use amcl::bls48::ecp;
-    use amcl::bls48::mpin256;
-
-    let mut rng = create_rng();
-
-    pub const PERMITS: bool = true;
-    pub const PINERROR: bool = true;
-    pub const FULL: bool = true;
-    //pub const SINGLE_PASS:bool=false;
-
-    const EFS: usize = mpin256::EFS;
-    const EGS: usize = mpin256::EGS;
-
-    let mut s: [u8; EGS] = [0; EGS];
-    const RM: usize = EFS as usize;
-    let mut hcid: [u8; RM] = [0; RM];
-    let mut hsid: [u8; RM] = [0; RM];
-
-    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
-    const G2S: usize = 16 * EFS; /* Group 2 Size */
-    const EAS: usize = ecp::AESKEY;
-
-    let mut sst: [u8; G2S] = [0; G2S];
-    let mut token: [u8; G1S] = [0; G1S];
-    let mut permit: [u8; G1S] = [0; G1S];
-    let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut xid: [u8; G1S] = [0; G1S];
-    let mut xcid: [u8; G1S] = [0; G1S];
-    let mut x: [u8; EGS] = [0; EGS];
-    let mut y: [u8; EGS] = [0; EGS];
-    let mut sec: [u8; G1S] = [0; G1S];
-    let mut r: [u8; EGS] = [0; EGS];
-    let mut z: [u8; G1S] = [0; G1S];
-    let mut hid: [u8; G1S] = [0; G1S];
-    let mut htid: [u8; G1S] = [0; G1S];
-    let mut rhid: [u8; G1S] = [0; G1S];
-    let mut w: [u8; EGS] = [0; EGS];
-    let mut t: [u8; G1S] = [0; G1S];
-    let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
-    let mut h: [u8; RM] = [0; RM];
-    let mut ck: [u8; EAS] = [0; EAS];
-    let mut sk: [u8; EAS] = [0; EAS];
-
-    let sha = ecp::HASH_TYPE;
-
-    println!("\nTesting MPIN - PIN is 1234");
-    /* Trusted Authority set-up */
-
-    mpin256::random_generate(&mut rng, &mut s);
-    print!("Master Secret s: 0x");
-    printbinary(&s);
-
-    /* Create Client Identity */
-    let name = "testUser@miracl.com";
-    let client_id = name.as_bytes();
-
-    print!("Client ID= ");
-    printbinary(&client_id);
-
-    mpin256::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
-
-    /* Client and Server are issued secrets by DTA */
-    mpin256::get_server_secret(&s, &mut sst);
-    print!("Server Secret SS: 0x");
-    printbinary(&sst);
-
-    mpin256::get_client_secret(&mut s, &hcid, &mut token);
-    print!("Client Secret CS: 0x");
-    printbinary(&token);
-
-    /* Client extracts PIN from secret to create Token */
-    let pin: i32 = 1234;
-    println!("Client extracts PIN= {}", pin);
-    let mut rtn = mpin256::extract_pin(sha, &client_id, pin, &mut token);
-    if rtn != 0 {
-        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
-    }
-
-    print!("Client Token TK: 0x");
-    printbinary(&token);
-
-    if FULL {
-        mpin256::precompute(&token, &hcid, &mut g1, &mut g2);
-    }
-
-    let mut date = 0;
-    if PERMITS {
-        date = mpin256::today();
-        /* Client gets "Time Token" permit from DTA */
-
-        mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit);
-        print!("Time Permit TP: 0x");
-        printbinary(&permit);
-
-        /* This encoding makes Time permit look random - Elligator squared */
-        mpin256::encoding(&mut rng, &mut permit);
-        print!("Encoded Time Permit TP: 0x");
-        printbinary(&permit);
-        mpin256::decoding(&mut permit);
-        print!("Decoded Time Permit TP: 0x");
-        printbinary(&permit);
-    }
-
-    print!("\nPIN= ");
-    let _ = io::Write::flush(&mut io::stdout());
-    let mut input_text = String::new();
-    let _ = io::stdin().read_line(&mut input_text);
-
-    let pin = input_text.trim().parse::<usize>().unwrap();
-
-    println!("MPIN Multi Pass");
-    /* Send U=x.ID to server, and recreate secret from token and pin */
-    rtn = mpin256::client_1(
-        sha,
-        date,
-        &client_id,
-        Some(&mut rng),
-        &mut x,
-        pin,
-        &token,
-        &mut sec,
-        Some(&mut xid[..]),
-        Some(&mut xcid[..]),
-        Some(&permit[..]),
-    );
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
-    }
-
-    if FULL {
-        mpin256::hash_id(sha, &client_id, &mut hcid);
-        mpin256::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
-    }
-
-    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin256::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
-
-    mpin256::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
-
-    if date != 0 {
-        rhid.clone_from_slice(&htid[..]);
-    } else {
-        rhid.clone_from_slice(&hid[..]);
-    }
-
-    /* Server generates Random number Y and sends it to Client */
-    mpin256::random_generate(&mut rng, &mut y);
-
-    if FULL {
-        mpin256::hash_id(sha, &client_id, &mut hsid);
-        mpin256::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
-    }
-
-    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
-    rtn = mpin256::client_2(&x, &y, &mut sec);
-    if rtn != 0 {
-        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
-    }
-
-    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
-    /* If PIN error not required, set E and F = null */
-
-    if !PINERROR {
-        rtn = mpin256::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            None,
-            None,
-        );
-    } else {
-        rtn = mpin256::server_2(
-            date,
-            &hid,
-            Some(&htid[..]),
-            &y,
-            &sst,
-            Some(&xid[..]),
-            Some(&xcid[..]),
-            &sec,
-            Some(&mut e),
-            Some(&mut f),
-        );
-    }
-
-    if rtn == mpin256::BAD_PIN {
-        println!("Server says - Bad Pin. I don't know you. Feck off.");
-        if PINERROR {
-            let err = mpin256::kangaroo(&e, &f);
-            if err != 0 {
-                println!("(Client PIN is out by {})", err)
-            }
-        }
-        return;
-    } else {
-        println!("Server says - PIN is good! You really are {}", name);
-    }
-
-    if FULL {
-        let mut pxcid = None;
-        if PERMITS {
-            pxcid = Some(&xcid[..])
-        };
-
-        mpin256::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin256::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
-        print!("Client Key =  0x");
-        printbinary(&ck);
-
-        mpin256::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
-        mpin256::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
-        print!("Server Key =  0x");
-        printbinary(&sk);
-    }
-}
-
-#[test]
-fn rsa_2048() {
-    //use amcl::rsa2048;
-    use amcl::rsa2048::ff;
-    use amcl::rsa2048::rsa;
-
-    let mut rng = create_rng();
-
-    let sha = rsa::HASH_TYPE;
-    let message: &[u8] = b"Hello World\n";
-    const RFS: usize = rsa::RFS;
-
-    let mut pbc = rsa::new_public_key(ff::FFLEN);
-    let mut prv = rsa::new_private_key(ff::HFLEN);
-
-    let mut ml: [u8; RFS] = [0; RFS];
-    let mut ms: [u8; RFS] = [0; RFS];
-    let mut c: [u8; RFS] = [0; RFS];
-    let mut s: [u8; RFS] = [0; RFS];
-    let mut e: [u8; RFS] = [0; RFS];
-
-    println!("\nTesting RSA");
-    println!("Generating public/private key pair");
-    rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
-
-    println!("Encrypting test string\n");
-    rsa::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E  */
-
-    rsa::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */
-    print!("Ciphertext= 0x");
-    printbinary(&c);
-
-    println!("Decrypting test string");
-    rsa::decrypt(&prv, &c, &mut ml);
-    let mlen = rsa::oaep_decode(sha, None, &mut ml); /* OAEP decode message  */
-
-    let mess = str::from_utf8(&ml[0..mlen]).unwrap();
-    print!("{}", &mess);
-
-    println!("Signing message");
-    rsa::pkcs15(sha, message, &mut c);
-
-    rsa::decrypt(&prv, &c, &mut s); /* create signature in S */
-
-    print!("Signature= 0x");
-    printbinary(&s);
-
-    rsa::encrypt(&pbc, &s, &mut ms);
-
-    let mut cmp = true;
-    if c.len() != ms.len() {
-        cmp = false;
-    } else {
-        for j in 0..c.len() {
-            if c[j] != ms[j] {
-                cmp = false
-            }
-        }
-    }
-    if cmp {
-        println!("Signature is valid");
-    } else {
-        println!("Signature is INVALID");
-    }
-
-    rsa::private_key_kill(&mut prv);
-}
diff --git a/tests/test_bls.rs b/tests/test_bls.rs
deleted file mode 100644
index 20cf73b..0000000
--- a/tests/test_bls.rs
+++ /dev/null
@@ -1,190 +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.
-*/
-
-extern crate amcl;
-
-use amcl::rand::RAND;
-
-pub fn printbinary(array: &[u8]) {
-    for i in 0..array.len() {
-        print!("{:02X}", array[i])
-    }
-    println!("")
-}
-
-fn create_rng() -> RAND {
-    let mut raw: [u8; 100] = [0; 100];
-
-    let mut rng = RAND::new();
-    rng.clean();
-    for i in 0..100 {
-        raw[i] = i as u8
-    }
-
-    rng.seed(100, &raw);
-    rng
-}
-
-#[test]
-fn bls_bn254() {
-    use amcl::bn254::bls;
-
-    let mut rng = create_rng();
-
-    const BFS: usize = bls::BFS;
-    const BGS: usize = bls::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-#[test]
-fn bls_bls383() {
-    use amcl::bls383::bls;
-
-    let mut rng = create_rng();
-
-    const BFS: usize = bls::BFS;
-    const BGS: usize = bls::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 4 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-#[test]
-fn bls_bls24() {
-    use amcl::bls24::bls192;
-
-    let mut rng = create_rng();
-
-    const BFS: usize = bls192::BFS;
-    const BGS: usize = bls192::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 8 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls192::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls192::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls192::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
-
-#[test]
-fn bls_bls48() {
-    use amcl::bls48::bls256;
-
-    let mut rng = create_rng();
-
-    const BFS: usize = bls256::BFS;
-    const BGS: usize = bls256::BGS;
-
-    let mut s: [u8; BGS] = [0; BGS];
-
-    const G1S: usize = BFS + 1; /* Group 1 Size */
-    const G2S: usize = 16 * BFS; /* Group 2 Size */
-
-    let mut w: [u8; G2S] = [0; G2S];
-    let mut sig: [u8; G1S] = [0; G1S];
-
-    let m = String::from("This is a test message");
-
-    bls256::key_pair_generate(&mut rng, &mut s, &mut w);
-    print!("Private key : 0x");
-    printbinary(&s);
-    print!("Public  key : 0x");
-    printbinary(&w);
-
-    bls256::sign(&mut sig, &m, &s);
-    print!("Signature : 0x");
-    printbinary(&sig);
-
-    let res = bls256::verify(&sig, &m, &w);
-    if res == 0 {
-        println!("Signature is OK");
-    } else {
-        println!("Signature is *NOT* OK");
-    }
-}
diff --git a/tests/test_nhs.rs b/tests/test_nhs.rs
deleted file mode 100644
index f272291..0000000
--- a/tests/test_nhs.rs
+++ /dev/null
@@ -1,71 +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.
-*/
-
-// Tests NewHope Simple API
-
-// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe)
-
-extern crate amcl;
-
-use amcl::nhs;
-use amcl::rand::RAND;
-
-#[test]
-fn test_nhs() {
-    let mut raw: [u8; 100] = [0; 100];
-
-    let mut srng = RAND::new();
-    srng.clean();
-    for i in 0..100 {
-        raw[i] = (i + 1) as u8
-    }
-
-    srng.seed(100, &raw);
-
-    let mut crng = RAND::new();
-    crng.clean();
-    for i in 0..100 {
-        raw[i] = (i + 2) as u8
-    }
-
-    crng.seed(100, &raw);
-
-    let mut ss: [u8; 1792] = [0; 1792];
-    let mut sb: [u8; 1824] = [0; 1824];
-    let mut uc: [u8; 2176] = [0; 2176];
-
-    let mut keya: [u8; 32] = [0; 32];
-    let mut keyb: [u8; 32] = [0; 32];
-
-    nhs::server_1(&mut srng, &mut sb, &mut ss);
-
-    nhs::client(&mut crng, &sb, &mut uc, &mut keyb);
-
-    nhs::server_2(&ss, &uc, &mut keya);
-
-    for i in 0..keya.len() {
-        print!("{:02X}", keya[i]);
-    }
-    println!("");
-
-    for i in 0..keyb.len() {
-        print!("{:02X}", keyb[i]);
-    }
-    println!("");
-}


[incubator-milagro-crypto-rust] 04/44: modify .gitignore

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit d36115ca07488e5f262418052f424ee7a9463541
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Aug 7 16:28:50 2019 +1000

    modify .gitignore
---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2c96eb1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+target/
+Cargo.lock


[incubator-milagro-crypto-rust] 12/44: Fix tests and benchmarks

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 570e3d3c45de6cb38c31f6d528bde96ac6747ce8
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Dec 13 15:58:15 2019 +1100

    Fix tests and benchmarks
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 BenchtestALL    | Bin 0 -> 5723448 bytes
 BenchtestALL.rs |  73 +++++++++++++++++++++++++++-----------------------------
 TestALL         | Bin 0 -> 6209648 bytes
 TestALL.rs      |   6 ++---
 TestBLS         | Bin 0 -> 4990944 bytes
 readme.md       |   2 +-
 6 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/BenchtestALL b/BenchtestALL
new file mode 100755
index 0000000..0323393
Binary files /dev/null and b/BenchtestALL differ
diff --git a/BenchtestALL.rs b/BenchtestALL.rs
index ff8fb92..1bc4629 100644
--- a/BenchtestALL.rs
+++ b/BenchtestALL.rs
@@ -19,9 +19,6 @@ under the License.
 #![allow(non_snake_case)]
 extern crate amcl;
 
-//use std::str;
-//use std::io;
-
 use amcl::arch;
 use amcl::rand::RAND;
 use amcl::types::{CurveType, CurvePairingType, ModType};
@@ -40,26 +37,26 @@ fn ed25519(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing ed25519 ECC");
 
-	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+	if ecp::CURVETYPE == CurveType::Weierstrass {
 		println!("Weierstrass parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::EDWARDS {
+	if ecp::CURVETYPE == CurveType::Edwards {
 		println!("Edwards parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+	if ecp::CURVETYPE == CurveType::Montgomery {
 		println!("Montgomery parameterization");
 	}
 
-	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+	if fp::MODTYPE == ModType::PseudoMersenne {
 		println!("Pseudo-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+	if fp::MODTYPE == ModType::MontgomeryFriendly {
 		println!("Montgomery friendly Modulus");
 	}
-	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+	if fp::MODTYPE == ModType::GeneralisedMersenne {
 		println!("Generalised-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::NOT_SPECIAL {
+	if fp::MODTYPE == ModType::NotSpecial {
 		println!("Not special Modulus");
 	}
 
@@ -68,8 +65,8 @@ fn ed25519(mut rng: &mut RAND) {
 
 	let G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let P = G.mul(&mut r);
 	if !P.is_infinity() {
@@ -103,26 +100,26 @@ fn nist256(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing nist256 ECC");
 
-	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+	if ecp::CURVETYPE == CurveType::Weierstrass {
 		println!("Weierstrass parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::EDWARDS {
+	if ecp::CURVETYPE == CurveType::Edwards {
 		println!("Edwards parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+	if ecp::CURVETYPE == CurveType::Montgomery {
 		println!("Montgomery parameterization");
 	}
 
-	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+	if fp::MODTYPE == ModType::PseudoMersenne {
 		println!("Pseudo-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+	if fp::MODTYPE == ModType::MontgomeryFriendly {
 		println!("Montgomery friendly Modulus");
 	}
-	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+	if fp::MODTYPE == ModType::GeneralisedMersenne {
 		println!("Generalised-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::NOT_SPECIAL {
+	if fp::MODTYPE == ModType::NotSpecial {
 		println!("Not special Modulus");
 	}
 
@@ -131,8 +128,8 @@ fn nist256(mut rng: &mut RAND) {
 
 	let G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let P = G.mul(&mut r);
 	if !P.is_infinity() {
@@ -166,26 +163,26 @@ fn goldilocks(mut rng: &mut RAND) {
 	let mut fail = false;
 	println!("\nTesting/Timing goldilocks ECC");
 
-	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+	if ecp::CURVETYPE == CurveType::Weierstrass {
 		println!("Weierstrass parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::EDWARDS {
+	if ecp::CURVETYPE == CurveType::Edwards {
 		println!("Edwards parameterization");
 	}
-	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+	if ecp::CURVETYPE == CurveType::Montgomery {
 		println!("Montgomery parameterization");
 	}
 
-	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+	if fp::MODTYPE == ModType::PseudoMersenne {
 		println!("Pseudo-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+	if fp::MODTYPE == ModType::MontgomeryFriendly {
 		println!("Montgomery friendly Modulus");
 	}
-	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+	if fp::MODTYPE == ModType::GeneralisedMersenne {
 		println!("Generalised-Mersenne Modulus");
 	}
-	if fp::MODTYPE == ModType::NOT_SPECIAL {
+	if fp::MODTYPE == ModType::NotSpecial {
 		println!("Not special Modulus");
 	}
 
@@ -194,8 +191,8 @@ fn goldilocks(mut rng: &mut RAND) {
 
 	let G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let P = G.mul(&mut r);
 	if !P.is_infinity() {
@@ -243,8 +240,8 @@ fn bn254(mut rng: &mut RAND) {
 
 	let mut G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let mut P = pair::g1mul(&mut G, &mut r);
 
@@ -403,8 +400,8 @@ fn bls383(mut rng: &mut RAND) {
 
 	let mut G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let mut P = pair::g1mul(&mut G, &mut r);
 
@@ -563,8 +560,8 @@ fn bls24(mut rng: &mut RAND) {
 
 	let mut G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let mut P = pair192::g1mul(&mut G, &mut r);
 
@@ -723,8 +720,8 @@ fn bls48(mut rng: &mut RAND) {
 
 	let mut G = ecp::ECP::generator();
 
-	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
-	let mut s = big::BIG::randomnum(&r, &mut rng);
+	let mut r = big::Big::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::Big::randomnum(&r, &mut rng);
 
 	let mut P = pair256::g1mul(&mut G, &mut r);
 
diff --git a/TestALL b/TestALL
new file mode 100755
index 0000000..36a1426
Binary files /dev/null and b/TestALL differ
diff --git a/TestALL.rs b/TestALL.rs
index 2dbf276..9c3e1d0 100644
--- a/TestALL.rs
+++ b/TestALL.rs
@@ -122,7 +122,7 @@ fn ecdh_ed25519(mut rng: &mut RAND) {
     print!("Servers DH Key=  0x");
     printbinary(&key);
 
-    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+    if ecp::CURVETYPE != CurveType::Montgomery {
         for i in 0..17 {
             m[i] = i as u8
         }
@@ -273,7 +273,7 @@ fn ecdh_nist256(mut rng: &mut RAND) {
     print!("Servers DH Key=  0x");
     printbinary(&key);
 
-    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+    if ecp::CURVETYPE != CurveType::Montgomery {
         for i in 0..17 {
             m[i] = i as u8
         }
@@ -424,7 +424,7 @@ fn ecdh_goldilocks(mut rng: &mut RAND) {
     print!("Servers DH Key=  0x");
     printbinary(&key);
 
-    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+    if ecp::CURVETYPE != CurveType::Montgomery {
         for i in 0..17 {
             m[i] = i as u8
         }
diff --git a/TestBLS b/TestBLS
new file mode 100755
index 0000000..b248889
Binary files /dev/null and b/TestBLS differ
diff --git a/readme.md b/readme.md
index 98f7d20..036defc 100644
--- a/readme.md
+++ b/readme.md
@@ -14,7 +14,7 @@ directory and its subdirectories to a fresh root directory.
 
 Then for example execute
 ```
-cargo rustc  --release --features "bn254 bls383 bls24 bls48 ed25519 nist256 goldilocks rsa2048"
+cargo build --release --features "bn254 bls383 bls24 bls48 ed25519 nist256 goldilocks rsa2048"
 ```
 This will create a build of the library for the current default target (be it 32 or 64 bits).
 


[incubator-milagro-crypto-rust] 27/44: Merge pull request #13 from sigp/cleanup-tests

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit b1140508dc0c60ec540f02c72a73cf80cc2982bd
Merge: e63b8f3 cd3c739
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Wed Mar 25 08:19:56 2020 +0000

    Merge pull request #13 from sigp/cleanup-tests
    
    [WIP] Cleanup tests

 Cargo.toml                                        |    4 +-
 TestALL.rs                                        | 1459 --------------------
 TestBLS.rs                                        |  190 ---
 TestNHS.rs                                        |   77 --
 readme.md                                         |   33 +-
 src/bls.rs                                        |   40 +-
 src/bls192.rs                                     |   38 +
 src/bls256.rs                                     |   38 +
 src/ecdh.rs                                       |  156 +++
 src/ecp.rs                                        |    2 +-
 src/gcm.rs                                        |    2 -
 src/lib.rs                                        |   11 +-
 src/mpin.rs                                       |  226 +++-
 src/mpin192.rs                                    |  227 +++-
 src/mpin256.rs                                    |  227 +++-
 src/nhs.rs                                        |   50 +
 src/roms/{rom_bn254CX_32.rs => rom_bn254cx_32.rs} |    6 +-
 src/roms/{rom_bn254CX_64.rs => rom_bn254cx_64.rs} |    6 +-
 src/rsa.rs                                        |   71 +
 src/test_utils/mod.rs                             |   21 +
 tests/test_all.rs                                 | 1473 ---------------------
 tests/test_bls.rs                                 |  190 ---
 tests/test_nhs.rs                                 |   71 -
 23 files changed, 1131 insertions(+), 3487 deletions(-)


[incubator-milagro-crypto-rust] 43/44: Merge pull request #23 from sigp/ecp-to-string

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit c49297580ce4df34a65d4d6f57638964be367353
Merge: 0a55e5d aac3576
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Tue May 5 07:38:08 2020 +0100

    Merge pull request #23 from sigp/ecp-to-string
    
    Fix ecp tostring

 src/ecp.rs | 1 +
 1 file changed, 1 insertion(+)


[incubator-milagro-crypto-rust] 02/44: Add gitignore and run cargo fmt --all

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit a665a5cec38836d6ed774765e85684ecb926f934
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Jul 3 11:25:15 2019 +1000

    Add gitignore and run cargo fmt --all
---
 .gitignore                    |   1 +
 src/aes.rs                    |  50 +++---
 src/big.rs                    |  14 +-
 src/bls.rs                    |  18 +-
 src/bls192.rs                 |  20 +--
 src/bls256.rs                 |  18 +-
 src/dbig.rs                   |   6 +-
 src/ecdh.rs                   |  11 +-
 src/ecp.rs                    |  31 ++--
 src/ecp2.rs                   |  35 ++--
 src/ecp4.rs                   |   4 +-
 src/ecp8.rs                   |   6 +-
 src/ff.rs                     |   4 +-
 src/fp.rs                     |  38 ++---
 src/fp12.rs                   | 381 ++++++++++++++++++++++++------------------
 src/fp16.rs                   |  22 +--
 src/fp2.rs                    |  26 +--
 src/fp24.rs                   | 360 ++++++++++++++++++++++-----------------
 src/fp4.rs                    |  32 ++--
 src/fp48.rs                   | 362 ++++++++++++++++++++++-----------------
 src/fp8.rs                    |  23 ++-
 src/lib.rs                    | 182 ++++++++++----------
 src/mpin.rs                   |   9 +-
 src/mpin192.rs                |   9 +-
 src/mpin256.rs                |   6 +-
 src/pair.rs                   | 101 ++++++-----
 src/pair192.rs                |  67 ++++----
 src/pair256.rs                |  65 ++++---
 src/roms/rom_anssi_32.rs      |   4 +-
 src/roms/rom_anssi_64.rs      |   4 +-
 src/roms/rom_bls24_32.rs      |   4 +-
 src/roms/rom_bls24_64.rs      |   4 +-
 src/roms/rom_bls381_32.rs     |   4 +-
 src/roms/rom_bls381_64.rs     |   4 +-
 src/roms/rom_bls383_32.rs     |   4 +-
 src/roms/rom_bls383_64.rs     |   4 +-
 src/roms/rom_bls461_32.rs     |   4 +-
 src/roms/rom_bls461_64.rs     |   4 +-
 src/roms/rom_bls48_32.rs      |   4 +-
 src/roms/rom_bls48_64.rs      |   4 +-
 src/roms/rom_bn254CX_32.rs    |   4 +-
 src/roms/rom_bn254CX_64.rs    |   5 +-
 src/roms/rom_bn254_32.rs      |   4 +-
 src/roms/rom_bn254_64.rs      |   6 +-
 src/roms/rom_brainpool_32.rs  |   4 +-
 src/roms/rom_brainpool_64.rs  |   4 +-
 src/roms/rom_c25519_32.rs     |   4 +-
 src/roms/rom_c25519_64.rs     |   4 +-
 src/roms/rom_c41417_32.rs     |   4 +-
 src/roms/rom_c41417_64.rs     |   4 +-
 src/roms/rom_ed25519_32.rs    |   4 +-
 src/roms/rom_ed25519_64.rs    |   4 +-
 src/roms/rom_fp256bn_32.rs    |   5 +-
 src/roms/rom_fp256bn_64.rs    |   4 +-
 src/roms/rom_fp512bn_32.rs    |   4 +-
 src/roms/rom_fp512bn_64.rs    |   4 +-
 src/roms/rom_goldilocks_32.rs |   4 +-
 src/roms/rom_goldilocks_64.rs |   4 +-
 src/roms/rom_hifive_32.rs     |   4 +-
 src/roms/rom_hifive_64.rs     |   4 +-
 src/roms/rom_nist256_32.rs    |   7 +-
 src/roms/rom_nist256_64.rs    |   4 +-
 src/roms/rom_nist384_32.rs    |   4 +-
 src/roms/rom_nist384_64.rs    |   5 +-
 src/roms/rom_nist521_32.rs    |   4 +-
 src/roms/rom_nist521_64.rs    |   4 +-
 src/roms/rom_nums256e_32.rs   |   5 +-
 src/roms/rom_nums256e_64.rs   |   5 +-
 src/roms/rom_nums256w_32.rs   |   4 +-
 src/roms/rom_nums256w_64.rs   |   4 +-
 src/roms/rom_nums384e_32.rs   |   5 +-
 src/roms/rom_nums384e_64.rs   |   5 +-
 src/roms/rom_nums384w_32.rs   |   5 +-
 src/roms/rom_nums384w_64.rs   |   5 +-
 src/roms/rom_nums512e_32.rs   |   4 +-
 src/roms/rom_nums512e_64.rs   |   4 +-
 src/roms/rom_nums512w_32.rs   |   4 +-
 src/roms/rom_nums512w_64.rs   |   4 +-
 src/roms/rom_rsa2048_32.rs    |   2 +-
 src/roms/rom_rsa2048_64.rs    |   2 +-
 src/roms/rom_rsa3072_32.rs    |   2 +-
 src/roms/rom_rsa3072_64.rs    |   2 +-
 src/roms/rom_rsa4096_32.rs    |   2 +-
 src/roms/rom_rsa4096_64.rs    |   2 +-
 src/roms/rom_secp256k1_32.rs  |   4 +-
 src/roms/rom_secp256k1_64.rs  |   4 +-
 src/types.rs                  |   1 -
 87 files changed, 1146 insertions(+), 990 deletions(-)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2f7896d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target/
diff --git a/src/aes.rs b/src/aes.rs
index eedea79..335a273 100644
--- a/src/aes.rs
+++ b/src/aes.rs
@@ -331,31 +331,31 @@ impl AES {
         while j < n {
             self.fkey[j] =
                 self.fkey[j - nk] ^ AES::subbyte(AES::rotl24(self.fkey[j - 1])) ^ (RCO[k] as u32);
-            if nk<=6 { 
-		for i in 1..nk {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}
-	    } else {
-		for i in 1..4  {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}
-		
-		if (j + 4) < n {
-			self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
-		}
-		for i in 5..nk {
-			if (i + j) >= n {
-				break;
-			}
-			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
-		}	        
-	    }
+            if nk <= 6 {
+                for i in 1..nk {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+            } else {
+                for i in 1..4 {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+
+                if (j + 4) < n {
+                    self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
+                }
+                for i in 5..nk {
+                    if (i + j) >= n {
+                        break;
+                    }
+                    self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+                }
+            }
             j += nk;
             k += 1;
         }
diff --git a/src/big.rs b/src/big.rs
index 7267ad4..285d82e 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -25,8 +25,8 @@ use super::super::arch::DChunk;
 use super::dbig::DBIG;
 use rand::RAND;
 
-pub use super::rom::MODBYTES;
 pub use super::rom::BASEBITS;
+pub use super::rom::MODBYTES;
 use std::cmp::Ordering;
 use std::fmt;
 
@@ -44,7 +44,9 @@ pub struct BIG {
 }
 
 impl Clone for BIG {
-    fn clone(&self) -> BIG { *self }
+    fn clone(&self) -> BIG {
+        *self
+    }
 }
 
 impl fmt::Display for BIG {
@@ -63,7 +65,7 @@ impl fmt::Debug for BIG {
 
 impl PartialEq for BIG {
     fn eq(&self, other: &BIG) -> bool {
-        if BIG::comp(self,other)==0 {
+        if BIG::comp(self, other) == 0 {
             return true;
         } else {
             return false;
@@ -84,7 +86,7 @@ impl Ord for BIG {
     }
 }
 
-impl Eq for BIG { }
+impl Eq for BIG {}
 
 impl PartialOrd for BIG {
     fn partial_cmp(&self, other: &BIG) -> Option<Ordering> {
@@ -345,7 +347,7 @@ impl BIG {
         res.w[0] += n as Chunk;
         for i in 1..len {
             res.shl(4);
-            let op = &val[i..i+1];
+            let op = &val[i..i + 1];
             let n = u8::from_str_radix(op, 16).unwrap();
             res.w[0] += n as Chunk;
         }
@@ -355,7 +357,7 @@ impl BIG {
     pub fn from_hex(val: String) -> BIG {
         BIG::fromstring(val)
     }
-    
+
     pub fn to_hex(&mut self) -> String {
         self.tostring()
     }
diff --git a/src/bls.rs b/src/bls.rs
index 7e7fd7a..c5c1b33 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -16,13 +16,13 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-use std::str;
 use super::ecp::ECP;
 use super::ecp2::ECP2;
+use std::str;
 //use super::fp12::FP12;
+use super::big;
 use super::big::BIG;
 use super::pair;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -79,14 +79,14 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP2::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
-    let mut r=pair::initmp();
-    pair::another(&mut r,&g,&d);
-    pair::another(&mut r,&pk,&hm);
-    let mut v=pair::miller(&r);
+    // Use new multi-pairing mechanism
+    let mut r = pair::initmp();
+    pair::another(&mut r, &g, &d);
+    pair::another(&mut r, &pk, &hm);
+    let mut v = pair::miller(&r);
 
-//.. or alternatively
-//    let mut v = pair::ate2(&g, &d, &pk, &hm);
+    //.. or alternatively
+    //    let mut v = pair::ate2(&g, &d, &pk, &hm);
 
     v = pair::fexp(&v);
     if v.isunity() {
diff --git a/src/bls192.rs b/src/bls192.rs
index 20ee92e..e981ab3 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -16,13 +16,13 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-use std::str;
 use super::ecp::ECP;
 use super::ecp4::ECP4;
+use std::str;
 //use super::fp24::FP24;
+use super::big;
 use super::big::BIG;
 use super::pair192;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -79,15 +79,15 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP4::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
-    let mut r=pair192::initmp();
-    pair192::another(&mut r,&g,&d);
-    pair192::another(&mut r,&pk,&hm);
-    let mut v=pair192::miller(&r);
+    // Use new multi-pairing mechanism
+    let mut r = pair192::initmp();
+    pair192::another(&mut r, &g, &d);
+    pair192::another(&mut r, &pk, &hm);
+    let mut v = pair192::miller(&r);
+
+    //.. or alternatively
+    //    let mut v = pair192::ate2(&g, &d, &pk, &hm);
 
-//.. or alternatively
-//    let mut v = pair192::ate2(&g, &d, &pk, &hm);
-    
     v = pair192::fexp(&v);
     if v.isunity() {
         return BLS_OK;
diff --git a/src/bls256.rs b/src/bls256.rs
index cdb553d..f9e4815 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -16,13 +16,13 @@ KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */
-use std::str;
 use super::ecp::ECP;
 use super::ecp8::ECP8;
+use std::str;
 //use super::fp48::FP48;
+use super::big;
 use super::big::BIG;
 use super::pair256;
-use super::big;
 use super::rom;
 
 use rand::RAND;
@@ -79,14 +79,14 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
     let pk = ECP8::frombytes(&w);
     d.neg();
 
-// Use new multi-pairing mechanism 
-    let mut r=pair256::initmp();
-    pair256::another(&mut r,&g,&d);
-    pair256::another(&mut r,&pk,&hm);
-    let mut v=pair256::miller(&r);
+    // Use new multi-pairing mechanism
+    let mut r = pair256::initmp();
+    pair256::another(&mut r, &g, &d);
+    pair256::another(&mut r, &pk, &hm);
+    let mut v = pair256::miller(&r);
 
-//.. or alternatively
-//    let mut v = pair256::ate2(&g, &d, &pk, &hm);
+    //.. or alternatively
+    //    let mut v = pair256::ate2(&g, &d, &pk, &hm);
 
     v = pair256::fexp(&v);
     if v.isunity() {
diff --git a/src/dbig.rs b/src/dbig.rs
index 353443a..2f5ad31 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -18,9 +18,9 @@ under the License.
 */
 
 use super::super::arch;
+use super::super::arch::Chunk;
 use super::big;
 use super::big::BIG;
-use super::super::arch::Chunk;
 
 #[derive(Copy)]
 pub struct DBIG {
@@ -28,7 +28,9 @@ pub struct DBIG {
 }
 
 impl Clone for DBIG {
-    fn clone(&self) -> DBIG { *self }
+    fn clone(&self) -> DBIG {
+        *self
+    }
 }
 
 impl DBIG {
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 9b49e18..2f9e516 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::ecp::ECP;
-use super::big::BIG;
 use super::rom;
-use super::big;
 
-use rand::RAND;
+use aes;
+use aes::AES;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-use aes;
-use aes::AES;
-
+use rand::RAND;
 
 pub const INVALID_PUBLIC_KEY: isize = -2;
 pub const ERROR: isize = -3;
diff --git a/src/ecp.rs b/src/ecp.rs
index 9e7b29c..a5c90c8 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -17,15 +17,15 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::fp::FP;
-use super::big::BIG;
 use super::big;
+use super::big::BIG;
+use super::fp::FP;
 use super::rom;
 
-pub use super::rom::{CURVETYPE, CURVE_PAIRING_TYPE, SEXTIC_TWIST, SIGN_OF_X, HASH_TYPE, AESKEY};
-pub use types::CurveType;
-use std::str::SplitWhitespace;
+pub use super::rom::{AESKEY, CURVETYPE, CURVE_PAIRING_TYPE, HASH_TYPE, SEXTIC_TWIST, SIGN_OF_X};
 use std::fmt;
+use std::str::SplitWhitespace;
+pub use types::CurveType;
 
 #[derive(Copy, Clone)]
 pub struct ECP {
@@ -41,15 +41,15 @@ impl PartialEq for ECP {
 }
 
 impl fmt::Display for ECP {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 impl fmt::Debug for ECP {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 #[allow(non_snake_case)]
@@ -193,7 +193,7 @@ impl ECP {
     /* test for O point-at-infinity */
     pub fn is_infinity(&self) -> bool {
         match CURVETYPE {
-            CurveType::EDWARDS=> self.x.iszilch() && self.y.equals(&self.z),
+            CurveType::EDWARDS => self.x.iszilch() && self.y.equals(&self.z),
             CurveType::WEIERSTRASS => self.x.iszilch() && self.z.iszilch(),
             CurveType::MONTGOMERY => self.z.iszilch(),
         }
@@ -440,7 +440,12 @@ impl ECP {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+        format!(
+            "{} {} {}",
+            self.x.to_hex(),
+            self.y.to_hex(),
+            self.z.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP {
diff --git a/src/ecp2.rs b/src/ecp2.rs
index afd9376..c7445fa 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -17,14 +17,14 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::fp2::FP2;
-use super::big::BIG;
-use types::{SexticTwist, CurvePairingType, SignOfX};
-use std::str::SplitWhitespace;
+use super::rom;
 use std::fmt;
+use std::str::SplitWhitespace;
+use types::{CurvePairingType, SexticTwist, SignOfX};
 
 #[derive(Copy, Clone)]
 pub struct ECP2 {
@@ -34,21 +34,21 @@ pub struct ECP2 {
 }
 
 impl PartialEq for ECP2 {
-	fn eq(&self, other: &ECP2) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &ECP2) -> bool {
+        self.equals(other)
+    }
 }
 
 impl fmt::Display for ECP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 impl fmt::Debug for ECP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+    }
 }
 
 #[allow(non_snake_case)]
@@ -291,14 +291,19 @@ impl ECP2 {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+        format!(
+            "{} {} {}",
+            self.x.to_hex(),
+            self.y.to_hex(),
+            self.z.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP2 {
         ECP2 {
             x: FP2::from_hex_iter(iter),
             y: FP2::from_hex_iter(iter),
-            z: FP2::from_hex_iter(iter)
+            z: FP2::from_hex_iter(iter),
         }
     }
 
diff --git a/src/ecp4.rs b/src/ecp4.rs
index d34b0fd..31a92e1 100644
--- a/src/ecp4.rs
+++ b/src/ecp4.rs
@@ -17,12 +17,12 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
+use super::rom;
 use types::{SexticTwist, SignOfX};
 //use std::str::SplitWhitespace;
 
diff --git a/src/ecp8.rs b/src/ecp8.rs
index a6d32a4..99953dc 100644
--- a/src/ecp8.rs
+++ b/src/ecp8.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::rom;
 use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::BIG;
+use super::rom;
 use types::{SexticTwist, SignOfX};
 
 pub struct ECP8 {
@@ -914,7 +914,7 @@ impl ECP8 {
         // Number of bits
         mt.zero();
         for i in 0..16 {
-	    t[i].norm();
+            t[i].norm();
             mt.or(&t[i]);
         }
 
diff --git a/src/ff.rs b/src/ff.rs
index 4737ee8..f1abc00 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::super::arch::Chunk;
 use super::big;
-use super::dbig::DBIG;
 use super::big::BIG;
-use super::super::arch::Chunk;
+use super::dbig::DBIG;
 use rand::RAND;
 
 use super::super::arch::DChunk;
diff --git a/src/fp.rs b/src/fp.rs
index 57345c1..bd790d3 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -17,14 +17,14 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::super::arch;
+use super::super::arch::Chunk;
 use super::big;
 use super::big::BIG;
 use super::dbig::DBIG;
 use super::rom;
-use super::super::arch::Chunk;
-use super::super::arch;
-use types::ModType;
 use std::str::FromStr;
+use types::ModType;
 
 #[derive(Copy, Clone)]
 pub struct FP {
@@ -50,14 +50,14 @@ impl fmt::Debug for FP {
     }
 }
 
-pub use super::rom::{MODBITS, MOD8, MODTYPE, SH};
-use std::str::SplitWhitespace;
+pub use super::rom::{MOD8, MODBITS, MODTYPE, SH};
 use std::fmt;
+use std::str::SplitWhitespace;
 
-pub const FEXCESS:i32 = (((1 as i32)<<SH)-1);
-pub const OMASK:Chunk = (-1)<<(MODBITS%big::BASEBITS);
-pub const TBITS:usize=MODBITS%big::BASEBITS; // Number of active bits in top word
-pub const TMASK:Chunk=(1<<TBITS)-1;
+pub const FEXCESS: i32 = (((1 as i32) << SH) - 1);
+pub const OMASK: Chunk = (-1) << (MODBITS % big::BASEBITS);
+pub const TBITS: usize = MODBITS % big::BASEBITS; // Number of active bits in top word
+pub const TMASK: Chunk = (1 << TBITS) - 1;
 
 impl FP {
     /* Constructors */
@@ -91,8 +91,8 @@ impl FP {
 
     pub fn nres(&mut self) {
         if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let r=BIG::new_ints(&rom::R2MODP);
-            let mut d=BIG::mul(&(self.x),&r);
+            let r = BIG::new_ints(&rom::R2MODP);
+            let mut d = BIG::mul(&(self.x), &r);
             self.x.copy(&FP::modulo(&mut d));
             self.xes = 2;
         } else {
@@ -105,7 +105,7 @@ impl FP {
         let x = iter.next().unwrap();
         FP {
             x: BIG::from_hex(x.to_string()),
-            xes
+            xes,
         }
     }
 
@@ -120,10 +120,10 @@ impl FP {
         format!("{} {}", self.xes, big)
     }
 
-/* convert back to regular form */
+    /* convert back to regular form */
     pub fn redc(&mut self) -> BIG {
         if MODTYPE != ModType::PSEUDO_MERSENNE && MODTYPE != ModType::GENERALISED_MERSENNE {
-            let mut d=DBIG::new_scopy(&(self.x));
+            let mut d = DBIG::new_scopy(&(self.x));
             return FP::modulo(&mut d);
         } else {
             let r = BIG::new_copy(&(self.x));
@@ -134,9 +134,9 @@ impl FP {
     /* reduce a DBIG to a BIG using the appropriate form of the modulus */
     /* dd */
     pub fn modulo(d: &mut DBIG) -> BIG {
-        if MODTYPE==ModType::PSEUDO_MERSENNE {
-            let mut b=BIG::new();
-            let mut t=d.split(MODBITS);
+        if MODTYPE == ModType::PSEUDO_MERSENNE {
+            let mut b = BIG::new();
+            let mut t = d.split(MODBITS);
             b.dcopy(&d);
             let v = t.pmul(rom::MCONST as isize);
 
@@ -149,8 +149,8 @@ impl FP {
             t.norm();
             return t;
         }
-    
-        if MODTYPE==ModType::MONTGOMERY_FRIENDLY {
+
+        if MODTYPE == ModType::MONTGOMERY_FRIENDLY {
             let mut b = BIG::new();
             for i in 0..big::NLEN {
                 let x = d.w[i];
diff --git a/src/fp12.rs b/src/fp12.rs
index 9c06a3e..745814f 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -18,19 +18,19 @@ under the License.
 */
 
 use super::big;
+use super::big::BIG;
+use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
 use super::rom;
-use types::SexticTwist;
 use std::str::SplitWhitespace;
-use super::ecp;
+use types::SexticTwist;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP12 {
@@ -41,9 +41,9 @@ pub struct FP12 {
 }
 
 impl PartialEq for FP12 {
-	fn eq(&self, other: &FP12) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP12) -> bool {
+        self.equals(other)
+    }
 }
 
 impl FP12 {
@@ -52,12 +52,12 @@ impl FP12 {
             a: FP4::new(),
             b: FP4::new(),
             c: FP4::new(),
-	    stype: ZERO,
+            stype: ZERO,
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -69,11 +69,11 @@ impl FP12 {
         f.a.copy(&FP4::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -82,7 +82,7 @@ impl FP12 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -91,7 +91,7 @@ impl FP12 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -100,7 +100,7 @@ impl FP12 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -129,9 +129,9 @@ impl FP12 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -175,20 +175,20 @@ impl FP12 {
 
     pub fn geta(&mut self) -> FP4 {
         return self.a;
-//        let f = FP4::new_copy(&self.a);
-//        return f;
+        //        let f = FP4::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP4 {
         return self.b;
-//        let f = FP4::new_copy(&self.b);
-//        return f;
+        //        let f = FP4::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP4 {
         return self.c;
-//        let f = FP4::new_copy(&self.c);
-//        return f;
+        //        let f = FP4::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -196,7 +196,7 @@ impl FP12 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -204,7 +204,7 @@ impl FP12 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -212,7 +212,7 @@ impl FP12 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -260,13 +260,13 @@ impl FP12 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
 
@@ -304,10 +304,10 @@ impl FP12 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -379,128 +379,144 @@ impl FP12 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
-/* FP12 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP12 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP12) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP4::new_copy(&self.a);
-            let mut z1=FP4::new_int(0);
-            let mut z2=FP4::new_int(0);
-            let mut z3=FP4::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP4::new_copy(&self.a);
+            let mut z1 = FP4::new_int(0);
+            let mut z2 = FP4::new_int(0);
+            let mut z3 = FP4::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP2::new_int(0);
-		    let mut gb=FP2::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP2::new_int(0);
+                    let mut gb = FP2::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp2s(&ga,&gb);
+                    z2.set_fp2s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+            } else {
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP4::new_copy(&self.a);
-            let mut t1=FP4::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
-
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
+            let mut t0 = FP4::new_copy(&self.a);
+            let mut t1 = FP4::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
- 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
+
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP2::new_int(0);
-		    let mut gb=FP2::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP2::new_int(0);
+                    let mut gb = FP2::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp2s(&ga,&gb);
+                    t0.set_fp2s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
-                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_int(0);
-                let mut t1=FP4::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                // dense by sparser - 13m
+                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_int(0);
+                let mut t1 = FP4::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -514,8 +530,10 @@ impl FP12 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -523,97 +541,121 @@ impl FP12 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
                 let mut z0 = FP4::new_copy(&self.a);
                 let mut z1 = FP4::new();
                 let mut z2 = FP4::new();
                 let mut z3 = FP4::new();
                 let mut t0 = FP4::new_copy(&self.a);
                 let mut t1 = FP4::new();
-	
+
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }	
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP12) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
-            let mut w1=FP2::new_copy(&self.a.geta());
-            let mut w2=FP2::new_copy(&self.a.getb());
-            let mut w3=FP2::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            let mut w1 = FP2::new_copy(&self.a.geta());
+            let mut w2 = FP2::new_copy(&self.a.getb());
+            let mut w3 = FP2::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP2::new_copy(&self.a.geta());
-            let mut tb=FP2::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP2::new_copy(&ta);
+            let mut ta = FP2::new_copy(&self.a.geta());
+            let mut tb = FP2::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP2::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP2::new_copy(&w1);
+            let mut t = FP2::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP2::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP2::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP2::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP2::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -623,44 +665,54 @@ impl FP12 {
             w2.mul_ip();
             w1.add(&w2);
 
-	    self.a.set_fp2s(&w1,&tc);
-	    self.b.set_fp2s(&td,&te);
-	    self.c.set_fp2(&w3);
-           
+            self.a.set_fp2s(&w1, &tc);
+            self.b.set_fp2s(&td, &te);
+            self.c.set_fp2(&w3);
+
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP2::new_copy(&self.a.geta());
-            let mut w2=FP2::new_copy(&self.a.getb());
-            let mut w3=FP2::new_copy(&self.c.getb());
+            let mut w1 = FP2::new_copy(&self.a.geta());
+            let mut w2 = FP2::new_copy(&self.a.getb());
+            let mut w3 = FP2::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP2::new_copy(&self.a.geta());
-            let mut tb=FP2::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP2::new_copy(&ta);
+            let mut ta = FP2::new_copy(&self.a.geta());
+            let mut tb = FP2::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP2::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP2::new_copy(&w1);
+            let mut t = FP2::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP2::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP2::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP2::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP2::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -669,20 +721,20 @@ impl FP12 {
 
             w2.mul_ip();
             w1.add(&w2);
-	    self.a.set_fp2s(&w1,&tc);
+            self.a.set_fp2s(&w1, &tc);
 
             w3.mul_ip();
             w3.norm();
-	    self.b.set_fp2h(&w3);
+            self.b.set_fp2h(&w3);
 
             te.norm();
             te.mul_ip();
-	    self.c.set_fp2s(&te,&td);
+            self.c.set_fp2s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -730,7 +782,7 @@ impl FP12 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -747,7 +799,7 @@ impl FP12 {
 
         self.b.pmul(f);
         self.c.pmul(&f2);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
@@ -902,7 +954,12 @@ impl FP12 {
     }
 
     pub fn to_hex(&self) -> String {
-        format!("{} {} {}", self.a.to_hex(), self.b.to_hex(), self.c.to_hex())
+        format!(
+            "{} {} {}",
+            self.a.to_hex(),
+            self.b.to_hex(),
+            self.c.to_hex()
+        )
     }
 
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP12 {
@@ -910,7 +967,7 @@ impl FP12 {
             a: FP4::from_hex_iter(iter),
             b: FP4::from_hex_iter(iter),
             c: FP4::from_hex_iter(iter),
-	    stype: DENSE
+            stype: DENSE,
         }
     }
 
diff --git a/src/fp16.rs b/src/fp16.rs
index c579db4..4ecf744 100644
--- a/src/fp16.rs
+++ b/src/fp16.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::BIG;
 use super::fp2::FP2;
 use super::fp8::FP8;
-use super::big::BIG;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -64,19 +64,19 @@ impl FP16 {
         return f;
     }
 
-    pub fn set_fp8s(&mut self,c: &FP8, d: &FP8) {
+    pub fn set_fp8s(&mut self, c: &FP8, d: &FP8) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp8(&mut self,c: &FP8) {
+    pub fn set_fp8(&mut self, c: &FP8) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp8h(&mut self,c: &FP8) {
+    pub fn set_fp8h(&mut self, c: &FP8) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
     /* reduce components mod Modulus */
@@ -119,14 +119,14 @@ impl FP16 {
 
     pub fn geta(&self) -> FP8 {
         return self.a;
-//        let f = FP8::new_copy(&self.a);
-//        return f;
+        //        let f = FP8::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP8 {
         return self.b;
-//        let f = FP8::new_copy(&self.b);
-//        return f;
+        //        let f = FP8::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
diff --git a/src/fp2.rs b/src/fp2.rs
index c848f19..be6c1df 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::fp;
-use super::fp::FP;
 use super::big::BIG;
 use super::dbig::DBIG;
+use super::fp;
+use super::fp::FP;
 use super::rom;
-use std::str::SplitWhitespace;
 use std::fmt;
+use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
 pub struct FP2 {
@@ -32,21 +32,21 @@ pub struct FP2 {
 }
 
 impl PartialEq for FP2 {
-	fn eq(&self, other: &FP2) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP2) -> bool {
+        self.equals(other)
+    }
 }
 
 impl fmt::Display for FP2 {
-	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-		write!(f, "FP2: [ {}, {} ]", self.a, self.b)
-	}
+    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)
-	}
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "FP2: [ {}, {} ]", self.a, self.b)
+    }
 }
 
 impl FP2 {
@@ -331,7 +331,7 @@ impl FP2 {
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP2 {
         FP2 {
             a: FP::from_hex_iter(iter),
-            b: FP::from_hex_iter(iter)
+            b: FP::from_hex_iter(iter),
         }
     }
 
diff --git a/src/fp24.rs b/src/fp24.rs
index 5f154b3..4041b1f 100644
--- a/src/fp24.rs
+++ b/src/fp24.rs
@@ -18,20 +18,20 @@ under the License.
 */
 
 use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::big::BIG;
 use super::rom;
-use types::{SexticTwist};
+use types::SexticTwist;
 //use std::str::SplitWhitespace;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP24 {
@@ -51,8 +51,8 @@ impl FP24 {
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -64,11 +64,11 @@ impl FP24 {
         f.a.copy(&FP8::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -77,7 +77,7 @@ impl FP24 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -86,7 +86,7 @@ impl FP24 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -95,7 +95,7 @@ impl FP24 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -123,9 +123,9 @@ impl FP24 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -169,20 +169,20 @@ impl FP24 {
 
     pub fn geta(&mut self) -> FP8 {
         return self.a;
-//        let f = FP8::new_copy(&self.a);
-//        return f;
+        //        let f = FP8::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP8 {
         return self.b;
-//	let f = FP8::new_copy(&self.b);
-//        return f;
+        //	let f = FP8::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP8 {
         return self.c;
-//        let f = FP8::new_copy(&self.c);
-//        return f;
+        //        let f = FP8::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -190,7 +190,7 @@ impl FP24 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -198,7 +198,7 @@ impl FP24 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -206,7 +206,7 @@ impl FP24 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -254,13 +254,13 @@ impl FP24 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
         let mut a = FP8::new_copy(&self.a);
@@ -297,10 +297,10 @@ impl FP24 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -373,127 +373,144 @@ impl FP24 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-/* FP24 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP24 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP24) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP8::new_copy(&self.a);
-            let mut z1=FP8::new_int(0);
-            let mut z2=FP8::new_int(0);
-            let mut z3=FP8::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP8::new_copy(&self.a);
+            let mut z1 = FP8::new_int(0);
+            let mut z2 = FP8::new_int(0);
+            let mut z3 = FP8::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP4::new_int(0);
-		    let mut gb=FP4::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP4::new_int(0);
+                    let mut gb = FP4::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp4s(&ga,&gb);
+                    z2.set_fp4s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+            } else {
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP8::new_copy(&self.a);
-            let mut t1=FP8::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
+            let mut t0 = FP8::new_copy(&self.a);
+            let mut t1 = FP8::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
-
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
- 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
+
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP4::new_int(0);
-		    let mut gb=FP4::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP4::new_int(0);
+                    let mut gb = FP4::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp4s(&ga,&gb);
+                    t0.set_fp4s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
-                let mut z0=FP8::new_copy(&self.a);
-                let mut z2=FP8::new_copy(&self.b);
-                let mut z3=FP8::new_copy(&self.b);
-                let mut t0=FP8::new_int(0);
-                let mut t1=FP8::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                // dense by sparser - 13m
+                let mut z0 = FP8::new_copy(&self.a);
+                let mut z2 = FP8::new_copy(&self.b);
+                let mut z3 = FP8::new_copy(&self.b);
+                let mut t0 = FP8::new_int(0);
+                let mut t1 = FP8::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -507,8 +524,10 @@ impl FP24 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -516,98 +535,121 @@ impl FP24 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
                 let mut z0 = FP8::new_copy(&self.a);
                 let mut z1 = FP8::new();
                 let mut z2 = FP8::new();
                 let mut z3 = FP8::new();
                 let mut t0 = FP8::new_copy(&self.a);
                 let mut t1 = FP8::new();
-	
+
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }	
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP24) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
-            let mut w1=FP4::new_copy(&self.a.geta());
-            let mut w2=FP4::new_copy(&self.a.getb());
-            let mut w3=FP4::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            let mut w1 = FP4::new_copy(&self.a.geta());
+            let mut w2 = FP4::new_copy(&self.a.getb());
+            let mut w3 = FP4::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP4::new_copy(&self.a.geta());
-            let mut tb=FP4::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP4::new_copy(&ta);
+            let mut ta = FP4::new_copy(&self.a.geta());
+            let mut tb = FP4::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP4::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP4::new_copy(&w1);
+            let mut t = FP4::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP4::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP4::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP4::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP4::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -617,44 +659,54 @@ impl FP24 {
             w2.times_i();
             w1.add(&w2);
 
-	    self.a.set_fp4s(&w1,&tc);
-	    self.b.set_fp4s(&td,&te);
-	    self.c.set_fp4(&w3);
+            self.a.set_fp4s(&w1, &tc);
+            self.b.set_fp4s(&td, &te);
+            self.c.set_fp4(&w3);
 
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP4::new_copy(&self.a.geta());
-            let mut w2=FP4::new_copy(&self.a.getb());
-            let mut w3=FP4::new_copy(&self.c.getb());
+            let mut w1 = FP4::new_copy(&self.a.geta());
+            let mut w2 = FP4::new_copy(&self.a.getb());
+            let mut w3 = FP4::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP4::new_copy(&self.a.geta());
-            let mut tb=FP4::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP4::new_copy(&ta);
+            let mut ta = FP4::new_copy(&self.a.geta());
+            let mut tb = FP4::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP4::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP4::new_copy(&w1);
+            let mut t = FP4::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP4::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP4::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP4::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP4::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -663,20 +715,20 @@ impl FP24 {
 
             w2.times_i();
             w1.add(&w2);
-	    self.a.set_fp4s(&w1,&tc);
+            self.a.set_fp4s(&w1, &tc);
 
             w3.times_i();
             w3.norm();
-	    self.b.set_fp4h(&w3);
+            self.b.set_fp4h(&w3);
 
             te.norm();
             te.times_i();
-	    self.c.set_fp4s(&te,&td);
+            self.c.set_fp4s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -724,7 +776,7 @@ impl FP24 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -749,7 +801,7 @@ impl FP24 {
             self.c.times_i2();
             self.c.times_i2();
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
diff --git a/src/fp4.rs b/src/fp4.rs
index 1db4b73..1e5f847 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::BIG;
 use super::fp::FP;
 use super::fp2::FP2;
-use super::big::BIG;
 use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -29,9 +29,9 @@ pub struct FP4 {
 }
 
 impl PartialEq for FP4 {
-	fn eq(&self, other: &FP4) -> bool {
-		self.equals(other)
-	}
+    fn eq(&self, other: &FP4) -> bool {
+        self.equals(other)
+    }
 }
 
 impl FP4 {
@@ -69,20 +69,20 @@ impl FP4 {
         f.b.zero();
         return f;
     }
-	
-    pub fn set_fp2s(&mut self,c: &FP2, d: &FP2) {
+
+    pub fn set_fp2s(&mut self, c: &FP2, d: &FP2) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp2(&mut self,c: &FP2) {
+    pub fn set_fp2(&mut self, c: &FP2) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp2h(&mut self,c: &FP2) {
+    pub fn set_fp2h(&mut self, c: &FP2) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
     /* reduce components mod Modulus */
@@ -125,14 +125,14 @@ impl FP4 {
 
     pub fn geta(&self) -> FP2 {
         return self.a;
-//        let f = FP2::new_copy(&self.a);
-//        return f;
+        //        let f = FP2::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP2 {
         return self.b;
-//        let f = FP2::new_copy(&self.b);
-//        return f;
+        //        let f = FP2::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
@@ -313,7 +313,7 @@ impl FP4 {
     pub fn from_hex_iter(iter: &mut SplitWhitespace) -> FP4 {
         FP4 {
             a: FP2::from_hex_iter(iter),
-            b: FP2::from_hex_iter(iter)
+            b: FP2::from_hex_iter(iter),
         }
     }
 
diff --git a/src/fp48.rs b/src/fp48.rs
index c72ee4c..96174b0 100644
--- a/src/fp48.rs
+++ b/src/fp48.rs
@@ -18,21 +18,21 @@ under the License.
 */
 
 use super::big;
+use super::big::BIG;
 use super::ecp;
+use super::fp16::FP16;
 use super::fp2::FP2;
 use super::fp4::FP4;
 use super::fp8::FP8;
-use super::fp16::FP16;
-use super::big::BIG;
 use super::rom;
 use types::SexticTwist;
 //use std::str::SplitWhitespace;
 
-pub const ZERO: usize=0;
-pub const ONE: usize=1;
-pub const SPARSER: usize=2;
-pub const SPARSE: usize=3;
-pub const DENSE: usize=4;
+pub const ZERO: usize = 0;
+pub const ONE: usize = 1;
+pub const SPARSER: usize = 2;
+pub const SPARSE: usize = 3;
+pub const DENSE: usize = 4;
 
 #[derive(Copy, Clone)]
 pub struct FP48 {
@@ -48,12 +48,12 @@ impl FP48 {
             a: FP16::new(),
             b: FP16::new(),
             c: FP16::new(),
-	    stype: ZERO,
+            stype: ZERO,
         }
     }
 
-    pub fn settype(&mut self,t: usize)  {
-	self.stype = t;
+    pub fn settype(&mut self, t: usize) {
+        self.stype = t;
     }
 
     pub fn gettype(&self) -> usize {
@@ -65,11 +65,11 @@ impl FP48 {
         f.a.copy(&FP16::new_int(a));
         f.b.zero();
         f.c.zero();
-	if a == 1 {
-	    f.stype=ONE;
-	} else {
-	    f.stype=SPARSER;
-	}
+        if a == 1 {
+            f.stype = ONE;
+        } else {
+            f.stype = SPARSER;
+        }
         return f;
     }
 
@@ -78,7 +78,7 @@ impl FP48 {
         f.a.copy(&x.a);
         f.b.copy(&x.b);
         f.c.copy(&x.c);
-	f.stype=x.stype;
+        f.stype = x.stype;
         return f;
     }
 
@@ -87,7 +87,7 @@ impl FP48 {
         g.a.copy(d);
         g.b.copy(e);
         g.c.copy(f);
-	g.stype=DENSE;
+        g.stype = DENSE;
         return g;
     }
 
@@ -96,7 +96,7 @@ impl FP48 {
         g.a.copy(d);
         g.b.zero();
         g.c.zero();
-	g.stype=SPARSER;
+        g.stype = SPARSER;
         return g;
     }
 
@@ -124,9 +124,9 @@ impl FP48 {
         self.a.cmove(&g.a, d);
         self.b.cmove(&g.b, d);
         self.c.cmove(&g.c, d);
-	let mut u=d as usize;
-	u=!(u-1);
-	self.stype^=(self.stype^g.stype)&u;
+        let mut u = d as usize;
+        u = !(u - 1);
+        self.stype ^= (self.stype ^ g.stype) & u;
     }
 
     /* return 1 if b==c, no branching */
@@ -170,20 +170,20 @@ impl FP48 {
 
     pub fn geta(&mut self) -> FP16 {
         return self.a;
-//        let f = FP16::new_copy(&self.a);
-//        return f;
+        //        let f = FP16::new_copy(&self.a);
+        //        return f;
     }
 
     pub fn getb(&mut self) -> FP16 {
         return self.b;
-//        let f = FP16::new_copy(&self.b);
-//        return f;
+        //        let f = FP16::new_copy(&self.b);
+        //        return f;
     }
 
     pub fn getc(&mut self) -> FP16 {
         return self.c;
-//        let f = FP16::new_copy(&self.c);
-//        return f;
+        //        let f = FP16::new_copy(&self.c);
+        //        return f;
     }
 
     /* copy self=x */
@@ -191,7 +191,7 @@ impl FP48 {
         self.a.copy(&x.a);
         self.b.copy(&x.b);
         self.c.copy(&x.c);
-	self.stype=x.stype;
+        self.stype = x.stype;
     }
 
     /* set self=1 */
@@ -199,7 +199,7 @@ impl FP48 {
         self.a.one();
         self.b.zero();
         self.c.zero();
-	self.stype=ONE;
+        self.stype = ONE;
     }
 
     /* set self=0 */
@@ -207,7 +207,7 @@ impl FP48 {
         self.a.zero();
         self.b.zero();
         self.c.zero();
-	self.stype=ZERO;
+        self.stype = ZERO;
     }
 
     /* this=conj(this) */
@@ -255,13 +255,13 @@ impl FP48 {
         self.c.dbl();
         self.b.add(&b);
         self.c.add(&c);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.reduce();
     }
 
     /* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
     pub fn sqr(&mut self) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             return;
         }
         let mut a = FP16::new_copy(&self.a);
@@ -298,10 +298,10 @@ impl FP48 {
         self.b.copy(&c);
         self.b.add(&d);
         self.c.add(&a);
-        if self.stype==SPARSER {
-            self.stype=SPARSE;
+        if self.stype == SPARSER {
+            self.stype = SPARSE;
         } else {
-            self.stype=DENSE;
+            self.stype = DENSE;
         }
         self.norm();
     }
@@ -373,127 +373,144 @@ impl FP48 {
         z3.times_i();
         self.a.copy(&z0);
         self.a.add(&z3);
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-/* FP48 full multiplication w=w*y */
-/* Supports sparse multiplicands */
-/* Usually w is denser than y */
+    /* FP48 full multiplication w=w*y */
+    /* Supports sparse multiplicands */
+    /* Usually w is denser than y */
     pub fn ssmul(&mut self, y: &FP48) {
-        if self.stype==ONE {
+        if self.stype == ONE {
             self.copy(&y);
             return;
         }
-        if y.stype==ONE {
+        if y.stype == ONE {
             return;
         }
-        if y.stype>=SPARSE {
-            let mut z0=FP16::new_copy(&self.a);
-            let mut z1=FP16::new_int(0);
-            let mut z2=FP16::new_int(0);
-            let mut z3=FP16::new_int(0);
+        if y.stype >= SPARSE {
+            let mut z0 = FP16::new_copy(&self.a);
+            let mut z1 = FP16::new_int(0);
+            let mut z2 = FP16::new_int(0);
+            let mut z3 = FP16::new_int(0);
             z0.mul(&y.a);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP8::new_int(0);
-		    let mut gb=FP8::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP8::new_int(0);
+                    let mut gb = FP8::new_int(0);
 
                     gb.copy(&self.b.getb());
                     gb.mul(&y.b.getb());
                     ga.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         ga.copy(&self.b.getb());
                         ga.mul(&y.b.geta());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         ga.copy(&self.b.geta());
                         ga.mul(&y.b.getb());
                     }
-		    z2.set_fp8s(&ga,&gb);
+                    z2.set_fp8s(&ga, &gb);
                     z2.times_i();
                 } else {
                     z2.copy(&self.b);
                     z2.mul(&y.b);
                 }
-            } else { 
-               z2.copy(&self.b);
-               z2.mul(&y.b);
+            } else {
+                z2.copy(&self.b);
+                z2.mul(&y.b);
             }
-            let mut t0=FP16::new_copy(&self.a);
-            let mut t1=FP16::new_copy(&y.a);
-            t0.add(&self.b); t0.norm();
-            t1.add(&y.b); t1.norm();
-
-            z1.copy(&t0); z1.mul(&t1);
-            t0.copy(&self.b); t0.add(&self.c); t0.norm();
-            t1.copy(&y.b); t1.add(&y.c); t1.norm();
-
-            z3.copy(&t0); z3.mul(&t1);
+            let mut t0 = FP16::new_copy(&self.a);
+            let mut t1 = FP16::new_copy(&y.a);
+            t0.add(&self.b);
+            t0.norm();
+            t1.add(&y.b);
+            t1.norm();
+
+            z1.copy(&t0);
+            z1.mul(&t1);
+            t0.copy(&self.b);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.b);
+            t1.add(&y.c);
+            t1.norm();
+
+            z3.copy(&t0);
+            z3.mul(&t1);
+
+            t0.copy(&z0);
+            t0.neg();
+            t1.copy(&z2);
+            t1.neg();
 
-            t0.copy(&z0); t0.neg();
-            t1.copy(&z2); t1.neg();
- 
             z1.add(&t0);
-            self.b.copy(&z1); self.b.add(&t1);
+            self.b.copy(&z1);
+            self.b.add(&t1);
 
             z3.add(&t1);
             z2.add(&t0);
 
-            t0.copy(&self.a); t0.add(&self.c); t0.norm();
-            t1.copy(&y.a); t1.add(&y.c); t1.norm();
-	
+            t0.copy(&self.a);
+            t0.add(&self.c);
+            t0.norm();
+            t1.copy(&y.a);
+            t1.add(&y.c);
+            t1.norm();
+
             t0.mul(&t1);
             z2.add(&t0);
 
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {
-                if y.stype==SPARSE || self.stype==SPARSE {
-
-                    let mut ga=FP8::new_int(0);
-		    let mut gb=FP8::new_int(0);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                if y.stype == SPARSE || self.stype == SPARSE {
+                    let mut ga = FP8::new_int(0);
+                    let mut gb = FP8::new_int(0);
 
                     ga.copy(&self.c.geta());
                     ga.mul(&y.c.geta());
                     gb.zero();
-                    if y.stype!=SPARSE {
+                    if y.stype != SPARSE {
                         gb.copy(&self.c.geta());
                         gb.mul(&y.c.getb());
                     }
-                    if self.stype!=SPARSE {
+                    if self.stype != SPARSE {
                         gb.copy(&self.c.getb());
                         gb.mul(&y.c.geta());
                     }
-		    t0.set_fp8s(&ga,&gb);
+                    t0.set_fp8s(&ga, &gb);
                 } else {
                     t0.copy(&self.c);
                     t0.mul(&y.c);
                 }
-            } else { 
+            } else {
                 t0.copy(&self.c);
                 t0.mul(&y.c);
             }
-            t1.copy(&t0); t1.neg();
+            t1.copy(&t0);
+            t1.neg();
 
-            self.c.copy(&z2); self.c.add(&t1);
+            self.c.copy(&z2);
+            self.c.add(&t1);
             z3.add(&t1);
             t0.times_i();
             self.b.add(&t0);
             z3.norm();
             z3.times_i();
-            self.a.copy(&z0); self.a.add(&z3);
+            self.a.copy(&z0);
+            self.a.add(&z3);
         } else {
-            if self.stype==SPARSER {
+            if self.stype == SPARSER {
                 self.smul(&y);
                 return;
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE { // dense by sparser - 13m 
-                let mut z0=FP16::new_copy(&self.a);
-                let mut z2=FP16::new_copy(&self.b);
-                let mut z3=FP16::new_copy(&self.b);
-                let mut t0=FP16::new_int(0);
-                let mut t1=FP16::new_copy(&y.a);
+            if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+                // dense by sparser - 13m
+                let mut z0 = FP16::new_copy(&self.a);
+                let mut z2 = FP16::new_copy(&self.b);
+                let mut z3 = FP16::new_copy(&self.b);
+                let mut t0 = FP16::new_int(0);
+                let mut t1 = FP16::new_copy(&y.a);
 
                 z0.mul(&y.a);
                 z2.pmul(&y.b.geta());
@@ -507,8 +524,10 @@ impl FP48 {
                 z3.norm();
                 z3.pmul(&y.b.geta());
 
-                t0.copy(&z0); t0.neg();
-                t1.copy(&z2); t1.neg();
+                t0.copy(&z0);
+                t0.neg();
+                t1.copy(&z2);
+                t1.neg();
 
                 self.b.add(&t0);
 
@@ -516,98 +535,121 @@ impl FP48 {
                 z3.add(&t1);
                 z2.add(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
                 z3.norm();
                 t0.mul(&y.a);
-                self.c.copy(&z2); self.c.add(&t0);
+                self.c.copy(&z2);
+                self.c.add(&t0);
 
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
+                self.a.copy(&z0);
+                self.a.add(&z3);
             }
-            if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
-
+            if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
                 let mut z0 = FP16::new_copy(&self.a);
                 let mut z1 = FP16::new();
                 let mut z2 = FP16::new();
                 let mut z3 = FP16::new();
                 let mut t0 = FP16::new_copy(&self.a);
                 let mut t1 = FP16::new();
-	
+
                 z0.mul(&y.a);
-                t0.add(&self.b); t0.norm();
+                t0.add(&self.b);
+                t0.norm();
 
-                z1.copy(&t0); z1.mul(&y.a);
-                t0.copy(&self.b); t0.add(&self.c);
+                z1.copy(&t0);
+                z1.mul(&y.a);
+                t0.copy(&self.b);
+                t0.add(&self.c);
                 t0.norm();
 
                 z3.copy(&t0);
                 z3.pmul(&y.c.getb());
                 z3.times_i();
 
-                t0.copy(&z0); t0.neg();
+                t0.copy(&z0);
+                t0.neg();
                 z1.add(&t0);
                 self.b.copy(&z1);
                 z2.copy(&t0);
 
-                t0.copy(&self.a); t0.add(&self.c); t0.norm();
-                t1.copy(&y.a); t1.add(&y.c); t1.norm();
+                t0.copy(&self.a);
+                t0.add(&self.c);
+                t0.norm();
+                t1.copy(&y.a);
+                t1.add(&y.c);
+                t1.norm();
 
                 t0.mul(&t1);
                 z2.add(&t0);
                 t0.copy(&self.c);
-			
+
                 t0.pmul(&y.c.getb());
                 t0.times_i();
-                t1.copy(&t0); t1.neg();
+                t1.copy(&t0);
+                t1.neg();
 
-                self.c.copy(&z2); self.c.add(&t1);
+                self.c.copy(&z2);
+                self.c.add(&t1);
                 z3.add(&t1);
                 t0.times_i();
                 self.b.add(&t0);
                 z3.norm();
                 z3.times_i();
-                self.a.copy(&z0); self.a.add(&z3);
-           }	
+                self.a.copy(&z0);
+                self.a.add(&z3);
+            }
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
         self.norm();
     }
 
-
     /* Special case of multiplication arises from special form of ATE pairing line function */
     pub fn smul(&mut self, y: &FP48) {
-        if ecp::SEXTIC_TWIST==SexticTwist::D_TYPE {	
-            let mut w1=FP8::new_copy(&self.a.geta());
-            let mut w2=FP8::new_copy(&self.a.getb());
-            let mut w3=FP8::new_copy(&self.b.geta());
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            let mut w1 = FP8::new_copy(&self.a.geta());
+            let mut w2 = FP8::new_copy(&self.a.getb());
+            let mut w3 = FP8::new_copy(&self.b.geta());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.b.geta());
 
-            let mut ta=FP8::new_copy(&self.a.geta());
-            let mut tb=FP8::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP8::new_copy(&ta);
+            let mut ta = FP8::new_copy(&self.a.geta());
+            let mut tb = FP8::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP8::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP8::new_copy(&w1);
+            let mut t = FP8::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.b.geta()); tb.norm();
-            let mut td=FP8::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut td = FP8::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.b.geta()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.b.geta()); tb.norm();
-            let mut te=FP8::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.b.geta());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.b.geta());
+            tb.norm();
+            let mut te = FP8::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -617,44 +659,54 @@ impl FP48 {
             w2.times_i();
             w1.add(&w2);
 
-	    self.a.set_fp8s(&w1,&tc);
-	    self.b.set_fp8s(&td,&te);
-	    self.c.set_fp8(&w3);
+            self.a.set_fp8s(&w1, &tc);
+            self.b.set_fp8s(&td, &te);
+            self.c.set_fp8(&w3);
 
             self.a.norm();
             self.b.norm();
         } else {
-            let mut w1=FP8::new_copy(&self.a.geta());
-            let mut w2=FP8::new_copy(&self.a.getb());
-            let mut w3=FP8::new_copy(&self.c.getb());
+            let mut w1 = FP8::new_copy(&self.a.geta());
+            let mut w2 = FP8::new_copy(&self.a.getb());
+            let mut w3 = FP8::new_copy(&self.c.getb());
 
             w1.mul(&y.a.geta());
             w2.mul(&y.a.getb());
             w3.mul(&y.c.getb());
 
-            let mut ta=FP8::new_copy(&self.a.geta());
-            let mut tb=FP8::new_copy(&y.a.geta());
-            ta.add(&self.a.getb()); ta.norm();
-            tb.add(&y.a.getb()); tb.norm();
-            let mut tc=FP8::new_copy(&ta);
+            let mut ta = FP8::new_copy(&self.a.geta());
+            let mut tb = FP8::new_copy(&y.a.geta());
+            ta.add(&self.a.getb());
+            ta.norm();
+            tb.add(&y.a.getb());
+            tb.norm();
+            let mut tc = FP8::new_copy(&ta);
             tc.mul(&tb);
-            let mut t=FP8::new_copy(&w1);
+            let mut t = FP8::new_copy(&w1);
             t.add(&w2);
             t.neg();
             tc.add(&t);
 
-            ta.copy(&self.a.geta()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.geta()); tb.add(&y.c.getb()); tb.norm();
-            let mut td=FP8::new_copy(&ta);
+            ta.copy(&self.a.geta());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.geta());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut td = FP8::new_copy(&ta);
             td.mul(&tb);
             t.copy(&w1);
             t.add(&w3);
             t.neg();
             td.add(&t);
 
-            ta.copy(&self.a.getb()); ta.add(&self.c.getb()); ta.norm();
-            tb.copy(&y.a.getb()); tb.add(&y.c.getb()); tb.norm();
-            let mut te=FP8::new_copy(&ta);
+            ta.copy(&self.a.getb());
+            ta.add(&self.c.getb());
+            ta.norm();
+            tb.copy(&y.a.getb());
+            tb.add(&y.c.getb());
+            tb.norm();
+            let mut te = FP8::new_copy(&ta);
             te.mul(&tb);
             t.copy(&w2);
             t.add(&w3);
@@ -663,20 +715,20 @@ impl FP48 {
 
             w2.times_i();
             w1.add(&w2);
-	    self.a.set_fp8s(&w1,&tc);
+            self.a.set_fp8s(&w1, &tc);
 
             w3.times_i();
             w3.norm();
-	    self.b.set_fp8h(&w3);
+            self.b.set_fp8h(&w3);
 
             te.norm();
             te.times_i();
-	    self.c.set_fp8s(&te,&td);
+            self.c.set_fp8s(&te, &td);
 
             self.a.norm();
             self.c.norm();
-	}
-	self.stype=SPARSE;
+        }
+        self.stype = SPARSE;
     }
 
     /* self=1/self */
@@ -724,7 +776,7 @@ impl FP48 {
         self.b.mul(&f3);
         self.c.copy(&f2);
         self.c.mul(&f3);
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* self=self^p using Frobenius */
@@ -753,7 +805,7 @@ impl FP48 {
             self.c.times_i4();
             self.c.times_i4();
         }
-        self.stype=DENSE;
+        self.stype = DENSE;
     }
 
     /* trace function */
diff --git a/src/fp8.rs b/src/fp8.rs
index dfc84d1..e693b13 100644
--- a/src/fp8.rs
+++ b/src/fp8.rs
@@ -17,10 +17,10 @@ specific language governing permissions and limitations
 under the License.
 */
 
+use super::big::BIG;
 use super::fp::FP;
 use super::fp2::FP2;
 use super::fp4::FP4;
-use super::big::BIG;
 //use std::str::SplitWhitespace;
 
 #[derive(Copy, Clone)]
@@ -65,22 +65,21 @@ impl FP8 {
         return f;
     }
 
-    pub fn set_fp4s(&mut self,c: &FP4, d: &FP4) {
+    pub fn set_fp4s(&mut self, c: &FP4, d: &FP4) {
         self.a.copy(&c);
-	self.b.copy(&d);
+        self.b.copy(&d);
     }
 
-    pub fn set_fp4(&mut self,c: &FP4) {
+    pub fn set_fp4(&mut self, c: &FP4) {
         self.a.copy(&c);
-	self.b.zero();
+        self.b.zero();
     }
 
-    pub fn set_fp4h(&mut self,c: &FP4) {
+    pub fn set_fp4h(&mut self, c: &FP4) {
         self.b.copy(&c);
-	self.a.zero();
+        self.a.zero();
     }
 
-
     /* reduce components mod Modulus */
     pub fn reduce(&mut self) {
         self.a.reduce();
@@ -121,14 +120,14 @@ impl FP8 {
 
     pub fn geta(&self) -> FP4 {
         return self.a;
-//        let f = FP4::new_copy(&self.a);
-//        return f;
+        //        let f = FP4::new_copy(&self.a);
+        //        return f;
     }
     /* extract imaginary part b */
     pub fn getb(&self) -> FP4 {
         return self.b;
-//        let f = FP4::new_copy(&self.b);
-//        return f;
+        //        let f = FP4::new_copy(&self.b);
+        //        return f;
     }
 
     /* test self=x */
diff --git a/src/lib.rs b/src/lib.rs
index 108057b..c68a165 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,18 +1,18 @@
 pub mod aes;
+#[cfg(target_pointer_width = "32")]
+#[path = "arch/arch32.rs"]
+pub mod arch;
+#[cfg(target_pointer_width = "64")]
+#[path = "arch/arch64.rs"]
+pub mod arch;
 pub mod gcm;
 pub mod hash256;
 pub mod hash384;
 pub mod hash512;
+pub mod nhs;
 pub mod rand;
 pub mod sha3;
-pub mod nhs;
 pub mod types;
-#[cfg(target_pointer_width = "32")]
-#[path = "arch/arch32.rs"]
-pub mod arch;
-#[cfg(target_pointer_width = "64")]
-#[path = "arch/arch64.rs"]
-pub mod arch;
 
 #[cfg(feature = "bls48")]
 #[path = "./"]
@@ -25,18 +25,18 @@ pub mod bls48 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls256;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp8;
+    pub mod fp;
+    pub mod fp16;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp8;
-    pub mod fp16;
     pub mod fp48;
-    pub mod pair256;
+    pub mod fp8;
     pub mod mpin256;
-    pub mod bls256;
+    pub mod pair256;
 }
 
 #[cfg(feature = "bls461")]
@@ -50,16 +50,16 @@ pub mod bls461 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls383")]
@@ -73,16 +73,16 @@ pub mod bls383 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls381")]
@@ -96,16 +96,16 @@ pub mod bls381 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "fp512bn")]
@@ -119,16 +119,16 @@ pub mod fp512bn {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "fp256bn")]
@@ -142,16 +142,16 @@ pub mod fp256bn {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
     pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bls24")]
@@ -165,17 +165,17 @@ pub mod bls24 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls192;
     pub mod dbig;
+    pub mod ecp;
+    pub mod ecp4;
     pub mod fp;
     pub mod fp2;
+    pub mod fp24;
     pub mod fp4;
     pub mod fp8;
-    pub mod fp24;
-    pub mod ecp;
-    pub mod ecp4;
-    pub mod pair192;
     pub mod mpin192;
-    pub mod bls192;
+    pub mod pair192;
 }
 
 #[cfg(feature = "anssi")]
@@ -190,9 +190,9 @@ pub mod anssi {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "brainpool")]
@@ -207,9 +207,9 @@ pub mod brainpool {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "goldilocks")]
@@ -224,9 +224,9 @@ pub mod goldilocks {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "hifive")]
@@ -241,9 +241,9 @@ pub mod hifive {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist256")]
@@ -258,9 +258,9 @@ pub mod nist256 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist384")]
@@ -275,9 +275,9 @@ pub mod nist384 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nist521")]
@@ -292,9 +292,9 @@ pub mod nist521 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums256e")]
@@ -309,9 +309,9 @@ pub mod nums256e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums256w")]
@@ -326,9 +326,9 @@ pub mod nums256w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums384e")]
@@ -343,9 +343,9 @@ pub mod nums384e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums384w")]
@@ -360,9 +360,9 @@ pub mod nums384w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums512w")]
@@ -377,9 +377,9 @@ pub mod nums512w {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "nums512e")]
@@ -394,9 +394,9 @@ pub mod nums512e {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "secp256k1")]
@@ -411,9 +411,9 @@ pub mod secp256k1 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "c25519")]
@@ -428,9 +428,9 @@ pub mod c25519 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "c41417")]
@@ -445,9 +445,9 @@ pub mod c41417 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "ed25519")]
@@ -462,9 +462,9 @@ pub mod ed25519 {
 
     pub mod big;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
+    pub mod fp;
 }
 
 #[cfg(feature = "bn254CX")]
@@ -478,17 +478,17 @@ pub mod bn254CX {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "bn254")]
@@ -502,60 +502,60 @@ pub mod bn254 {
     pub mod rom;
 
     pub mod big;
+    pub mod bls;
     pub mod dbig;
-    pub mod fp;
-    pub mod ecp;
     pub mod ecdh;
+    pub mod ecp;
     pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
     pub mod fp2;
     pub mod fp4;
-    pub mod fp12;
-    pub mod pair;
     pub mod mpin;
-    pub mod bls;
+    pub mod pair;
 }
 
 #[cfg(feature = "rsa2048")]
 #[path = "./"]
 pub mod rsa2048 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa2048_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa2048_64.rs"]
     pub mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
 }
 
 #[cfg(feature = "rsa3072")]
 #[path = "./"]
 pub mod rsa3072 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa3072_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa3072_64.rs"]
     pub mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
 }
 
 #[cfg(feature = "rsa4096")]
 #[path = "./"]
 pub mod rsa4096 {
+    pub mod big;
+    pub mod dbig;
+    pub mod ff;
     #[cfg(target_pointer_width = "32")]
     #[path = "roms/rom_rsa4096_32.rs"]
     mod rom;
     #[cfg(target_pointer_width = "64")]
     #[path = "roms/rom_rsa4096_64.rs"]
     mod rom;
-    pub mod big;
-    pub mod dbig;
-    pub mod ff;
     pub mod rsa;
-}
\ No newline at end of file
+}
diff --git a/src/mpin.rs b/src/mpin.rs
index 6d7e9ca..dbb713b 100644
--- a/src/mpin.rs
+++ b/src/mpin.rs
@@ -20,21 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp2::ECP2;
-use super::fp4::FP4;
 use super::fp12::FP12;
-use super::big::BIG;
+use super::fp4::FP4;
 use super::pair;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-
+use rand::RAND;
 
 /* MPIN API Functions */
 
diff --git a/src/mpin192.rs b/src/mpin192.rs
index 276a560..3278b30 100644
--- a/src/mpin192.rs
+++ b/src/mpin192.rs
@@ -20,21 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp4::ECP4;
-use super::fp8::FP8;
 use super::fp24::FP24;
-use super::big::BIG;
+use super::fp8::FP8;
 use super::pair192;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
-
+use rand::RAND;
 
 /* MPIN API Functions */
 
diff --git a/src/mpin256.rs b/src/mpin256.rs
index b4928e9..76340c7 100644
--- a/src/mpin256.rs
+++ b/src/mpin256.rs
@@ -20,20 +20,20 @@ under the License.
 use std::time::SystemTime;
 use std::time::UNIX_EPOCH;
 
+use super::big;
+use super::big::BIG;
 use super::ecp;
 use super::ecp::ECP;
 use super::ecp8::ECP8;
 use super::fp16::FP16;
 use super::fp48::FP48;
-use super::big::BIG;
 use super::pair256;
-use super::big;
 use super::rom;
 
-use rand::RAND;
 use hash256::HASH256;
 use hash384::HASH384;
 use hash512::HASH512;
+use rand::RAND;
 
 /* MPIN API Functions */
 
diff --git a/src/pair.rs b/src/pair.rs
index 2050296..ce59f0d 100644
--- a/src/pair.rs
+++ b/src/pair.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::BIG;
+use super::dbig::DBIG;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp2::ECP2;
-use super::fp4::FP4;
+use super::fp::FP;
 use super::fp12;
 use super::fp12::FP12;
-use super::big::BIG;
-use super::dbig::DBIG;
-use super::ecp;
+use super::fp2::FP2;
+use super::fp4::FP4;
 use super::rom;
-use types::{SexticTwist, CurvePairingType, SignOfX};
+use types::{CurvePairingType, SexticTwist, SignOfX};
 
 #[allow(non_snake_case)]
 fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
@@ -81,7 +80,7 @@ fn linedbl(A: &mut ECP2, qx: &FP, qy: &FP) -> FP12 {
         c.times_i();
     }
     A.dbl();
-    let mut res= FP12::new_fp4s(&a, &b, &c);
+    let mut res = FP12::new_fp4s(&a, &b, &c);
     res.settype(fp12::SPARSER);
     return res;
 }
@@ -132,18 +131,18 @@ fn lineadd(A: &mut ECP2, B: &ECP2, qx: &FP, qy: &FP) -> FP12 {
     }
 
     A.add(B);
-    let mut res= FP12::new_fp4s(&a, &b, &c);
+    let mut res = FP12::new_fp4s(&a, &b, &c);
     res.settype(fp12::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
+fn lbits(n3: &mut BIG, n: &mut BIG) -> usize {
     n.copy(&BIG::new_ints(&rom::CURVE_BNX));
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
         n.pmul(6);
-        if ecp::SIGN_OF_X==SignOfX::POSITIVEX {
+        if ecp::SIGN_OF_X == SignOfX::POSITIVEX {
             n.inc(2);
         } else {
             n.dec(2);
@@ -159,18 +158,18 @@ fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP12; rom::ATE_BITS] {
     let r: [FP12; rom::ATE_BITS] = [FP12::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP12]) -> FP12 {
-    let mut res=FP12::new_int(1);
+pub fn miller(r: &[FP12]) -> FP12 {
+    let mut res = FP12::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -179,14 +178,13 @@ pub fn miller(r:&[FP12]) -> FP12 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
+pub fn another(r: &mut [FP12], P1: &ECP2, Q1: &ECP) {
     let mut f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
     let mut n = BIG::new();
     let mut n3 = BIG::new();
     let mut K = ECP2::new();
 
-
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP2::new();
     P.copy(P1);
     P.affine();
@@ -194,8 +192,8 @@ pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
     Q.copy(Q1);
     Q.affine();
 
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
-        if ecp::SEXTIC_TWIST==SexticTwist::M_TYPE {
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
             f.inverse();
             f.norm();
         }
@@ -210,37 +208,37 @@ pub fn another(r:&mut [FP12],P1: &ECP2,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
     }
 
-/* R-ate fixup required for BN curves */
-    if ecp::CURVE_PAIRING_TYPE==CurvePairingType::BN {
-        if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    /* R-ate fixup required for BN curves */
+    if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
             A.neg();
         }
         K.copy(&P);
         K.frob(&f);
-        let mut lv=lineadd(&mut A,&K,&qx,&qy);
+        let mut lv = lineadd(&mut A, &K, &qx, &qy);
         K.frob(&f);
         K.neg();
-        let lv2=lineadd(&mut A,&K,&qx,&qy);
+        let lv2 = lineadd(&mut A, &K, &qx, &qy);
         lv.smul(&lv2);
-	r[0].ssmul(&lv);
-    } 
+        r[0].ssmul(&lv);
+    }
 }
 
 #[allow(non_snake_case)]
@@ -256,7 +254,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
             f.inverse();
             f.norm();
         }
-    } 
+    }
     let mut P = ECP2::new();
     P.copy(P1);
     P.affine();
@@ -275,7 +273,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -310,7 +308,7 @@ pub fn ate(P1: &ECP2, Q1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         let lv2 = lineadd(&mut A, &K, &qx, &qy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
     }
 
@@ -330,7 +328,7 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
             f.inverse();
             f.norm();
         }
-    } 
+    }
 
     let mut P = ECP2::new();
     P.copy(P1);
@@ -365,25 +363,25 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
     NR.copy(&R);
     NR.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
@@ -405,7 +403,7 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         let mut lv2 = lineadd(&mut A, &K, &qx, &qy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
 
         K.copy(&R);
@@ -415,9 +413,8 @@ pub fn ate2(P1: &ECP2, Q1: &ECP, R1: &ECP2, S1: &ECP) -> FP12 {
         K.frob(&f);
         K.neg();
         lv2 = lineadd(&mut B, &K, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
-
     }
 
     return r;
@@ -439,10 +436,10 @@ pub fn fexp(m: &FP12) -> FP12 {
     r.frob(&f);
     r.frob(&f);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
 
     /* Hard part of final exp */
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
diff --git a/src/pair192.rs b/src/pair192.rs
index 4310b6b..3883b90 100644
--- a/src/pair192.rs
+++ b/src/pair192.rs
@@ -17,17 +17,16 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::BIG;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp4::ECP4;
-use super::fp4::FP4;
-use super::fp8::FP8;
+use super::fp::FP;
+use super::fp2::FP2;
 use super::fp24;
 use super::fp24::FP24;
-use super::big::BIG;
-use super::ecp;
+use super::fp4::FP4;
+use super::fp8::FP8;
 use super::rom;
 use types::{SexticTwist, SignOfX};
 
@@ -80,7 +79,7 @@ fn linedbl(A: &mut ECP4, qx: &FP, qy: &FP) -> FP24 {
         c.times_i();
     }
     A.dbl();
-    let mut res= FP24::new_fp8s(&a, &b, &c);
+    let mut res = FP24::new_fp8s(&a, &b, &c);
     res.settype(fp24::SPARSER);
     return res;
 }
@@ -130,14 +129,14 @@ fn lineadd(A: &mut ECP4, B: &ECP4, qx: &FP, qy: &FP) -> FP24 {
     }
 
     A.add(B);
-    let mut res= FP24::new_fp8s(&a, &b, &c);
+    let mut res = FP24::new_fp8s(&a, &b, &c);
     res.settype(fp24::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
+fn lbits(n3: &mut BIG, n: &mut BIG) -> usize {
     n.copy(&BIG::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
@@ -148,18 +147,18 @@ fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP24; rom::ATE_BITS] {
     let r: [FP24; rom::ATE_BITS] = [FP24::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP24]) -> FP24 {
-    let mut res=FP24::new_int(1);
+pub fn miller(r: &[FP24]) -> FP24 {
+    let mut res = FP24::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -168,11 +167,11 @@ pub fn miller(r:&[FP24]) -> FP24 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
+pub fn another(r: &mut [FP24], P1: &ECP4, Q1: &ECP) {
     let mut n = BIG::new();
     let mut n3 = BIG::new();
-    
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP4::new();
     P.copy(P1);
     P.affine();
@@ -189,18 +188,18 @@ pub fn another(r:&mut [FP24],P1: &ECP4,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
@@ -231,7 +230,7 @@ pub fn ate(P1: &ECP4, Q1: &ECP) -> FP24 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -296,25 +295,25 @@ pub fn ate2(P1: &ECP4, Q1: &ECP, R1: &ECP4, S1: &ECP) -> FP24 {
     NR.copy(&R);
     NR.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
@@ -341,10 +340,10 @@ pub fn fexp(m: &FP24) -> FP24 {
     lv.copy(&r);
     r.frob(&f, 4);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
diff --git a/src/pair256.rs b/src/pair256.rs
index 7cdca72..9353fe6 100644
--- a/src/pair256.rs
+++ b/src/pair256.rs
@@ -17,19 +17,18 @@ specific language governing permissions and limitations
 under the License.
 */
 
-
-use super::fp::FP;
+use super::big::BIG;
+use super::ecp;
 use super::ecp::ECP;
-use super::fp2::FP2;
 use super::ecp8::ECP8;
-use super::fp8::FP8;
+use super::fp::FP;
 use super::fp16::FP16;
+use super::fp2::FP2;
 use super::fp48;
 use super::fp48::FP48;
-use super::big::BIG;
-use super::ecp;
+use super::fp8::FP8;
 use super::rom;
-use types::{SignOfX, SexticTwist};
+use types::{SexticTwist, SignOfX};
 
 #[allow(non_snake_case)]
 fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
@@ -80,7 +79,7 @@ fn linedbl(A: &mut ECP8, qx: &FP, qy: &FP) -> FP48 {
         c.times_i();
     }
     A.dbl();
-    let mut res= FP48::new_fp16s(&a, &b, &c);
+    let mut res = FP48::new_fp16s(&a, &b, &c);
     res.settype(fp48::SPARSER);
     return res;
 }
@@ -130,14 +129,14 @@ fn lineadd(A: &mut ECP8, B: &ECP8, qx: &FP, qy: &FP) -> FP48 {
     }
 
     A.add(B);
-    let mut res= FP48::new_fp16s(&a, &b, &c);
+    let mut res = FP48::new_fp16s(&a, &b, &c);
     res.settype(fp48::SPARSER);
     return res;
 }
 
 /* prepare ate parameter, n=6u+2 (BN) or n=u (BLS), n3=3*n */
 #[allow(non_snake_case)]
-fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
+fn lbits(n3: &mut BIG, n: &mut BIG) -> usize {
     n.copy(&BIG::new_ints(&rom::CURVE_BNX));
     n3.copy(&n);
     n3.pmul(3);
@@ -148,18 +147,18 @@ fn lbits(n3: &mut BIG,n: &mut BIG) -> usize {
 /* prepare for multi-pairing */
 pub fn initmp() -> [FP48; rom::ATE_BITS] {
     let r: [FP48; rom::ATE_BITS] = [FP48::new_int(1); rom::ATE_BITS];
-    return r
+    return r;
 }
 
 /* basic Miller loop */
-pub fn miller(r:&[FP48]) -> FP48 {
-    let mut res=FP48::new_int(1);
+pub fn miller(r: &[FP48]) -> FP48 {
+    let mut res = FP48::new_int(1);
     for i in (1..rom::ATE_BITS).rev() {
         res.sqr();
         res.ssmul(&r[i]);
     }
 
-    if ecp::SIGN_OF_X==SignOfX::NEGATIVEX {
+    if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
         res.conj();
     }
     res.ssmul(&r[0]);
@@ -168,11 +167,11 @@ pub fn miller(r:&[FP48]) -> FP48 {
 
 /* Accumulate another set of line functions for n-pairing */
 #[allow(non_snake_case)]
-pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
+pub fn another(r: &mut [FP48], P1: &ECP8, Q1: &ECP) {
     let mut n = BIG::new();
     let mut n3 = BIG::new();
 
-// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+    // P is needed in affine form for line function, Q for (Qx,Qy) extraction
     let mut P = ECP8::new();
     P.copy(P1);
     P.affine();
@@ -189,18 +188,18 @@ pub fn another(r:&mut [FP48],P1: &ECP8,Q1: &ECP) {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
-    for i in (1..nb-1).rev() {
-        let mut lv=linedbl(&mut A,&qx,&qy);
+    for i in (1..nb - 1).rev() {
+        let mut lv = linedbl(&mut A, &qx, &qy);
 
-	let bt=n3.bit(i)-n.bit(i);
-        if bt==1 {
-            let lv2=lineadd(&mut A,&P,&qx,&qy);
+        let bt = n3.bit(i) - n.bit(i);
+        if bt == 1 {
+            let lv2 = lineadd(&mut A, &P, &qx, &qy);
             lv.smul(&lv2);
         }
-        if bt==-1 {
-            let lv2=lineadd(&mut A,&NP,&qx,&qy);
+        if bt == -1 {
+            let lv2 = lineadd(&mut A, &NP, &qx, &qy);
             lv.smul(&lv2);
         }
         r[i].ssmul(&lv);
@@ -231,7 +230,7 @@ pub fn ate(P1: &ECP8, Q1: &ECP) -> FP48 {
     NP.copy(&P);
     NP.neg();
 
-    let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
@@ -294,25 +293,25 @@ pub fn ate2(P1: &ECP8, Q1: &ECP, R1: &ECP8, S1: &ECP) -> FP48 {
     NR.copy(&R);
     NR.neg();
 
-     let nb=lbits(&mut n3,&mut n);
+    let nb = lbits(&mut n3, &mut n);
 
     for i in (1..nb - 1).rev() {
         r.sqr();
         let mut lv = linedbl(&mut A, &qx, &qy);
         let lv2 = linedbl(&mut B, &sx, &sy);
-	lv.smul(&lv2);
+        lv.smul(&lv2);
         r.ssmul(&lv);
         let bt = n3.bit(i) - n.bit(i);
         if bt == 1 {
             lv = lineadd(&mut A, &P, &qx, &qy);
             let lv2 = lineadd(&mut B, &R, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
         if bt == -1 {
             lv = lineadd(&mut A, &NP, &qx, &qy);
             let lv2 = lineadd(&mut B, &NR, &sx, &sy);
-	    lv.smul(&lv2);
+            lv.smul(&lv2);
             r.ssmul(&lv);
         }
     }
@@ -339,10 +338,10 @@ pub fn fexp(m: &FP48) -> FP48 {
     lv.copy(&r);
     r.frob(&f, 8);
     r.mul(&lv);
-//    if r.isunity() {
-//	r.zero();
-//	return r;
-//    }
+    //    if r.isunity() {
+    //	r.zero();
+    //	return r;
+    //    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
diff --git a/src/roms/rom_anssi_32.rs b/src/roms/rom_anssi_32.rs
index 403fb04..d64b4fc 100644
--- a/src/roms/rom_anssi_32.rs
+++ b/src/roms/rom_anssi_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use anssi::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use anssi::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // anssi Modulus
diff --git a/src/roms/rom_anssi_64.rs b/src/roms/rom_anssi_64.rs
index b0add0f..654ad6f 100644
--- a/src/roms/rom_anssi_64.rs
+++ b/src/roms/rom_anssi_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use anssi::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use anssi::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // anssi Modulus
diff --git a/src/roms/rom_bls24_32.rs b/src/roms/rom_bls24_32.rs
index 72afe58..afdc8b9 100644
--- a/src/roms/rom_bls24_32.rs
+++ b/src/roms/rom_bls24_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls24::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls24::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls24 Modulus
diff --git a/src/roms/rom_bls24_64.rs b/src/roms/rom_bls24_64.rs
index 0c500da..33a6f13 100644
--- a/src/roms/rom_bls24_64.rs
+++ b/src/roms/rom_bls24_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls24::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls24::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // bls24 Modulus
diff --git a/src/roms/rom_bls381_32.rs b/src/roms/rom_bls381_32.rs
index 1ba0fe5..61f3140 100644
--- a/src/roms/rom_bls381_32.rs
+++ b/src/roms/rom_bls381_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls381::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls381::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls381 Modulus
diff --git a/src/roms/rom_bls381_64.rs b/src/roms/rom_bls381_64.rs
index 08df12c..cea1446 100644
--- a/src/roms/rom_bls381_64.rs
+++ b/src/roms/rom_bls381_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls381::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls381::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // bls381 Modulus
diff --git a/src/roms/rom_bls383_32.rs b/src/roms/rom_bls383_32.rs
index 0ccb42d..4fd502e 100644
--- a/src/roms/rom_bls383_32.rs
+++ b/src/roms/rom_bls383_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls383::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls383::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_bls383_64.rs b/src/roms/rom_bls383_64.rs
index 71bef66..5b3b97d 100644
--- a/src/roms/rom_bls383_64.rs
+++ b/src/roms/rom_bls383_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls383::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls383::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_bls461_32.rs b/src/roms/rom_bls461_32.rs
index c452a9f..3a07a56 100644
--- a/src/roms/rom_bls461_32.rs
+++ b/src/roms/rom_bls461_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls461::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls461::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // bls461 Modulus
diff --git a/src/roms/rom_bls461_64.rs b/src/roms/rom_bls461_64.rs
index 500ef04..b6d822c 100644
--- a/src/roms/rom_bls461_64.rs
+++ b/src/roms/rom_bls461_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls461::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls461::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // bls461 Modulus
diff --git a/src/roms/rom_bls48_32.rs b/src/roms/rom_bls48_32.rs
index 83517a8..73cedc4 100644
--- a/src/roms/rom_bls48_32.rs
+++ b/src/roms/rom_bls48_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls48::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls48::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // bls48 Modulus
diff --git a/src/roms/rom_bls48_64.rs b/src/roms/rom_bls48_64.rs
index 129c776..fe41cb4 100644
--- a/src/roms/rom_bls48_64.rs
+++ b/src/roms/rom_bls48_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bls48::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bls48::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // bls48 Modulus
diff --git a/src/roms/rom_bn254CX_32.rs b/src/roms/rom_bn254CX_32.rs
index e1cff0d..e0ebba9 100644
--- a/src/roms/rom_bn254CX_32.rs
+++ b/src/roms/rom_bn254CX_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254CX::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254CX::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // bn254CX Modulus
diff --git a/src/roms/rom_bn254CX_64.rs b/src/roms/rom_bn254CX_64.rs
index 7f6d274..fa9e221 100644
--- a/src/roms/rom_bn254CX_64.rs
+++ b/src/roms/rom_bn254CX_64.rs
@@ -17,10 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254CX::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
-
+use bn254CX::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // bn254CX Modulus
diff --git a/src/roms/rom_bn254_32.rs b/src/roms/rom_bn254_32.rs
index c9ae5ec..e31eb7e 100644
--- a/src/roms/rom_bn254_32.rs
+++ b/src/roms/rom_bn254_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_bn254_64.rs b/src/roms/rom_bn254_64.rs
index f61b542..ce48907 100644
--- a/src/roms/rom_bn254_64.rs
+++ b/src/roms/rom_bn254_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use bn254::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use bn254::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // BN254 Modulus
 // Base Bits= 56
@@ -205,4 +205,4 @@ pub const SEXTIC_TWIST: SexticTwist = SexticTwist::D_TYPE;
 pub const ATE_BITS: usize = 66;
 pub const SIGN_OF_X: SignOfX = SignOfX::NEGATIVEX;
 pub const HASH_TYPE: usize = 32;
-pub const AESKEY: usize = 16;
\ No newline at end of file
+pub const AESKEY: usize = 16;
diff --git a/src/roms/rom_brainpool_32.rs b/src/roms/rom_brainpool_32.rs
index b788632..440c8e8 100644
--- a/src/roms/rom_brainpool_32.rs
+++ b/src/roms/rom_brainpool_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Note that the original curve has been transformed to an isomorphic curve with A=-3 */
 
-use brainpool::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use brainpool::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // brainpool Modulus
diff --git a/src/roms/rom_brainpool_64.rs b/src/roms/rom_brainpool_64.rs
index 8191561..804e479 100644
--- a/src/roms/rom_brainpool_64.rs
+++ b/src/roms/rom_brainpool_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Note that the original curve has been transformed to an isomorphic curve with A=-3 */
 
-use brainpool::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use brainpool::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // brainpool Modulus
diff --git a/src/roms/rom_c25519_32.rs b/src/roms/rom_c25519_32.rs
index 6da6a05..ca6d72c 100644
--- a/src/roms/rom_c25519_32.rs
+++ b/src/roms/rom_c25519_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Curve25519 Modulus
diff --git a/src/roms/rom_c25519_64.rs b/src/roms/rom_c25519_64.rs
index 9a8c59f..bf3eb59 100644
--- a/src/roms/rom_c25519_64.rs
+++ b/src/roms/rom_c25519_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // Curve25519 Modulus
diff --git a/src/roms/rom_c41417_32.rs b/src/roms/rom_c41417_32.rs
index a8330cb..bd177c8 100644
--- a/src/roms/rom_c41417_32.rs
+++ b/src/roms/rom_c41417_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c41417::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c41417::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // c41417 Modulus
diff --git a/src/roms/rom_c41417_64.rs b/src/roms/rom_c41417_64.rs
index 52b51b1..5c08731 100644
--- a/src/roms/rom_c41417_64.rs
+++ b/src/roms/rom_c41417_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use c41417::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use c41417::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // c41417 Modulus
diff --git a/src/roms/rom_ed25519_32.rs b/src/roms/rom_ed25519_32.rs
index be1d156..d92afa1 100644
--- a/src/roms/rom_ed25519_32.rs
+++ b/src/roms/rom_ed25519_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use ed25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use ed25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Curve25519 Modulus
diff --git a/src/roms/rom_ed25519_64.rs b/src/roms/rom_ed25519_64.rs
index cf23672..cf6f1f9 100644
--- a/src/roms/rom_ed25519_64.rs
+++ b/src/roms/rom_ed25519_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use ed25519::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use ed25519::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // Curve25519 Modulus
diff --git a/src/roms/rom_fp256bn_32.rs b/src/roms/rom_fp256bn_32.rs
index e3cabe1..85b145a 100644
--- a/src/roms/rom_fp256bn_32.rs
+++ b/src/roms/rom_fp256bn_32.rs
@@ -17,10 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp256bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
-
+use fp256bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_fp256bn_64.rs b/src/roms/rom_fp256bn_64.rs
index bde7639..77ffc40 100644
--- a/src/roms/rom_fp256bn_64.rs
+++ b/src/roms/rom_fp256bn_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp256bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp256bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // fp256bn Modulus
 // Base Bits= 56
diff --git a/src/roms/rom_fp512bn_32.rs b/src/roms/rom_fp512bn_32.rs
index cdc44af..18fefed 100644
--- a/src/roms/rom_fp512bn_32.rs
+++ b/src/roms/rom_fp512bn_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp512bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp512bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_fp512bn_64.rs b/src/roms/rom_fp512bn_64.rs
index 54d85c4..65779f7 100644
--- a/src/roms/rom_fp512bn_64.rs
+++ b/src/roms/rom_fp512bn_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use fp512bn::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use fp512bn::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 pub const MODULUS: [Chunk; NLEN] = [
diff --git a/src/roms/rom_goldilocks_32.rs b/src/roms/rom_goldilocks_32.rs
index 5d5f8bb..791423c 100644
--- a/src/roms/rom_goldilocks_32.rs
+++ b/src/roms/rom_goldilocks_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use goldilocks::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use goldilocks::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // Goldilocks modulus
diff --git a/src/roms/rom_goldilocks_64.rs b/src/roms/rom_goldilocks_64.rs
index d6cadf1..15e48b3 100644
--- a/src/roms/rom_goldilocks_64.rs
+++ b/src/roms/rom_goldilocks_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use goldilocks::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use goldilocks::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // Goldilocks modulus
diff --git a/src/roms/rom_hifive_32.rs b/src/roms/rom_hifive_32.rs
index cfa9f59..19ef026 100644
--- a/src/roms/rom_hifive_32.rs
+++ b/src/roms/rom_hifive_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use hifive::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use hifive::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
diff --git a/src/roms/rom_hifive_64.rs b/src/roms/rom_hifive_64.rs
index b2eebb9..b59e423 100644
--- a/src/roms/rom_hifive_64.rs
+++ b/src/roms/rom_hifive_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use hifive::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use hifive::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 
diff --git a/src/roms/rom_nist256_32.rs b/src/roms/rom_nist256_32.rs
index 6859da5..bed195e 100644
--- a/src/roms/rom_nist256_32.rs
+++ b/src/roms/rom_nist256_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use nist256::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist256::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 
@@ -45,8 +45,7 @@ pub const CURVE_B: [Chunk; NLEN] = [
     0xAC635D8, 0x5,
 ];
 pub const CURVE_ORDER: [Chunk; NLEN] = [
-    0xC632551, 0xB9CAC2F, 0x79E84F3, 0xFAADA71, 0xFFFBCE6, 0xFFFFFFF, 0xFFFFFF, 0x0, 0xFFFFFFF,
-    0xF,
+    0xC632551, 0xB9CAC2F, 0x79E84F3, 0xFAADA71, 0xFFFBCE6, 0xFFFFFFF, 0xFFFFFF, 0x0, 0xFFFFFFF, 0xF,
 ];
 pub const CURVE_GX: [Chunk; NLEN] = [
     0x898C296, 0xA13945D, 0xB33A0F4, 0x7D812DE, 0xF27703, 0xE563A44, 0x7F8BCE6, 0xE12C424,
diff --git a/src/roms/rom_nist256_64.rs b/src/roms/rom_nist256_64.rs
index 015bbb3..fa4fd8b 100644
--- a/src/roms/rom_nist256_64.rs
+++ b/src/roms/rom_nist256_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use nist256::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist256::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nist256 modulus
diff --git a/src/roms/rom_nist384_32.rs b/src/roms/rom_nist384_32.rs
index 48d7826..b025645 100644
--- a/src/roms/rom_nist384_32.rs
+++ b/src/roms/rom_nist384_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist384::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist384::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
diff --git a/src/roms/rom_nist384_64.rs b/src/roms/rom_nist384_64.rs
index f0f5c69..0c8b75c 100644
--- a/src/roms/rom_nist384_64.rs
+++ b/src/roms/rom_nist384_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist384::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist384::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 
@@ -44,7 +44,6 @@ pub const R2MODP: [Chunk; NLEN] = [
 ];
 pub const MCONST: Chunk = 0x100000001;
 
-
 // nist384 Curve
 pub const CURVE_COF_I: isize = 1;
 pub const CURVE_A: isize = -3;
diff --git a/src/roms/rom_nist521_32.rs b/src/roms/rom_nist521_32.rs
index 55cbf30..11d8c51 100644
--- a/src/roms/rom_nist521_32.rs
+++ b/src/roms/rom_nist521_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist521::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist521::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // nist521 Modulus
diff --git a/src/roms/rom_nist521_64.rs b/src/roms/rom_nist521_64.rs
index bf241b2..11bb5f2 100644
--- a/src/roms/rom_nist521_64.rs
+++ b/src/roms/rom_nist521_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nist521::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nist521::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nist521 Modulus
diff --git a/src/roms/rom_nums256e_32.rs b/src/roms/rom_nums256e_32.rs
index 45506bd..1f3b5c1 100644
--- a/src/roms/rom_nums256e_32.rs
+++ b/src/roms/rom_nums256e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 
@@ -68,4 +68,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
-
diff --git a/src/roms/rom_nums256e_64.rs b/src/roms/rom_nums256e_64.rs
index 4382924..bae331c 100644
--- a/src/roms/rom_nums256e_64.rs
+++ b/src/roms/rom_nums256e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums256 Modulus
@@ -77,4 +77,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 32;
 pub const AESKEY: usize = 16;
-
diff --git a/src/roms/rom_nums256w_32.rs b/src/roms/rom_nums256w_32.rs
index b768380..2e56c41 100644
--- a/src/roms/rom_nums256w_32.rs
+++ b/src/roms/rom_nums256w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // nums256 modulus
diff --git a/src/roms/rom_nums256w_64.rs b/src/roms/rom_nums256w_64.rs
index 5b5d491..711d7ec 100644
--- a/src/roms/rom_nums256w_64.rs
+++ b/src/roms/rom_nums256w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums256w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums256w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums256 Modulus
diff --git a/src/roms/rom_nums384e_32.rs b/src/roms/rom_nums384e_32.rs
index eaad1c8..888eff6 100644
--- a/src/roms/rom_nums384e_32.rs
+++ b/src/roms/rom_nums384e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums384 Modulus
@@ -71,4 +71,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384e_64.rs b/src/roms/rom_nums384e_64.rs
index 08d83c2..20ee825 100644
--- a/src/roms/rom_nums384e_64.rs
+++ b/src/roms/rom_nums384e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 // nums384 Modulus
@@ -92,4 +92,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384w_32.rs b/src/roms/rom_nums384w_32.rs
index 92181a6..f49379e 100644
--- a/src/roms/rom_nums384w_32.rs
+++ b/src/roms/rom_nums384w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums384 Modulus
@@ -71,4 +71,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums384w_64.rs b/src/roms/rom_nums384w_64.rs
index 3f51d94..f9e134b 100644
--- a/src/roms/rom_nums384w_64.rs
+++ b/src/roms/rom_nums384w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums384w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums384w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
 // nums384 Modulus
@@ -91,4 +91,3 @@ pub const ATE_BITS: usize = 0;
 pub const SIGN_OF_X: SignOfX = SignOfX::NOT;
 pub const HASH_TYPE: usize = 48;
 pub const AESKEY: usize = 24;
-
diff --git a/src/roms/rom_nums512e_32.rs b/src/roms/rom_nums512e_32.rs
index 8d53f9f..b14a0a1 100644
--- a/src/roms/rom_nums512e_32.rs
+++ b/src/roms/rom_nums512e_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums512 Modulus
diff --git a/src/roms/rom_nums512e_64.rs b/src/roms/rom_nums512e_64.rs
index 298f3cc..7e3fd98 100644
--- a/src/roms/rom_nums512e_64.rs
+++ b/src/roms/rom_nums512e_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512e::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512e::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nums512 Modulus
diff --git a/src/roms/rom_nums512w_32.rs b/src/roms/rom_nums512w_32.rs
index 785070c..c3e07c5 100644
--- a/src/roms/rom_nums512w_32.rs
+++ b/src/roms/rom_nums512w_32.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
 // nums512 Modulus
diff --git a/src/roms/rom_nums512w_64.rs b/src/roms/rom_nums512w_64.rs
index 6868c87..52ee250 100644
--- a/src/roms/rom_nums512w_64.rs
+++ b/src/roms/rom_nums512w_64.rs
@@ -17,9 +17,9 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use nums512w::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use nums512w::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 60
 // nums512 Modulus
diff --git a/src/roms/rom_rsa2048_32.rs b/src/roms/rom_rsa2048_32.rs
index 6dd06a6..29b5a60 100644
--- a/src/roms/rom_rsa2048_32.rs
+++ b/src/roms/rom_rsa2048_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 128;
 pub const BASEBITS: usize = 28;
-pub const FFLEN: usize = 2;
\ No newline at end of file
+pub const FFLEN: usize = 2;
diff --git a/src/roms/rom_rsa2048_64.rs b/src/roms/rom_rsa2048_64.rs
index be3ba0d..4caac22 100644
--- a/src/roms/rom_rsa2048_64.rs
+++ b/src/roms/rom_rsa2048_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 128;
 pub const BASEBITS: usize = 58;
-pub const FFLEN: usize = 2;
\ No newline at end of file
+pub const FFLEN: usize = 2;
diff --git a/src/roms/rom_rsa3072_32.rs b/src/roms/rom_rsa3072_32.rs
index d5622e2..62b929e 100644
--- a/src/roms/rom_rsa3072_32.rs
+++ b/src/roms/rom_rsa3072_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 48;
 pub const BASEBITS: usize = 28;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa3072_64.rs b/src/roms/rom_rsa3072_64.rs
index 4d1ed2b..ef66da7 100644
--- a/src/roms/rom_rsa3072_64.rs
+++ b/src/roms/rom_rsa3072_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 48;
 pub const BASEBITS: usize = 58;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa4096_32.rs b/src/roms/rom_rsa4096_32.rs
index 223cb7d..16ade15 100644
--- a/src/roms/rom_rsa4096_32.rs
+++ b/src/roms/rom_rsa4096_32.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 64;
 pub const BASEBITS: usize = 29;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_rsa4096_64.rs b/src/roms/rom_rsa4096_64.rs
index 77d3eb6..e8ebfc6 100644
--- a/src/roms/rom_rsa4096_64.rs
+++ b/src/roms/rom_rsa4096_64.rs
@@ -1,3 +1,3 @@
 pub const MODBYTES: usize = 64;
 pub const BASEBITS: usize = 60;
-pub const FFLEN: usize = 8;
\ No newline at end of file
+pub const FFLEN: usize = 8;
diff --git a/src/roms/rom_secp256k1_32.rs b/src/roms/rom_secp256k1_32.rs
index 94bbbaa..cb28327 100644
--- a/src/roms/rom_secp256k1_32.rs
+++ b/src/roms/rom_secp256k1_32.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use secp256k1::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use secp256k1::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 28
 // secp256k1 modulus
diff --git a/src/roms/rom_secp256k1_64.rs b/src/roms/rom_secp256k1_64.rs
index b22d875..43a3b91 100644
--- a/src/roms/rom_secp256k1_64.rs
+++ b/src/roms/rom_secp256k1_64.rs
@@ -19,9 +19,9 @@ under the License.
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-use secp256k1::big::NLEN;
 use super::super::arch::Chunk;
-use types::{ModType, CurveType, CurvePairingType, SexticTwist, SignOfX};
+use secp256k1::big::NLEN;
+use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 56
 
diff --git a/src/types.rs b/src/types.rs
index ea310d7..19b43d0 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -42,4 +42,3 @@ pub enum SignOfX {
     POSITIVEX,
     NEGATIVEX,
 }
-


[incubator-milagro-crypto-rust] 15/44: Duplicate tests in cargo test

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit de198225b44463a96b48e3bc6b5fc4494e86628d
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Fri Dec 13 17:18:41 2019 +1100

    Duplicate tests in cargo test
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 tests/test_all.rs | 1473 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/test_bls.rs |  190 +++++++
 tests/test_nhs.rs |   71 +++
 3 files changed, 1734 insertions(+)

diff --git a/tests/test_all.rs b/tests/test_all.rs
new file mode 100644
index 0000000..c543dac
--- /dev/null
+++ b/tests/test_all.rs
@@ -0,0 +1,1473 @@
+/*
+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.
+*/
+
+extern crate amcl;
+
+use std::io;
+use std::str;
+
+use amcl::rand::RAND;
+use amcl::types::CurveType;
+
+pub fn printbinary(array: &[u8]) {
+    for i in 0..array.len() {
+        print!("{:02X}", array[i])
+    }
+    println!("")
+}
+
+fn create_rng() -> RAND {
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut rng = RAND::new();
+    rng.clean();
+    for i in 0..100 {
+        raw[i] = i as u8
+    }
+
+    rng.seed(100, &raw);
+    rng
+}
+
+#[test]
+fn ecdh_ed25519() {
+    //use amcl::ed25519;
+    use amcl::ed25519::ecdh;
+    use amcl::ed25519::ecp;
+
+    let mut rng = create_rng();
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::Montgomery {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+#[test]
+fn ecdh_nist256() {
+    use amcl::nist256::ecdh;
+    use amcl::nist256::ecp;
+
+    let mut rng = create_rng();
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::Montgomery {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+#[test]
+fn ecdh_goldilocks() {
+    use amcl::goldilocks::ecdh;
+    use amcl::goldilocks::ecp;
+
+    let mut rng = create_rng();
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::Montgomery {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+#[test]
+fn mpin_bn254() {
+    use amcl::bn254::ecp;
+    use amcl::bn254::mpin;
+
+    let mut rng = create_rng();
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin::EFS;
+    const EGS: usize = mpin::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hcid);
+        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hsid);
+        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+#[test]
+fn mpin_bls383() {
+    //use amcl::bls383;
+    use amcl::bls383::ecp;
+    use amcl::bls383::mpin;
+
+    let mut rng = create_rng();
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin::EFS;
+    const EGS: usize = mpin::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hcid);
+        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hsid);
+        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+#[test]
+fn mpin_bls24() {
+    //use amcl::bls24;
+    use amcl::bls24::ecp;
+    use amcl::bls24::mpin192;
+
+    let mut rng = create_rng();
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin192::EFS;
+    const EGS: usize = mpin192::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 8 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut g2: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut f: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin192::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin192::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin192::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin192::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin192::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin192::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin192::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin192::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin192::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin192::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin192::hash_id(sha, &client_id, &mut hcid);
+        mpin192::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin192::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin192::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin192::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin192::hash_id(sha, &client_id, &mut hsid);
+        mpin192::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin192::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin192::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin192::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin192::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin192::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin192::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin192::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin192::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin192::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+#[test]
+fn mpin_bls48() {
+    //use amcl::bls48;
+    use amcl::bls48::ecp;
+    use amcl::bls48::mpin256;
+
+    let mut rng = create_rng();
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin256::EFS;
+    const EGS: usize = mpin256::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 16 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin256::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin256::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin256::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin256::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin256::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin256::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin256::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin256::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin256::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin256::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin256::hash_id(sha, &client_id, &mut hcid);
+        mpin256::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin256::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin256::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin256::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin256::hash_id(sha, &client_id, &mut hsid);
+        mpin256::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin256::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin256::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin256::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin256::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin256::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin256::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin256::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin256::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin256::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+#[test]
+fn rsa_2048() {
+    //use amcl::rsa2048;
+    use amcl::rsa2048::ff;
+    use amcl::rsa2048::rsa;
+
+    let mut rng = create_rng();
+
+    let sha = rsa::HASH_TYPE;
+    let message: &[u8] = b"Hello World\n";
+    const RFS: usize = rsa::RFS;
+
+    let mut pbc = rsa::new_public_key(ff::FFLEN);
+    let mut prv = rsa::new_private_key(ff::HFLEN);
+
+    let mut ml: [u8; RFS] = [0; RFS];
+    let mut ms: [u8; RFS] = [0; RFS];
+    let mut c: [u8; RFS] = [0; RFS];
+    let mut s: [u8; RFS] = [0; RFS];
+    let mut e: [u8; RFS] = [0; RFS];
+
+    println!("\nTesting RSA");
+    println!("Generating public/private key pair");
+    rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
+
+    println!("Encrypting test string\n");
+    rsa::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E  */
+
+    rsa::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */
+    print!("Ciphertext= 0x");
+    printbinary(&c);
+
+    println!("Decrypting test string");
+    rsa::decrypt(&prv, &c, &mut ml);
+    let mlen = rsa::oaep_decode(sha, None, &mut ml); /* OAEP decode message  */
+
+    let mess = str::from_utf8(&ml[0..mlen]).unwrap();
+    print!("{}", &mess);
+
+    println!("Signing message");
+    rsa::pkcs15(sha, message, &mut c);
+
+    rsa::decrypt(&prv, &c, &mut s); /* create signature in S */
+
+    print!("Signature= 0x");
+    printbinary(&s);
+
+    rsa::encrypt(&pbc, &s, &mut ms);
+
+    let mut cmp = true;
+    if c.len() != ms.len() {
+        cmp = false;
+    } else {
+        for j in 0..c.len() {
+            if c[j] != ms[j] {
+                cmp = false
+            }
+        }
+    }
+    if cmp {
+        println!("Signature is valid");
+    } else {
+        println!("Signature is INVALID");
+    }
+
+    rsa::private_key_kill(&mut prv);
+}
diff --git a/tests/test_bls.rs b/tests/test_bls.rs
new file mode 100644
index 0000000..20cf73b
--- /dev/null
+++ b/tests/test_bls.rs
@@ -0,0 +1,190 @@
+/*
+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.
+*/
+
+extern crate amcl;
+
+use amcl::rand::RAND;
+
+pub fn printbinary(array: &[u8]) {
+    for i in 0..array.len() {
+        print!("{:02X}", array[i])
+    }
+    println!("")
+}
+
+fn create_rng() -> RAND {
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut rng = RAND::new();
+    rng.clean();
+    for i in 0..100 {
+        raw[i] = i as u8
+    }
+
+    rng.seed(100, &raw);
+    rng
+}
+
+#[test]
+fn bls_bn254() {
+    use amcl::bn254::bls;
+
+    let mut rng = create_rng();
+
+    const BFS: usize = bls::BFS;
+    const BGS: usize = bls::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+#[test]
+fn bls_bls383() {
+    use amcl::bls383::bls;
+
+    let mut rng = create_rng();
+
+    const BFS: usize = bls::BFS;
+    const BGS: usize = bls::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+#[test]
+fn bls_bls24() {
+    use amcl::bls24::bls192;
+
+    let mut rng = create_rng();
+
+    const BFS: usize = bls192::BFS;
+    const BGS: usize = bls192::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 8 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls192::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls192::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls192::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+#[test]
+fn bls_bls48() {
+    use amcl::bls48::bls256;
+
+    let mut rng = create_rng();
+
+    const BFS: usize = bls256::BFS;
+    const BGS: usize = bls256::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 16 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls256::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls256::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls256::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
diff --git a/tests/test_nhs.rs b/tests/test_nhs.rs
new file mode 100644
index 0000000..f272291
--- /dev/null
+++ b/tests/test_nhs.rs
@@ -0,0 +1,71 @@
+/*
+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.
+*/
+
+// Tests NewHope Simple API
+
+// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe)
+
+extern crate amcl;
+
+use amcl::nhs;
+use amcl::rand::RAND;
+
+#[test]
+fn test_nhs() {
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut srng = RAND::new();
+    srng.clean();
+    for i in 0..100 {
+        raw[i] = (i + 1) as u8
+    }
+
+    srng.seed(100, &raw);
+
+    let mut crng = RAND::new();
+    crng.clean();
+    for i in 0..100 {
+        raw[i] = (i + 2) as u8
+    }
+
+    crng.seed(100, &raw);
+
+    let mut ss: [u8; 1792] = [0; 1792];
+    let mut sb: [u8; 1824] = [0; 1824];
+    let mut uc: [u8; 2176] = [0; 2176];
+
+    let mut keya: [u8; 32] = [0; 32];
+    let mut keyb: [u8; 32] = [0; 32];
+
+    nhs::server_1(&mut srng, &mut sb, &mut ss);
+
+    nhs::client(&mut crng, &sb, &mut uc, &mut keyb);
+
+    nhs::server_2(&ss, &uc, &mut keya);
+
+    for i in 0..keya.len() {
+        print!("{:02X}", keya[i]);
+    }
+    println!("");
+
+    for i in 0..keyb.len() {
+        print!("{:02X}", keyb[i]);
+    }
+    println!("");
+}


[incubator-milagro-crypto-rust] 17/44: Merge pull request #8 from kirk-baird/bn256CX-bug

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 0104d600beaf1c0ee39284cb08195b86fb8d4018
Merge: 881a669 032e9f9
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Fri Dec 13 09:10:54 2019 +0000

    Merge pull request #8 from kirk-baird/bn256CX-bug
    
    Fix minor bug with compilation

 src/roms/rom_bn254CX_64.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[incubator-milagro-crypto-rust] 41/44: Fix ecp tostring

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit aac35764784b22fd1235051337a0290c64ca46a4
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Mon May 4 16:40:08 2020 +1000

    Fix ecp tostring
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/ecp.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ecp.rs b/src/ecp.rs
index 77ce689..49a478e 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -431,6 +431,7 @@ impl ECP {
     /* convert to hex string */
     pub fn tostring(&self) -> String {
         let W = self.clone();
+        W.affine();
         if W.is_infinity() {
             return String::from("infinity");
         }


[incubator-milagro-crypto-rust] 18/44: Merge pull request #9 from kirk-baird/test-improvements

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit f54d09057093063a460a2626040a8b273db77ce1
Merge: 0104d60 de19822
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Fri Dec 13 16:33:14 2019 +0000

    Merge pull request #9 from kirk-baird/test-improvements
    
    [WIP] Fix tests and benchmarks

 .gitignore                      |   4 +
 BenchtestALL.rs                 |  73 ++++++++-------
 TestALL.rs                      |   6 +-
 readme.md                       |   2 +-
 TestALL.rs => tests/test_all.rs |  86 ++++++++++--------
 tests/test_bls.rs               | 190 ++++++++++++++++++++++++++++++++++++++++
 tests/test_nhs.rs               |  71 +++++++++++++++
 7 files changed, 354 insertions(+), 78 deletions(-)


[incubator-milagro-crypto-rust] 22/44: Merge pull request #11 from sigp/fp-display

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit dbd1bd1d93e6bfe2ddf36b1cc71581c909fd80a0
Merge: 87a97b6 a8d0330
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Thu Jan 23 12:32:44 2020 +0000

    Merge pull request #11 from sigp/fp-display
    
    Fix issue displaying FP values

 src/fp.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)


[incubator-milagro-crypto-rust] 24/44: Merge pull request #12 from sigp/mutability

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit e63b8f3774da6734669829fcbc0b0551cb1158cf
Merge: dbd1bd1 dfdf99b
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Fri Jan 24 09:13:20 2020 +0000

    Merge pull request #12 from sigp/mutability
    
    Tidy up mutability requirements

 src/big.rs  |  6 +++---
 src/fp.rs   | 12 +++++-------
 src/fp12.rs | 24 +++++++++---------------
 src/fp16.rs |  4 ++--
 src/fp2.rs  |  6 +++---
 src/fp24.rs | 16 +++++-----------
 src/fp4.rs  |  4 ++--
 src/fp48.rs | 16 +++++-----------
 src/fp8.rs  |  4 ++--
 9 files changed, 36 insertions(+), 56 deletions(-)


[incubator-milagro-crypto-rust] 40/44: Update to hash to curve version 7

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit cc1b6e87e401455ff3703e0fa31c653930b9f149
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Mon May 4 16:18:29 2020 +1000

    Update to hash to curve version 7
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/bls381.rs                                      | 132 ++-------------------
 src/fp.rs                                          |  21 ++--
 src/fp2.rs                                         |  17 ++-
 src/hash256.rs                                     |  10 +-
 src/hash384.rs                                     |  10 +-
 src/hash512.rs                                     |  10 +-
 src/hash_to_curve.rs                               |  87 ++++++++------
 src/roms/rom_bls381g1_32.rs                        |   4 +-
 src/roms/rom_bls381g1_64.rs                        |   6 +-
 src/roms/rom_bls381g2_32.rs                        |   6 +-
 src/roms/rom_bls381g2_64.rs                        |   6 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 src/test_utils/test_vector_structs.rs              |   1 -
 20 files changed, 319 insertions(+), 431 deletions(-)

diff --git a/src/bls381.rs b/src/bls381.rs
index f03576d..b6a11ea 100644
--- a/src/bls381.rs
+++ b/src/bls381.rs
@@ -29,7 +29,9 @@ use super::ecp::ECP;
 use super::ecp2::ECP2;
 use super::fp::FP;
 use super::fp2::FP2;
-use super::hash_to_curve::*;
+use super::hash_to_curve::{
+    hash_to_field_fp, hash_to_field_fp2, simplified_swu_fp, simplified_swu_fp2,
+};
 use super::pair;
 use super::rom::*;
 
@@ -106,7 +108,7 @@ pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
 /// Hash to Curve
 ///
 /// Takes a message as input and converts it to a Curve Point
-/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-3
 pub fn hash_to_curve_g1(msg: &[u8]) -> ECP {
     let u =
         hash_to_field_fp(msg, 2, DST).expect("hash to field should not fail for given parameters");
@@ -120,7 +122,8 @@ pub fn hash_to_curve_g1(msg: &[u8]) -> ECP {
 // Simplified SWU for Pairing-Friendly Curves
 //
 // Take a field point and map it to a Curve Point.
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+// SSWU - https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-6.6.2
+// ISO11 - https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#appendix-C.2
 fn map_to_curve_g1(u: FP) -> ECP {
     let (x, y) = simplified_swu_fp(u);
     iso11_to_ecp(&x, &y)
@@ -132,7 +135,7 @@ fn map_to_curve_g1(u: FP) -> ECP {
 /// Hash to Curve
 ///
 /// Takes a message as input and converts it to a Curve Point
-/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-3
 pub fn hash_to_curve_g2(msg: &[u8]) -> ECP2 {
     let u =
         hash_to_field_fp2(msg, 2, DST).expect("hash to field should not fail for given parameters");
@@ -146,7 +149,8 @@ pub fn hash_to_curve_g2(msg: &[u8]) -> ECP2 {
 // Simplified SWU for Pairing-Friendly Curves
 //
 // Take a field point and map it to a Curve Point.
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+// SSWU - https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-6.6.2
+// ISO3 - https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#appendix-C.3
 fn map_to_curve_g2(u: FP2) -> ECP2 {
     let (x, y) = simplified_swu_fp2(u);
     iso3_to_ecp2(&x, &y)
@@ -157,124 +161,6 @@ mod tests {
     use super::*;
     use crate::test_utils::*;
 
-    // The following tests were exported from
-    // https://github.com/kwantam/bls_sigs_ref/tree/master/python-impl
-    // Format: [(input, output)]
-    // input: [u0_a, u0_b, u1_a, u1_b]
-    // output: [x_a, x_b, y_a, y_b]
-    pub const TESTS: [([&str; 4], [&str; 4]); 4] =
-        [
-            // Test 0
-            (
-                // Input
-                [
-                    "004ad233c619209060e40059b81e4c1f92796b05aa1bc6358d65e53dc0d657dfbc713d4030b0b6d9234a6634fd1944e7",
-                    "0e2386c82713441bc3b06a460bd81850f4bf376ea89c80b18c0881e855c58dc8e83b2fd23af983f4786508e30c42af01",
-                    "08a6a75e0a8d32f1e096f29047ea879dd34a5504218d7ce92c32c244786822fb73fbf708d167ad86537468249ec6df48",
-                    "07016d0e5e13cd65780042c6f7b4c74ae1c58da438c99582696818b5c229895b893318dcb87d2a65e557d4ebeb408b70"
-                ],
-                // Output
-                [
-                    "04861c41efcc5fc56e62273692b48da25d950d2a0aaffb34eff80e8dbdc2d41ca38555ceb8554368436aea47d16056b5",
-                    "09db5217528c55d982cf05fc54242bdcd25f1ebb73372e00e16d8e0f19dc3aeabdeef2d42d693405a04c37d60961526a",
-                    "177d05b95e7879a7ddbd83c15114b5a4e9846fde72b2263072dc9e60db548ccbadaacb92cc4952d4f47425fe3c5e0172",
-                    "0fc82c99b928ed9df12a74f9215c3df8ae1e9a3fa54c00897889296890b23a0edcbb9653f9170bf715f882b35c0b4647"
-                ]
-            ),
-            // Test 1
-            (
-                // Input
-                [
-                    "083c57b3ee2ecba5bbf874bb03897827f949096efceea00f002c979de7e5e9429fcf1f3323d4c8c548cd6f8ecb1a5c1d",
-                    "0344fdfe8e1401867a275b3bef7e6ec52450968ab8a1293938fe3d5712dda67c85afeb91d85ab83fcdbebba4dc913e44",
-                    "1361b5ee134c6bee4e287e63f852b6e48546dcf0684af7cf3e7653a3427a609f769ce4d9d99a638b6ae432130fa43104",
-                    "18425b12c2ab5de136eb493b88ca950a45cab942505b5dd59a8b3ae8ec34c40ada65ff2719b1fcda9769fb22882002f9"
-                ],
-                // Output
-                [
-                    "15f7a5c1168ad5ab67ff285c80fa8dd932ca88d9f8b3803c6c7b1f525d2dd5d01f2418259ae167c17c514d55e4707ddb",
-                    "04378269c7364a6cefcdafdb87b004d3ebf6853f46687e46f29f23196d47a176c6f858be34c9f9a3608c74e804f6c686",
-                    "023d9d46abe82bc0ac7c104d9519c037ff72893b8371d72ab92378f60a2361d7171df6b33500828c88923ddb1aab7fa5",
-                    "1015adfeece3613836bf82541ea560c701e197b3d081e2c242b217d809f4ac0ca787b402537a66c0d1f6b76e1b19e94b"
-                ]
-            ),
-            // Test 2
-            (
-                // Input
-                [
-                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
-                ],
-                // Output
-                [
-                    "19da1b4d47efeeb154f8968b43da2125376e0999ba722141419b03fd857490562fa42a5d0973956d1932dd20c1e0a284",
-                    "18426da25dadd359adfda64fbaddac4414da2a841cb467935289877db450fac424361efb2e7fb141b7b98e6b2f888aef",
-                    "0c2f8d431770d9be9b087c36fc5b66bb83ce6372669f48294193ef646105e0f21d17b134e7d1ad9c18f54b81f6a3707b",
-                    "03257c3be77016e69b75905a97871008a6dfd2e324a6748c48d3304380156987bd0905991824936fcfe34ab25c3b6caa"
-                ]
-            ),
-            // Test 3
-            (
-                // Input
-                [
-                    "05495a3dfa360cb809c1904530db1986aea4bf356e634b40b51e0ee5fcb6cb75085a72a0626873a426470067627c6418",
-                    "11e63b587bedb59c2140518565950bdf881d75c0cccdcedcd9f4b71f2cfede3e5fdbe0261b015562d5edeaa11b7b2b76",
-                    "116c87bbeece66871eb6c2a51bc4327b10ffe470b49c28ef8eef624da766caa2cc9ff6c7042b26b2efd3404f5a81a140",
-                    "010450a90c17ba2997b645ef340fb5b207d6c915b34a93d93e75ee905d6d203d4aac046e10bd4d94a215604ade7afa8e"
-                ],
-                // Output
-                [
-                    "0f1614a6e91c3e00799098fded2f2cfd72cb585cbdaec41b478509913c6772266a764f00b24a7f99607948a4b69b4d8f",
-                    "13ca2148705ca7ba49c92ab8985d7babcc8afc6bf8e397fb829f5fe3f49e51c41332ba4389f5ba66667310b22bea16c9",
-                    "026a743ee00eec8c7ef63351f4a3b26b2f029c10130385efc56ce53d0788db32ff5296ab77f9c389bd196cce8fc1e888",
-                    "0d458d80897e922f3e7e15cfa66a0d3645d95788bddb7478af3f1b5ca662c348b0e9ffdb88fabfdb74f103fea0c2d793"
-                ]
-            )
-        ];
-
-    #[test]
-    fn test_map_to_curve_g2() {
-        // Only run when signatures are on G2
-        if BLS_SIG_G1 {
-            return;
-        }
-
-        for test in &TESTS {
-            // Input u0 and u1
-            let a = Big::frombytes(&hex::decode(test.0[0]).unwrap());
-            let b = Big::frombytes(&hex::decode(test.0[1]).unwrap());
-            let u0 = FP2::new_bigs(a, b);
-            let a = Big::frombytes(&hex::decode(test.0[2]).unwrap());
-            let b = Big::frombytes(&hex::decode(test.0[3]).unwrap());
-            let u1 = FP2::new_bigs(a, b);
-
-            // Map to Curve
-            let (iso3_0_x, iso3_0_y) = simplified_swu_fp2(u0);
-            let (iso3_1_x, iso3_1_y) = simplified_swu_fp2(u1);
-
-            // 3-Isogeny Map
-            let mut q0 = iso3_to_ecp2(&iso3_0_x, &iso3_0_y);
-            let q1 = iso3_to_ecp2(&iso3_1_x, &iso3_1_y);
-            q0.add(&q1);
-
-            // Clear Cofactor
-            q0.clear_cofactor();
-
-            // Check expected values
-            let a = Big::frombytes(&hex::decode(test.1[0]).unwrap());
-            let b = Big::frombytes(&hex::decode(test.1[1]).unwrap());
-            let check_x = FP2::new_bigs(a, b);
-            let a = Big::frombytes(&hex::decode(test.1[2]).unwrap());
-            let b = Big::frombytes(&hex::decode(test.1[3]).unwrap());
-            let check_y = FP2::new_bigs(a, b);
-            let check_e = ECP2::new_fp2s(check_x, check_y);
-
-            assert!(q0.equals(&check_e));
-        }
-    }
-
     #[test]
     #[cfg(feature = "bls381g2")]
     fn test_hash_to_curve_g2() {
diff --git a/src/fp.rs b/src/fp.rs
index 058d7a4..94e1a64 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -221,7 +221,7 @@ impl FP {
         self.xes = 1;
     }
 
-    /// test this=0?
+    /// Check if self is 0
     pub fn iszilch(&self) -> bool {
         let mut a = self.clone();
         a.reduce();
@@ -694,12 +694,19 @@ impl FP {
         return w.jacobi(&p);
     }
 
-    /// Checks if the field value is negative
+    /// Checks sign of a field element
     ///
-    /// Negative if a > -a
-    pub fn is_neg(&mut self) -> bool {
-        let mut neg_a = self.clone();
-        neg_a.neg();
-        Big::comp(&self.redc(), &neg_a.redc()) > 0
+    /// true if Negative, if a % 2 == 1
+    /// false if Positive, if a % 2 == 0
+    ///
+    /// Not constant time.
+    /// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-4.1
+    pub fn sgn0(&self) -> bool {
+        let x = self.redc();
+        if x.parity() == 0 {
+            false
+        } else {
+            true
+        }
     }
 }
diff --git a/src/fp2.rs b/src/fp2.rs
index 82a10a9..3b94761 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -401,11 +401,18 @@ impl FP2 {
         self.b.sub(&b);
     }
 
-    // b > -b OR if b is 0 then a > -a
-    pub fn is_neg(&mut self) -> bool {
-        if self.b.iszilch() {
-            return self.a.is_neg();
+    /// Checks sign of a field element
+    ///
+    /// true if Negative
+    /// false if Positive
+    ///
+    /// Not constant time.
+    /// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-4.1
+    pub fn sgn0(&self) -> bool {
+        if self.a.iszilch() {
+            self.b.sgn0()
+        } else {
+            self.a.sgn0()
         }
-        self.b.is_neg()
     }
 }
diff --git a/src/hash256.rs b/src/hash256.rs
index 5860524..f8c9b6a 100644
--- a/src/hash256.rs
+++ b/src/hash256.rs
@@ -38,13 +38,13 @@ const HASH256_K: [u32; 64] = [
 ];
 
 /// The block size of each round.
-const BLOCK_SIZE: usize = 64;
-/// Ipad Byte
+pub const BLOCK_SIZE: usize = 64;
+/// Hash Length in Bytes
+pub const HASH_BYTES: usize = 32;
+// Ipad Byte
 const IPAD_BYTE: u8 = 0x36;
-/// Opad Byte
+// Opad Byte
 const OPAD_BYTE: u8 = 0x5c;
-/// Hash Length in Bytes
-const HASH_BYTES: usize = 32;
 
 pub struct HASH256 {
     length: [u32; 2],
diff --git a/src/hash384.rs b/src/hash384.rs
index 5c349a1..bc57b24 100644
--- a/src/hash384.rs
+++ b/src/hash384.rs
@@ -110,13 +110,13 @@ const HASH384_K: [u64; 80] = [
 ];
 
 /// The block size of each round.
-const BLOCK_SIZE: usize = 128;
-/// Ipad Byte
+pub const BLOCK_SIZE: usize = 128;
+/// Hash Length in Bytes
+pub const HASH_BYTES: usize = 48;
+// Ipad Byte
 const IPAD_BYTE: u8 = 0x36;
-/// Opad Byte
+// Opad Byte
 const OPAD_BYTE: u8 = 0x5c;
-/// Hash Length in Bytes
-const HASH_BYTES: usize = 48;
 
 pub struct HASH384 {
     length: [u64; 2],
diff --git a/src/hash512.rs b/src/hash512.rs
index 34970a7..5244475 100644
--- a/src/hash512.rs
+++ b/src/hash512.rs
@@ -110,13 +110,13 @@ const HASH512_K: [u64; 80] = [
 ];
 
 /// The block size of each round.
-const BLOCK_SIZE: usize = 128;
-/// Ipad Byte
+pub const BLOCK_SIZE: usize = 128;
+/// Hash Length in Bytes
+pub const HASH_BYTES: usize = 64;
+// Ipad Byte
 const IPAD_BYTE: u8 = 0x36;
-/// Opad Byte
+// Opad Byte
 const OPAD_BYTE: u8 = 0x5c;
-/// Hash Length in Bytes
-const HASH_BYTES: usize = 64;
 
 pub struct HASH512 {
     length: [u64; 2],
diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs
index 8adf370..a7628b9 100644
--- a/src/hash_to_curve.rs
+++ b/src/hash_to_curve.rs
@@ -3,14 +3,13 @@ use super::dbig::DBig;
 use super::fp::FP;
 use super::fp2::FP2;
 use super::rom::{
-    HASH_ALGORITHM, HASH_TYPE, L, MODULUS, SSWU_A1, SSWU_A2, SSWU_B1, SSWU_B2, SSWU_Z1, SSWU_Z2,
-    Z_PAD,
+    HASH_ALGORITHM, L, MODULUS, SSWU_A1, SSWU_A2, SSWU_B1, SSWU_B2, SSWU_Z1, SSWU_Z2,
 };
 
 use errors::AmclError;
-use hash256::HASH256;
-use hash384::HASH384;
-use hash512::HASH512;
+use hash256::{BLOCK_SIZE as SHA256_BLOCK_SIZE, HASH256, HASH_BYTES as SHA256_HASH_BYTES};
+use hash384::{BLOCK_SIZE as SHA384_BLOCK_SIZE, HASH384, HASH_BYTES as SHA384_HASH_BYTES};
+use hash512::{BLOCK_SIZE as SHA512_BLOCK_SIZE, HASH512, HASH_BYTES as SHA512_HASH_BYTES};
 
 /// Oversized DST padding
 pub const OVERSIZED_DST: &[u8] = b"H2C-OVERSIZE-DST-";
@@ -22,6 +21,24 @@ pub enum HashAlgorithm {
     Sha512,
 }
 
+impl HashAlgorithm {
+    pub fn length(&self) -> usize {
+        match self {
+            HashAlgorithm::Sha256 => SHA256_HASH_BYTES,
+            HashAlgorithm::Sha384 => SHA384_HASH_BYTES,
+            HashAlgorithm::Sha512 => SHA512_HASH_BYTES,
+        }
+    }
+
+    pub fn block_size(&self) -> usize {
+        match self {
+            HashAlgorithm::Sha256 => SHA256_BLOCK_SIZE,
+            HashAlgorithm::Sha384 => SHA384_BLOCK_SIZE,
+            HashAlgorithm::Sha512 => SHA512_BLOCK_SIZE,
+        }
+    }
+}
+
 /// Hash a message
 pub fn hash(msg: &[u8], hash_function: HashAlgorithm) -> Vec<u8> {
     match hash_function {
@@ -49,13 +66,13 @@ pub fn hash(msg: &[u8], hash_function: HashAlgorithm) -> Vec<u8> {
 // Hash To Field - Fp
 //
 // Take a message as bytes and convert it to a Field Point
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-5.2
 pub fn hash_to_field_fp(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP>, AmclError> {
     let m = 1;
     let p = Big::new_ints(&MODULUS);
 
     let len_in_bytes = count * m * L;
-    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst)?;
 
     let mut u: Vec<FP> = Vec::with_capacity(count as usize);
     for i in 0..count as usize {
@@ -70,14 +87,14 @@ pub fn hash_to_field_fp(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP>,
 // Hash To Field - Fp2
 //
 // Take a message as bytes and convert it to a vector of Field Points with extension degree 2.
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-5.2
 pub fn hash_to_field_fp2(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP2>, AmclError> {
     let m = 2;
     let p = Big::new_ints(&MODULUS);
 
     let len_in_bytes = count * m * L;
 
-    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst)?;
 
     let mut u: Vec<FP2> = Vec::with_capacity(count as usize);
     for i in 0..count as usize {
@@ -96,33 +113,28 @@ pub fn hash_to_field_fp2(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP2
 // Expand Message XMD
 //
 // Take a message and convert it to pseudo random bytes of specified length
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.3.1
-pub fn expand_message_xmd(
-    msg: &[u8],
-    len_in_bytes: usize,
-    dst: &[u8],
-    hash_algorithm: HashAlgorithm,
-) -> Result<Vec<u8>, AmclError> {
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-5.3.1
+fn expand_message_xmd(msg: &[u8], len_in_bytes: usize, dst: &[u8]) -> Result<Vec<u8>, AmclError> {
     // ell = ceiling(len_in_bytes / b_in_bytes)
-    let ell = (len_in_bytes + HASH_TYPE - 1) / HASH_TYPE;
+    let ell = (len_in_bytes + HASH_ALGORITHM.length() - 1) / HASH_ALGORITHM.length();
 
     // Error if length of output less than 255 bytes
-    if ell >= 255 {
+    if ell > 255 {
         return Err(AmclError::HashToFieldError);
     }
 
     // Create DST prime as (dst.len() || dst)
-    let dst_prime = if dst.len() > 256 {
+    let dst_prime = if dst.len() > 255 {
         // DST too long, shorten to H("H2C-OVERSIZE-DST-" || dst)
         let mut tmp = OVERSIZED_DST.to_vec();
         tmp.extend_from_slice(dst);
-        let mut prime = vec![32u8; 1];
-        prime.append(&mut hash(&tmp, hash_algorithm));
-        prime
+        let mut tmp = hash(&tmp, HASH_ALGORITHM).to_vec();
+        tmp.push(HASH_ALGORITHM.length() as u8);
+        tmp
     } else {
-        // DST correct size, prepend length as a single byte
-        let mut prime = vec![dst.len() as u8; 1];
-        prime.extend_from_slice(dst);
+        // DST correct size, append length as a single byte
+        let mut prime = dst.to_vec();
+        prime.push(dst.len() as u8);
         prime
     };
 
@@ -130,19 +142,20 @@ pub fn expand_message_xmd(
     let mut b: Vec<Vec<u8>> = vec![vec![]; 2];
 
     // Set b[0] to H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime)
-    let mut tmp = Z_PAD.to_vec();
+    // l_i_b_str = I2OSP(len_in_bytes, 2)
+    let mut tmp = vec![0; HASH_ALGORITHM.block_size()];
     tmp.extend_from_slice(msg);
-    let l_i_b_str: &[u8] = &(len_in_bytes as u16).to_be_bytes();
-    tmp.extend_from_slice(l_i_b_str);
+    let l_i_b_str: [u8; 2] = (len_in_bytes as u16).to_be_bytes();
+    tmp.extend_from_slice(&l_i_b_str);
     tmp.push(0u8);
     tmp.extend_from_slice(&dst_prime);
-    b[0] = hash(&tmp, hash_algorithm);
+    b[0] = hash(&tmp, HASH_ALGORITHM);
 
     // Set b[1] to H(b_0 || I2OSP(1, 1) || DST_prime)
     tmp = b[0].clone();
     tmp.push(1u8);
     tmp.extend_from_slice(&dst_prime);
-    b[1] = hash(&tmp, hash_algorithm);
+    b[1] = hash(&tmp, HASH_ALGORITHM);
 
     pseudo_random_bytes.extend_from_slice(&b[1]);
 
@@ -158,7 +171,7 @@ pub fn expand_message_xmd(
             .collect();
         tmp.push(i as u8); // i < 256
         tmp.extend_from_slice(&dst_prime);
-        b.push(hash(&tmp, hash_algorithm));
+        b.push(hash(&tmp, HASH_ALGORITHM));
 
         pseudo_random_bytes.extend_from_slice(&b[i]);
     }
@@ -170,12 +183,11 @@ pub fn expand_message_xmd(
 // Simplified Shallue-van de Woestijne-Ulas Method - Fp
 //
 // Returns projectives as (XZ, YZ, Z)
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-6.6.2
 pub fn simplified_swu_fp(u: FP) -> (FP, FP) {
     // tmp1 = Z * u^2
     // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
     let mut tmp1 = u.clone();
-    let is_neg_u = tmp1.is_neg();
     tmp1.sqr();
     tmp1.mul(&SSWU_Z1);
     let mut tv1 = tmp1.clone();
@@ -233,7 +245,7 @@ pub fn simplified_swu_fp(u: FP) -> (FP, FP) {
     }
 
     // Negate y if y and t are opposite in sign
-    if is_neg_u != y.is_neg() {
+    if u.sgn0() != y.sgn0() {
         y.neg();
     }
 
@@ -243,12 +255,11 @@ pub fn simplified_swu_fp(u: FP) -> (FP, FP) {
 // Simplified Shallue-van de Woestijne-Ulas Method - Fp2
 //
 // Returns projectives as (X, Y)
-// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-07#section-6.6.2
 pub fn simplified_swu_fp2(u: FP2) -> (FP2, FP2) {
     // tmp1 = Z * u^2
     // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
     let mut tmp1 = u.clone();
-    let is_neg_u = tmp1.is_neg();
     tmp1.sqr();
     tmp1.mul(&SSWU_Z2);
     let mut tv1 = tmp1.clone();
@@ -284,7 +295,7 @@ pub fn simplified_swu_fp2(u: FP2) -> (FP2, FP2) {
     // y = sqrt(gx)
     let mut y = gx.clone();
     if !y.sqrt() {
-        // x = x * Z^2 * u
+        // x = x * Z * u^2
         x.mul(&tmp1);
 
         // gx = x^3 + A * x + B
@@ -299,7 +310,7 @@ pub fn simplified_swu_fp2(u: FP2) -> (FP2, FP2) {
     }
 
     // Negate y if y and t are opposite in sign
-    if is_neg_u != y.is_neg() {
+    if u.sgn0() != y.sgn0() {
         y.neg();
     }
 
diff --git a/src/roms/rom_bls381g1_32.rs b/src/roms/rom_bls381g1_32.rs
index 0add498..06b6b38 100644
--- a/src/roms/rom_bls381g1_32.rs
+++ b/src/roms/rom_bls381g1_32.rs
@@ -216,14 +216,12 @@ pub const AESKEY: usize = 16;
 pub const BLS_SIG_G1: bool = true;
 
 // BLS Standard Constants
-/// L = ceil(ceil(log2(Q) + 128) / 8)
+/// L = ceil(ceil(log2(p) + 128) / 8)
 pub const L: usize = 64;
 /// Hash to Curve Suite
 pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
 /// Domain Separation Tag
 pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
-/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
-pub const Z_PAD: [u8; 64] = [0u8; 64];
 
 lazy_static! {
     // G1 h_eff
diff --git a/src/roms/rom_bls381g1_64.rs b/src/roms/rom_bls381g1_64.rs
index 7032be0..f7b73db 100644
--- a/src/roms/rom_bls381g1_64.rs
+++ b/src/roms/rom_bls381g1_64.rs
@@ -218,16 +218,12 @@ pub const AESKEY: usize = 16;
 pub const BLS_SIG_G1: bool = true;
 
 // BLS Standard Constants
-/// L = ceil(ceil(log2(Q) + 128) / 8)
+/// L = ceil(ceil(log2(p) + 128) / 8)
 pub const L: usize = 64;
-/// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
-pub const B_IN_BYTES: usize = 32;
 /// Hash to Curve Suite
 pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
 /// Domain Separation Tag
 pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
-/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
-pub const Z_PAD: [u8; 64] = [0u8; 64];
 
 lazy_static! {
     // G1 h_eff
diff --git a/src/roms/rom_bls381g2_32.rs b/src/roms/rom_bls381g2_32.rs
index 538e470..51249ee 100644
--- a/src/roms/rom_bls381g2_32.rs
+++ b/src/roms/rom_bls381g2_32.rs
@@ -216,16 +216,12 @@ pub const AESKEY: usize = 16;
 pub const BLS_SIG_G1: bool = false;
 
 // BLS Standard Constants
-/// L = ceil(ceil(log2(Q) + 128) / 8)
+/// L = ceil(ceil(log2(p) + 128) / 8)
 pub const L: usize = 64;
-/// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
-pub const B_IN_BYTES: usize = 32;
 /// Hash to Curve Suite
 pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
 /// Domain Separation Tag
 pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
-/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
-pub const Z_PAD: [u8; 64] = [0u8; 64];
 
 lazy_static! {
     // G1 h_eff
diff --git a/src/roms/rom_bls381g2_64.rs b/src/roms/rom_bls381g2_64.rs
index 5b8968a..0e05c89 100644
--- a/src/roms/rom_bls381g2_64.rs
+++ b/src/roms/rom_bls381g2_64.rs
@@ -218,16 +218,12 @@ pub const AESKEY: usize = 16;
 pub const BLS_SIG_G1: bool = false;
 
 // BLS Standard Constants
-/// L = ceil(ceil(log2(Q) + 128) / 8)
+/// L = ceil(ceil(log2(p) + 128) / 8)
 pub const L: usize = 64;
 /// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
-pub const B_IN_BYTES: usize = 32;
-/// Hash to Curve Suite
 pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
 /// Domain Separation Tag
 pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
-/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
-pub const Z_PAD: [u8; 64] = [0u8; 64];
 
 lazy_static! {
     // G1 h_eff
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
index cba0e19..adab80e 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
@@ -12,65 +12,64 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SSWU",
-    "sgn0": "sgn0_be"
+    "name": "SSWU"
   },
   "randomOracle": false,
   "vectors": [
     {
       "P": {
-        "x": "0x115281bd55a4103f31c8b12000d98149598b72e5da14e953277def263a24bc2e9fd8fa151df73ea3800f9c8cbb9b245c",
-        "y": "0x0796506faf9edbf1957ba8d667a079cab0d3a37e302e5132bd25665b66b26ea8556a0cfb92d6ae2c4890df0029b455ce"
+        "x": "0x1223effdbb2d38152495a864d78eee14cb0992d89a241707abb03819a91a6d2fd65854ab9a69e9aacb0cbebfd490732c",
+        "y": "0x0f925d61e0b235ecd945cbf0309291878df0d06e5d80d6b84aa4ff3e00633b26f9a7cb3523ef737d90e6d71e8b98b2d5"
       },
       "Q": {
-        "x": "0x0dddf77f320e7848a457358ab8d3b84cbaf19307be26b91a10c211651691cd736b1f59d77aed3954f857f108d6966f5b",
-        "y": "0x0450ab32020649f22a2fca166a1d8a59d4c93f1eb078a4bedd6c48027b9933507a2a8ae4d915305f58ede781283325a9"
+        "x": "0x062bef7110b5a85023eb7766d8b923f654cb65ef23acc571de3266e46fb87c2efe7ed2b07f7d078dcb0970f30545523d",
+        "y": "0x095aaedd31b4bfecd080de37112afa90db9bb15e3798b122f8b7c93ff7984b8a41233d5ee994a4fceae1b8162dcc0cac"
       },
       "msg": "",
       "u": [
-        "0x0ccb6bda9b602ab82aae21c0291623e2f639648a6ada1c76d8ffb664130fd18d98a2cc6160624148827a9726678e7cd4"
+        "0x07fdf49ea58e96015d61f6b5c9d1c8f277146a533ae7fbca2a8ef4c41055cd961fbc6e26979b5554e4b4f22330c0e16d"
       ]
     },
     {
       "P": {
-        "x": "0x04a7a63d24439ade3cd16eaab22583c95b061136bd5013cf109d92983f902c31f49c95cbeb97222577e571e97a68a32e",
-        "y": "0x09a8aa8d6e4b409bbe9a6976c016688269024d6e9d378ed25e8b4986194511f479228fa011ec88b8f4c57a621fc12187"
+        "x": "0x179d3fd0b4fb1da43aad06cea1fb3f828806ddb1b1fa9424b1e3944dfdbab6e763c42636404017da03099af0dcca0fd6",
+        "y": "0x0d037cb1c6d495c0f5f22b061d23f1be3d7fe64d3c6820cfcd99b6b36fa69f7b4c1f4addba2ae7aa46fb25901ab483e4"
       },
       "Q": {
-        "x": "0x12897a9a513b12303a7f0f3a3cc7c838d16847a31507980945312bede915848159bd390b16b8e378b398e31a385d9180",
-        "y": "0x1372530cc0811d70071e50640281aa8aaf96ee09c01281ccfead92296cb9dacf5054aa51dbea730e46239e709042a15d"
+        "x": "0x0ac8969372efb9ae5f9b6d53a440f4a57d9ff2e40b4903f8d167d58ba59ead7218a06b4b1821f2ca28ab1239502e1de2",
+        "y": "0x01541a3325e7311a4aabff560a091467b847ffca590e1aaf354aaee1a6075d050ddd556d9c28e1fbfb97ca8749a8d68d"
       },
       "msg": "abc",
       "u": [
-        "0x08accd9a1bd4b75bb2e9f014ac354a198cbf607f0061d00a6286f5544cf4f9ecc1439e3194f570cbbc7b96d1a754f231"
+        "0x1275ab3adbf824a169ed4b1fd669b49cf406d822f7fe90d6b2f8c601b5348436f89761bb1ad89a6fb1137cd91810e5d2"
       ]
     },
     {
       "P": {
-        "x": "0x05c59faaf88187f51cd9cc6c20ca47ac66cc38d99af88aef2e82d7f35104168916f200a79562e64bc843f83cdc8a4675",
-        "y": "0x0b10472100a4aaa665f35f044b14a234b8f74990fa029e3dd06aa60b232fd9c232564ceead8cdb72a8a0320fc1071845"
+        "x": "0x15aa66c77eded1209db694e8b1ba49daf8b686733afaa7b68c683d0b01788dfb0617a2e2d04c0856db4981921d3004af",
+        "y": "0x0952bb2f61739dd1d201dd0a79d74cda3285403d47655ee886afe860593a8a4e51c5b77a22d2133e3a4280eaaaa8b788"
       },
       "Q": {
-        "x": "0x08459bd42a955d6e247fce6c81eda0ad9645f9e666d141a71f0afa3fbc509b2c58550fe077d073cc752493400399fddd",
-        "y": "0x169d35a8c6bb915ae910f4c6cde359622746b0c8b2b241b411d0e92ef991d3e6a7b0fafabb93c1de2e3997d6e362ce8a"
+        "x": "0x07f6e801e5102c171d6fdaf312be3b1bb2d01c9c4842ebf199d70351abf8c28e24347fa87694f72952c9e1a46f83d3e3",
+        "y": "0x17dd3a8bf9d7f433a33f15ccb0b8e9e26e850cbe7c87293887ec704aa5dc8454b22299ff0eaecbf487a761a5625c81ee"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x0a359cf072db3a39acf22f086d825fcf49d0daf241d98902342380fc5130b44e55de8f684f300bc11c44dee526413363"
+        "0x0e93d11d30de6d84b8578827856f5c05feef36083eef0b7b263e35ecb9b56e86299614a042e57d467fa20948e8564909"
       ]
     },
     {
       "P": {
-        "x": "0x10147709f8d4f6f2fa6f957f6c6533e3bf9069c01be721f9421d88e0f02d8c617d048c6f8b13b81309d1ef6b56eeddc7",
-        "y": "0x1048977c38688f1a3acf48ae319216cb1509b6a29bd1e7f3b2e476088a280e8c97d4a4c147f0203c7b3acb3caa566ae8"
+        "x": "0x06328ce5106e837935e8da84bd9af473422e62492930aa5f460369baad9545defa468d9399854c23a75495d2a80487ee",
+        "y": "0x094bfdfe3e552447433b5a00967498a3f1314b86ce7a7164c8a8f4131f99333b30a574607e301d5f774172c627fd0bca"
       },
       "Q": {
-        "x": "0x08c937d529c01ab2398b85b0bff6da465ed6265d4944dbbef7d383eea40157927082739c7b5417027d2225c6cb9d5ef0",
-        "y": "0x059047d83b5ea1ff7f0665b406acede27f233d3414055cbff25b37614b679f08fd6d807b5956edec6abad36c5321d99e"
+        "x": "0x053a91131611b1160954bdd0e69ffac08246ec85067a5dffb9f90e24623975265f798212fce88b41b2e67a7934fcfcfc",
+        "y": "0x1913fd2b7c72b8b702a87906c6f98e1e81b5c6774f1fd708118d5f2b9d90f4c756e79df8c9323af7a203b94a2018546a"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x181d09392c52f7740d5eaae52123c1dfa4808343261d8bdbaf19e7773e5cdfd989165cd9ecc795500e5da2437dde2093"
+        "0x015a41481155d17074d20be6d8ec4d46632a51521cd9c916e265bd9b47343b3689979b50708c8546cbc2916b86cb1a3a"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
index 43785d3..bef437d 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
@@ -12,85 +12,84 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SSWU",
-    "sgn0": "sgn0_be"
+    "name": "SSWU"
   },
   "randomOracle": true,
   "vectors": [
     {
       "P": {
-        "x": "0x14738daf70f5142df038c9e3be76f5d71b0db6613e5ef55cfe8e43e27f840dc75de97092da617376a9f598e7a0920c47",
-        "y": "0x12645b7cb071943631d062b22ca61a8a3df2a8bdac4e6fcd2c18643ef37a98beacf770ce28cb01c8abf5ed63d1a19b53"
+        "x": "0x0576730ab036cbac1d95b38dca905586f28d0a59048db4e8778782d89bff856ddef89277ead5a21e2975c4a6e3d8c79e",
+        "y": "0x1273e568bebf1864393c517f999b87c1eaa1b8432f95aea8160cd981b5b05d8cd4a7cf00103b6ef87f728e4b547dd7ae"
       },
       "Q0": {
-        "x": "0x02f2686965a4dd27ccb11119f2e131aefee818744a414d23ecef4db1407991fdf058f0affaee18fd586a9ab81060ae20",
-        "y": "0x0341a16c88a39b3d111b36b7cf885b7147b1d54b9201faaba5b47d7839bcf433cc35bb1f7b8e55aa9382a52fe4d84370"
+        "x": "0x0b63f31bcc08df890f35ee362c8538fac22cf22637aa2ba22d9c85bc1bda995926ab690d86830bf8ae06f4d537ccf6d7",
+        "y": "0x0666f3763cc7b223ab237e313f6474c9a3c2f5ed985ee8d1faa0928b4b428ec1a366226125ce8f415edb3f706e71d80e"
       },
       "Q1": {
-        "x": "0x1357bddd2bc6c8e752f3cf498ffe29ae87d8ff933701ae76f82d2839b0d9aee5229d4fff54dfb8223be0d88fa4485863",
-        "y": "0x09ba0ec3c78cf1e65330721f777b529aef27539642c39be11f459106b890ec5eb4a21c5d94885603e822cfa765170857"
+        "x": "0x0362c0f9d6cf4b73309a16b439d096b3ead588ab03cff57daf56fe747ab6d7774d5bfc0bd0a55bbeb0f05ec25cc191f6",
+        "y": "0x18d279b38babbd69aa176031655d138a731c049385aeef6eff3bf80e45ebcad0a941cdfc135e9ea1690a25eb6eac38e5"
       },
       "msg": "",
       "u": [
-        "0x14700e34d15178550475044b044b4e41ca8d52a655c34f8afea856d21d499f48c9370d2bae4ae8351305493e48d36ab5",
-        "0x17e2da57f6fd3f11dba6119db4cd26b03e63e67b4e42db678d9c41fdfcaff00ba336d8563abcd9da6c17d2e1784ee858"
+        "0x0633af2b38973d1cfb6e905292c41f209fe52e5be989b5e0d32c06a0e3c23e4843927cb8289b440f3cde0da46dc9ba0d",
+        "0x022474974e47d74c495de648eff1c8e4fabbae0d8ce3e30e3d1a5f9386cdf2582f78df056342d59ccca34321d93ef13d"
       ]
     },
     {
       "P": {
-        "x": "0x01fea27a940188120178dfceec87dca78b745b6e73757be21c54d6cee6f07e3d5a465cf425c9d34dccfa95acffa86bf2",
-        "y": "0x18def9271f5fd253380c764a6818e8b6524c3d35864fcf963d85031225d62bf8cd0abeb326c3c62fec56f6100fa04367"
+        "x": "0x061daf0cc00d8912dac1d4cf5a7c32fca97f8b3bf3f805121888e5eb89f77f9a9f406569027ac6d0e61b1229f42c43d6",
+        "y": "0x0de1601e5ba02cb637c1d35266f5700acee9850796dc88e860d022d7b9e7e3dce5950952e97861e5bb16d215c87f030d"
       },
       "Q0": {
-        "x": "0x119cc1d21e3e494d388a8718fe9f8ec6d8ff134486ce5c1f97129797616c4b8125f0dc568c59836cbf064496136438bc",
-        "y": "0x19e6c998825ee57b82c4808e4df477680f0f254c9edce228104422494a4e5d40d11ee676f6b861b6c49cf7de9d777aef"
+        "x": "0x0e8334d819ca7fad50979a487e0bc95cb1410914f1d760f842fc3dd0102755e7ca81b0356da7b9771ab11bf50efbca67",
+        "y": "0x120397edf7002610f907c2d4ecfcc4e817f1f8915becb5919510796bf595d854048461662ad960347216b00dfc79db38"
       },
       "Q1": {
-        "x": "0x0d1783f40bd83461b921c3fcd0e9ba326ef75272b122cf44338f0060d7179995a38ea9c66f3ce800e2f693d2634a4524",
-        "y": "0x017b2566d55fa7ee43844f1fa068cb0a11d5889c11607d939da046697c8ba25cf71054c2a8eb2189d3680485a39f5bdd"
+        "x": "0x013e1240e4da2abda009e263089cb8e57f1b24d0d1df09f644cc9c9a8b3fde7d154c7f1b0895a0af22b902a8140fb3ce",
+        "y": "0x0d6a9f75f2088dcac8f8ec0ab94bf2dac23b7b832bf23c91f9241f753c5831054b058192351a972347cb19806e78477d"
       },
       "msg": "abc",
       "u": [
-        "0x10c84aa245c74ee20579a27e63199be5d19cdfb5e44c6b587765931605d7790a1df6e1433f78bcddb4edb8553374f75e",
-        "0x0f73433dcc2b5f9905c49d905bd62e1a1529b057c77194e56d196860d9d645167e0430aec9d3c70de31dd046fcab4a20"
+        "0x07df547923a0c77ddc4fea1a8a2eb156aef1746d5452239a55a378c5d3590e0b75cddff0eef2a9214a41923f2be27b55",
+        "0x0f95fd8f00e25c3073ec07f249a7d527e580f01a6986158aeb064ed831d544fb9c5dbceb6604c908db5430d8f3d1c4f3"
       ]
     },
     {
       "P": {
-        "x": "0x0bdbca067fc4458a1206ecf3e235b400449c5693dd99e99a9793da076cb65e1b796bc279c892ae1c320c3783e25062d2",
-        "y": "0x12ca3f12b93b0028390a4ef4fa7083cb23f66ca42423e6e53987620e1d57c23a0ad6a14db1f709d0494c7d5122e0632f"
+        "x": "0x0fb3455436843e76079c7cf3dfef75e5a104dfe257a29a850c145568d500ad31ccfe79be9ae0ea31a722548070cf98cd",
+        "y": "0x177989f7e2c751658df1b26943ee829d3ebcf131d8f805571712f3a7527ee5334ecff8a97fc2a50cea86f5e6212e9a57"
       },
       "Q0": {
-        "x": "0x1614d05720a39379fb89469883f90ae3e50995def9e17f8f8566a3f6cfb4fe88267eac1dc7834406fc597965065ef100",
-        "y": "0x1060e5aab331ac4940693a936ea80029bb2c4a3945add7ae35bce805e767af827c4a9ffcb5842fbc50ab234716d895f6"
+        "x": "0x03ff794b445b926906b2fa710ba5db9f7b8689429a1630ab672854b5ba1a7c59bf3667d64aa63824a8798dcb631bfa9a",
+        "y": "0x1581711cffadabb6136f4bf57749e04b92787c7486da6b6da1fa758655c9af275b23540370d9f3987a100f0d3dc8e6db"
       },
       "Q1": {
-        "x": "0x0f612cda21cee750b1ccff361a4ce047e70d9a9e152e96a60aa29b5d8a5dcd25f7c5bd71bb56bd34e6a8af7532afaa4f",
-        "y": "0x1878f926302468949ef290b4fee621d1172e072eda1b42e366df68fc87f53c35583dbc043009e0b38a04a9b1ff617efe"
+        "x": "0x133bdea6715b4ef780693cd0055025b221becc8e04506a776484590df9b43af62ef402778a9c98ec540bc293e9741565",
+        "y": "0x0d953a5bdb2d16e62bfeab742e70ea64fddd83e8210b2416d40a02b0d90986fd0d00a3d77751ac467964ecc037dc284a"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x11503eb4a558d0d2c5fc7cdddb51ba715c33577cf1a7f2f21a7eee6d2a570332bbbe53ae3392c9f8d8f6c172ae484692",
-        "0x0efd59b8d98be7c491dfdb9d2a669e32e9bb348f8a64dbf7e47708dd5d40f484b1439109a3f96230bf63af72b908c43d"
+        "0x0a5d2ed6108aa08d652ab61af11c12d8750ed179cb962779c7b5393f219ad4b78b7b252a2896a341ad451e93f1904fb0",
+        "0x17d6cd69f4bd29b85c550539a296c76ced075d9d39a81f4cdc2804a7184ff9ea4a5a85dac4a2a61e317894d0fba55740"
       ]
     },
     {
       "P": {
-        "x": "0x0a81ca09b6a8c05712396801e6432a87b14ab1f764fa519e9f515816607283fe2a653a191fc1c8fee89cd30195e7a8e1",
-        "y": "0x11c7f1b59bb552692288da6557d1b5c72a448101faf56dd4125d8422af1425c4ddeecfbd5200525064657a79bdd0c3ed"
+        "x": "0x0514af2137c1ae1d78d5cb97ee606ea142824c199f0f25ac463a0c78200de57640d34686521d3e9cf6b3721834f8a038",
+        "y": "0x047a85d6898416a0899e26219bca7c4f0fa682717199de196b02b95eaf9fb55456ac3b810e78571a1b7f5692b7c58ab6"
       },
       "Q0": {
-        "x": "0x0a817078e7f30f08e94a25c2a1947160db1fe52042626660b8252cd339e678a1fecc0e6da60390a203532bd089a426b6",
-        "y": "0x097bd5d6ae3f5b5d0ba5e4099485caa2c505a1d900e4525af10254b3927ae0c82611be944ff8fdc6b278aab9e17ee27c"
+        "x": "0x17dc55e956f1e24c800fa6a61ccba179fbba6bbe27e96ab16b862defa4782d567f8733f1ee39acd7b665ba0204318d7f",
+        "y": "0x0252510413c32677817c4ee5f84e4c8f66721e489913a50eac550f41ad48b01b763ec9eed5bd68bcac76131ca9ebd741"
       },
       "Q1": {
-        "x": "0x1098f203da72c58dca61ffd52a3de82603d3154c527df51c2efe6298ea0eeaa065d57ba3a809b5e32d9d56dade119006",
-        "y": "0x0bcbd9df3505f049476f060c1d1c958fe8b34e426fd7e75424c9e227d9c4d3edbd5eddb8b1e89cc91b4a7bd3275d4d70"
+        "x": "0x03d2f5444d39ed19b6087cd684d2a72795038d1ffe9ab120f7e5ce41fb48af76bba3eb4efc8a696418fcb3c5cfdbfd94",
+        "y": "0x061a1fe191cbf373b74d5f642148722160b5524dd2c06a49c5e4d5480966de5b0854d53cbea144b482fa687eaf9fdc66"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x134dc7f817cc08c5a3128892385ff6e9dd55f5e39d9a2d74ac74058d5dfc025d507806ab5d9254bd2334defbb477400d",
-        "0x0eeaf2c6f4c1ca5cc039d99cb94234f67e65968f36d9dd77e95da55dadd085b50fbb11489167ded9157e5aac0d99d5be"
+        "0x111e524a9da7ae49a1cf6b03f5bc9d374f16951dcba59d03529a94afd4e5ba171fb1dffa373d13993503d594abd1b5ed",
+        "0x006ad90d8d5101c88db3923376f2a33ff922ba39342d1a5462785796b6ebdec10dedb5e9cd9ff8e611af939f7f617844"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json
index 9e9e234..05128dc 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json
@@ -12,65 +12,64 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SVDW",
-    "sgn0": "sgn0_be"
+    "name": "SVDW"
   },
   "randomOracle": false,
   "vectors": [
     {
       "P": {
-        "x": "0x126690faf7d2cc7838d18f58ae94e9eab1d042fb93ed7245aee5a1a3ecac3f1935df62b807f9bd7be1018492b4ccd087",
-        "y": "0x0d2fe772107e935ddfb916da6dd69cb3c9b112cbd7452a3da77e16620f58c06db9c1eb19ab031995c96dc2d0c16b5031"
+        "x": "0x10a5d58b52dc8b0e5b9c83e5e5ca49cc48d9efe5018d4d9816200b2e6a2ed51a64f62bd413f1139d7504bae8e777e970",
+        "y": "0x10a24635478b4cb41a2919057d76d4b41bf41ebf23f8622f6f709e722a7f4922ccfd001ead45f275685b5136e0d09012"
       },
       "Q": {
-        "x": "0x10c4561604827f4687f7bf5a365411577c6c0298910d6a67685c675f1dd0b59ac5fbb46b729b3389499aaaf5b11bfc06",
-        "y": "0x114963eba7ffc5e3bc4c86a1dbf73b4952bfd60fa94449b2adc81dee0e974e4afd228a1af4fb1d4ede14cdc727deed0c"
+        "x": "0x008b9526bf4806b9157907fbfdf03849905a586ab3b4faa2e1287d54b151639c1c4e49e02c03df7e77384eab5f05b559",
+        "y": "0x0888e71e577d22fa3891063e89307590efa7eaac676ce879afc53a79155698f4ee55008e66be14dd77cf7ff41c55722a"
       },
       "msg": "",
       "u": [
-        "0x1754372e423dd665efc2703d235a5b42ad5609ee9872c303a0b900b152d5ae8d64c2d67764a6f188b87d61445cf5634c"
+        "0x118f642bd1c2a29911bb43e9838991f9399c41e3bf92a71b9219c8a5edbdce319f51b90e72b949848851b608e0caee0e"
       ]
     },
     {
       "P": {
-        "x": "0x03929609010843a52432b815cb5fb90d6a5ee8a10cc75c70d6f1bd64642a0057d2e69187ea3fff0a34e7e72b1cef5948",
-        "y": "0x196b4734ee0b1845619e8b871c0a2ea556660dab119868ad5542dc5b782b0df61cb6d2a1b2cd174a80cbc9f8cde6d470"
+        "x": "0x0dead3d3db337422694f10ba8e2391fffb6efff65c6bd60f624d0ce10fa200481a72ce0aaad111a4410a38a4b4108a46",
+        "y": "0x0038a800c995de01127f278169d365089cfa9ef09efd538dee91c97c8ec40891df0f50843864ad23904129d5b4f4a1d6"
       },
       "Q": {
-        "x": "0x0f5b63a00bd63757fab41dbc9b47b679650d903a83934eb920a13097d58dd5f82068c059bf1de52971373c3cc83c427e",
-        "y": "0x03f2547ce0337e25a9fad27335f499b054cc1ab3e1c29366959599b5d362602bedcce56c0e039c4ec0fbbdf041564892"
+        "x": "0x12e095c062d0a4358c5b382f8610e6104aed69944447f0d04b0a9f0afd378e8fa8de4f0711168cd3aff501a145615503",
+        "y": "0x0fe86fc6d6e51c6f9d75fc83c9da98a724a062ed25934740219653228b882182d6a4fac1a42480228db3c12344d2145e"
       },
       "msg": "abc",
       "u": [
-        "0x0a55c5bc65256c488bb068e3b1d5d2fc4acb3017da1f7d9a3a9036eb5880123b0aad219aedb4836eab28e7a85d171054"
+        "0x08a8225bcdee1e9db85e01ebee4b14a8825cc401189ae1c0474b483b0970b28e1ac12082c22954bfbb825fdcef77ecdc"
       ]
     },
     {
       "P": {
-        "x": "0x107485fecc3be4b92f8cc35f1782c67742d055c379e6bcb77836396edebe728aec4ecad0290bd1bbd5be7047ccb8554c",
-        "y": "0x0603d69e02982c8a0edc6fd84848fa9d9c75a0d7a372eb1ea2672245ee2d9ed672cd1a564fec3cb77758b966316d5c09"
+        "x": "0x15651e258c566dc7527a165698f8d71157078344c2dd359d220cf00168e536ec89222681f49c0b9b4cd0e8ffe85fcce7",
+        "y": "0x0077640379dd49d0ac509ac041a5f3c8a54cddbc6add66d5ce4ff86896fb293f43696ad6c628400be7fba6b058e3db8c"
       },
       "Q": {
-        "x": "0x09c7ef760508a7d4a226869cae2c556a8773ebf5d4bbba33b0cffbbba598105bf7549cd33d52ded62be72f718ab0ac9c",
-        "y": "0x0aa4882a7806cac7bb3bd6404000066b7c6ff14dc590efa26f2740b1af2f3be2b50e1d5b99b37d723d9d3b0cf089bf62"
+        "x": "0x0319e7028069c8fc4ab9155d810c607186b9f97f854018d195f71734039f83fd42d839dcdc044acb91db25d155c5fa58",
+        "y": "0x1171bd0048f0741d7f2b5f1316678b5017cdc2d2efd28ef9d8140633b200d57343b04d9f1ae25d9ef4a1bccdb57bbda8"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x06983540e75c0e7a36976a66cbfee71e05c9ea2cbdb3b0f25aa9329e02ee95895fcde7262dae46c370c148e1027c4819"
+        "0x0979bb7682c048cc9fe6b9cbd69a009a8347ae1fe3931b3afe24c29867adb96aa967e7682b3a47f9b9567c8551218a46"
       ]
     },
     {
       "P": {
-        "x": "0x06c214d69a4ecd4fd0230f2dd2a8988daff27c597acee1ec5e6045e0848894d1435f5c143f4226fbc27a2045921c2499",
-        "y": "0x179e0869d8c73643e0bc27ebe3178ee297ad366c9a4f416a0b0ac2265ff763fbd8c0bf37e637d081190352f4c1961f74"
+        "x": "0x06b8d589c3d2018d069d4cc57a359402a27ccb5bc017d9a2d67762720a63afb9e2a12c0c417becc4b51efcb39e8cd2d4",
+        "y": "0x1307d340e6d9d16d822105a014419e9f6be6dd3fdbc42e2f96099058a9fa24f17d81d4ce82cbd473bbe51bc95e988751"
       },
       "Q": {
-        "x": "0x0598fd95bcd0a790e6921a51f212f5194781521cf32fcea581be2a5cbfd2a8fda8828141a24168689a273d258b1fe083",
-        "y": "0x04d0dbee266de33d9bee538d188e209476ebe3b34e58a19d0ea6ae542219b3f3549685ef3eef82991feb23ddde098285"
+        "x": "0x138307c4c46b63f05521143275b28a48a6ee2dbccef2b75e77e87257b775a346905090bbfe4c35948bc76be1a6307b33",
+        "y": "0x1668fe7bd31692c9ed74c657d631e82faa5aba8f89703870def3974fe42947b1f36f2f3787e7f690ebf2fc8fb6e91dd1"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x011a4d12d373940b946029aef4bbdbb880810b25370d1f5b171e2d68091fabc9a4c8fc4f39c9b0ef98c34b5f90070a9d"
+        "0x0aeef9f4c2881a00b584bcfe2fe19b861cb00fef6edcc5779b32178e952f033bf9066489921612cf3d25a8be095809d1"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json
index 8384f86..888d0af 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json
@@ -12,85 +12,84 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SVDW",
-    "sgn0": "sgn0_be"
+    "name": "SVDW"
   },
   "randomOracle": true,
   "vectors": [
     {
       "P": {
-        "x": "0x045f87745ff759f9197e131ad83d47d635dc36a3e0c7e4a1be5e1effe5e63ac69c8f34e6c3aef9c5cf28224922788367",
-        "y": "0x06125886a03f883740a078313d5fa6e4a68b9c0394eb75f77c65fc8b44db3f4ef933ac6adf341bc45fabc7907afcb832"
+        "x": "0x163505b44d4a47de22946139337d787f93f4356075c55401f4fdbeb3ede4f3138684e2437e50175f94eac511d7c673d6",
+        "y": "0x0d09a4540a792daf4d0368f20afb5bd859e537e362edfc9b6f35290b6d05df90937ea91e6277d1cb91638c1abaec4eca"
       },
       "Q0": {
-        "x": "0x0d8deaf1a9fe87c5710466d0cd554b243a041a97c15228f1c65be6244b5e1a575f4ab2762a1cc9ff18d45d4f1494e2c6",
-        "y": "0x090dce51930eff6bccfc7cc2920f180c398b0a97085ff9e4841367e701a0f28616bef537203d27b0656f3b7ee52ee0ac"
+        "x": "0x04c5db8bf2c09bda41eab080eb6ffed00f30d4c650a0c0c8cb136d9041a9e9b420aa5737fc8dcd1ec2eda971b4bbf7e1",
+        "y": "0x05b8cc1054ff8ec690a4c073649b474b7b96f2b26ebf83cdd354197ab89f66d78f120407a934d5aac78913d16a8092a5"
       },
       "Q1": {
-        "x": "0x0a36d0d4051eb32d253b069d1d15c5b69cefbb75bf38d66d43b37432b34f88b2553bf063c6533ca87112c3e95c295ebf",
-        "y": "0x0bdc425e77f44ac13587b17dab2b1b9d3e3501be1fe1c56c7f3701fbe53b43a37263c04fd9aa1b7f58b1b63fe6cb29fd"
+        "x": "0x0ace795fe3b2f40cceda72f6fc9086009db87b1e63e906df2eeca748df8f961ae3c83e83bf6c11b5d833e7b93c8911f6",
+        "y": "0x02be94da9204c38c42828e677cc941184b62ab9aaebe408f90035c50afd732611550dcd31cec9625874596c8d45dd2f5"
       },
       "msg": "",
       "u": [
-        "0x04a74117c448f7aad70bd41328b3856de638c0e10c9ff344295a04b90db0f2afe80ff2da62e091793d6e52bc70b28d47",
-        "0x06f44093874c190fff1e893c847a59601d5d5ac0aebd85ba36b3906a93173e0d2fcf6bed8013ee2679ca337f21f8f053"
+        "0x10baa9e54a51ad63c6d8675830a2d74c43abd00a4e56432e90aa77ccf95997286d3b7bf1f61059b76663878995426b9d",
+        "0x0acf2dcf2bf547d48c01b96379801bd7e2b9f815f22132a07d1ae1ffe49040825ba7b28082696a67b3de2cf9de5f886f"
       ]
     },
     {
       "P": {
-        "x": "0x009a357691a6f7b2917d9a34ba64d896d40b49733fcb3207f8c146e20fffb47823198a26b6ceeb01215fc3422908020e",
-        "y": "0x03fe44c894c107a8547826b60f577b90f80c63f899ef9dcff94daadae180ad803609337c9ec97d6d9b8ba306df7a9849"
+        "x": "0x02967a7955df3c43807263e9d33c28912daebcdf915ada74ea6ec131210a3f304d97a59d6e3b7bcd98d84f61efb2f659",
+        "y": "0x13dab558fae67943edd68f571bdc82ad6944f2d80285d9f578d4b1be0d7b4641c653ca52f13eb3474922617c00e4eab5"
       },
       "Q0": {
-        "x": "0x01b50bac3377c4e764fda5fcbe9bb477c3becb8cf18a3026a88ab2a0fbf6d8164d60d85ac9e67b6712fbb26b10ec4597",
-        "y": "0x11acedae54a20e1f8d58fd074e1b7de957203f56365b52a09824ff9f8d191356914818bdb35faffe8657ad24e1f5db5f"
+        "x": "0x118e12a015459f171fa12049d2bf7a43aa2d07b10709c2e21757f191cc60a3313e447c4ceefb3dc89e05893af65b133d",
+        "y": "0x0c02fa378304433efcf458c0cc531b72b8613e425cb8404be8612aee0f7850724ed2a6c6d02a8310cf381b99c85293c6"
       },
       "Q1": {
-        "x": "0x16bb1fce160d3fb5194b275a907cb03bfbe8713e830f2a573acc26782c65c9a6e88d96c6489c96dc6f65815cb5ab2662",
-        "y": "0x159720d02fef12d1a40b1c91336908d72b0eb1fe54a16a914c5ae9710a8fa8dfad035ac6c39708c88318fe26113f28d5"
+        "x": "0x107450b1fd1a5e7b8fdf96cd40da9c1919ba86c124160ab6d5d2ed9f83ee8f97c1530437f6f811fa4f4cd1d0a7d69c42",
+        "y": "0x039185c9fb255a0ac30d091675f02d29bfcf6045b1532384056876a389819d48da77fd71669516e7c98e12da273cddd7"
       },
       "msg": "abc",
       "u": [
-        "0x145191560d1db38062a0a2e29469d71eb035f888cd4bb2792ddf88ad63c93320738a3e4c6e199bb286e26efaad665a0f",
-        "0x17f7bbcbcf64dedb58af6560e2b2d08a678e4a57a0b042978840abb77f25b33090035675ac30bb461a8955a9d1ebb411"
+        "0x12b51a783412cbfae1f1b20d7000184c74c889382dc65762ad98a8d6d654aec9a05fa4621693072c67e41987e36b3998",
+        "0x150a735bb2fb20d4b6221a2d20cfbe275826a63a38f04f757ac63a35dc0a26041d842e9d7f27e3394a007bbeee92fe85"
       ]
     },
     {
       "P": {
-        "x": "0x04eb09680fe48598533932907810fb7681e60b3689cb138454bec627490c5089b6dd755556e52a36c3817e98b62d7497",
-        "y": "0x1763dd8bf6823d9a22124d22a4ab3d93d8a9603ec80b4a40905b26664b16033fa6e73a6155c9bc4c6faa42bf911ffba1"
+        "x": "0x084b64b095e373b86441e9fe737a3f8e56fe7f0016a973ed9938db9958505a8927ca220d8e8235901d4bc1dccd4362bb",
+        "y": "0x0fd10114cded64bf037d3ba00b4a85e5f19847535dbc960bdaaa8a92bbb9d8a845dc355370ed0edb9d4403afc39bd30c"
       },
       "Q0": {
-        "x": "0x164e16e858fa1e1a4ea52152ffe0a42f1e6ae1258dd830eb7aa66434d7d5689da945e29c61766ae213bc1878363a3d4c",
-        "y": "0x077cc4c8f74f33a0e6036d32c4407b3021b0be82e0eba80a1fc119f69a071c52f25764dbd72f2cafb420264c079b7691"
+        "x": "0x01bbafd66bbe5955cf186e1b050f962f7a2efa4f03ff50353dbda78568f5541aa8582c25057a9fe414f9a1bd82eccf0a",
+        "y": "0x0c96fd01df526fda79643a45b1ec5d435e63a3af5cf4088f30c07302ff8e0a271aff59e5da618ab9b89326fe8b4338fa"
       },
       "Q1": {
-        "x": "0x06a856de4eb5651a21c68c7e85796c16e417d7d97cb3e1b74bbc4042b340e647fc41cc570bd160fe9917d32a47bc8b5e",
-        "y": "0x15c4e89949bbdb253d333018a1417150f8a78187c343f5bbdf25d962c513df1d96ee1059facab028549ebe7716164466"
+        "x": "0x086bb205df6314011dedc477b201229f383c1e2585b5aaf269fc6762ccb2397690064429dddbf9f304367508aac0fe83",
+        "y": "0x02f80d27fd2981db284b0f66cf3d8e06f751464e610009b9f3fbb818f526ff85f7f1a38ea3c85008c5814ff19d05a1ee"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x06ed3e25d860fc574e482bbc0a09c5f44216ad44d75ea499cf905efe4bc3c5fd3e94df483d17501395f325d3c8ea7925",
-        "0x1426c02b7de4bedb4a301c7d2d4a270f672a8fc448471f2c3dfcf43846b102e592ad6e055c2d5149fcbc21f5fb6002c0"
+        "0x163831497fddb01bbad44e3f592ad34635579e055d36be71d53bec8b22c27525a471ea058bea4a188a857861fd1af802",
+        "0x0cf8d175460236795d8163d01d5068d82b218295a1f8a8eca094ce27ff208ab5c9c3f4212e3fcdef3980a267598f6830"
       ]
     },
     {
       "P": {
-        "x": "0x0915842b42c2c4d3b509823c60c1fad834784ff451855f43390b80c3b6985d76aadc6ecfbb4b42a07921410d6821f0bb",
-        "y": "0x052873ee0b444dd8337ce403636d680cff1e9402b7a1ce2ab210bff11a83fe4e14216fe96efe3f344c1a2ec0fc1b2c5f"
+        "x": "0x1362872938edd5f0f648d3f8f71225b38a9bbf6c28dee168d76b274125ef4596d1959dfa622861848b2bf713fda12601",
+        "y": "0x0308f950d4321be5e06a751aee088d09da8fdb36c4bc6b801d529e43250f3e90d55c8d9fea6d3762912f92866bd89d02"
       },
       "Q0": {
-        "x": "0x15901778217bbe602fe603edfa0518009197445f34dd2184450fb2a1a5088945c32d31f6a9fcd9e3c4333557a11c18a3",
-        "y": "0x126fc2597e155f4aeeacb7a039b5a0012be2cc1433d8c097b6c8e9e6be9b5f279c0decb019a6995345e607a36681f8a3"
+        "x": "0x17f78156bb227c0fefb04a3d58f7315cd7eb696e52b7efeef9fa82171e8c6d8dd265f7fcffa8e6e734c6cc2611363e80",
+        "y": "0x000a6e05625536b8cc8fff02ebe2ff0a6f137d5f0b644afae033fdbec60e41e281383e97333a342e3492baeddf637e36"
       },
       "Q1": {
-        "x": "0x0dcb7e280b34f7caf24928ecb126a3bacbfeb4b70612d60bc7cd36467ad58cf33925e9c78635cdb7a024c0a3031846c1",
-        "y": "0x066bbc62980e8bf7664f2b84ee69f3ed2c1a49ef1f8c0d35d709ef1ed149f79cc93a65ccde5194d333710496f087d41d"
+        "x": "0x191f209664bd324339cbbc4e3afe7e713fd47e57c476ff8c224bef6b59745384ec6f15edd912c56336299733b9650f3a",
+        "y": "0x108c7a3b7d2e6c83e1e9bbcb03960a3b9115d871cce130d8622576339bbb3fd02565de45b06620d557e9244c4a4944d8"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x0da5000e88db641d86b6aa2711b88b9bcf45fc95689dec569bd9ae6aac6b19e96620920f3fb806d0e72a111889983c11",
-        "0x0367d0cf2689a9e972f01d9d325a3e1bdcee67af7f39fb71030869457ea93d0039e58bb92cd058e45ced781def78ac79"
+        "0x130bc594dc2a536afba69280db5d4675051f5eb3a5d147290874f53fd275acddf4faca77145fb23aa6d9357a00e0a4f4",
+        "0x02e5a19a37149c402114906448c3f7558125edbfce8c5241056d32bac7980d95d820ecf23dbfa5eafa9c4f8c3dbb4b70"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
index 95bcfc4..5c577ab 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
@@ -12,65 +12,64 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SSWU",
-    "sgn0": "sgn0_be"
+    "name": "SSWU"
   },
   "randomOracle": false,
   "vectors": [
     {
       "P": {
-        "x": "0x170919c7845a9e623cef297e17484606a3eb2ae21ed8a21ff2b258861daefa3ac36955c0b374c6f4925868920d9c5f0b,0x04264ddf941f7c9ea5ad62027c72b194c6c3f62a92fcdb56ddc9de7990489af1f81c576e7f451c2cd416102253e040f0",
-        "y": "0x0ce03abe6c55ff0640b2b303440d88bd1a2b0cbfe3274b2802c1f58b1085e4dd8795c9c4d9c166d2f033e3c438e7f8a9,0x02d03d852629f70563e3a653ccc2e114439f551a2fd87c8136eb205b84e22c3f40507beccdcdc52c921b69a57968ec7c"
+        "x": "0x027e4bfada0b47f9f07e04aec463c7371e68f2fd0c738cd517932ea3801a35acf09db018deda57387b0f270f7a219e4d,0x0d4333b77becbf9f9dfa3ca928002233d1ecc854b1447e5a71f751c9042d000f42db91c1d6649a5e0ad22bd7bf7398b8",
+        "y": "0x053674cba9ef516ddc218fedb37324e6c47de27f88ab7ef123b006127d738293c0277187f7e2f80a299a24d84ed03da7,0x0cc76dc777ea0d447e02a41004f37a0a7b1fafb6746884e8d9fc276716ccf47e4e0899548a2ec71c2bdf1a2a50e876db"
       },
       "Q": {
-        "x": "0x029b6b7335975135a3dd653cb5f865f8e1a6fd0e806f83f08078426d294efb72578dc6747b81747d03b5bce9fa9c6d4c,0x0e31914536a751dce017585d51c8c30127cf0abf8cce302faf8ea87de1393a37696df8d999f597b256e8e19a0865817a",
-        "y": "0x0a718016d326692f10e7508c6abc624e1b37da5fd0e4391acf5a19fac36b97a9ae13a79dd2bd0b28c1db20f9d27607e9,0x01df562b2fe9e7281b63a3c136a93773184ad924d9a0a0cd01b51150f175f9dfaa8d009f77df9812636a6de4a1b0a901"
+        "x": "0x0155447bd67775ed9eaf35db498e8acf00b9240a8b336b284d4be1558036495c5872384378c0931b888f85575768f52f,0x09fbb2d6ee99f38a93c38c891cb28c5e2f18e97c78c7b74fbbb2d4d21c1b02dd05170a3734bdf7ca97ac17091b85b1fc",
+        "y": "0x17d2d52554474a2cc19322bce0c3079671043190fc6d33679530df9341bf23424b2aa4470de343e65ab1b1a3c1f380d7,0x052e9100ee074779a4da267cd34ba58be71f373b05ea5f9fb4a28dfb279a9129efd5f22156b2d3ae2b3c52ac0fc7004c"
       },
       "msg": "",
       "u": [
-        "0x09367e3b485dda3925e82cc458e5009051281d3e442e94f9ef9feec44ee26375d6dc904dc1aa1f831f2aebd7b437ad12,0x094376a68cdc8f64bd981d59bf762f9b2960df6b135f6e09ceada2fe8d0000bbf04023492796c09f8ef04016a2e8365f"
+        "0x0e775d7827adf385b83e20e4445bd3fab21d7b4498426daf3c1d608b9d41e9edb5eda0df022e753b8bb4bc3bb7db4914,0x025fbc07711ba267b7e70c82caa70a16fbb1d470ae24ceef307f5e2000751677820b7013ad4e25492dcf30052d3e5eca"
       ]
     },
     {
       "P": {
-        "x": "0x16d830a4e12fddfbdaf9a667f94f21e490879fd3ccc5ee6f039cd7c2174fb47ea8027af78779a978d2a921612844587f,0x019a3b47aa956b2b548cc04d9e109dec06642d6e28814f7e35f807e1ce609e2eae3a155af406c842529776d8192f562e",
-        "y": "0x15930174c11aa9b51a5cc3ebfa1ab6377e2318c4ea2df387bdb84b28687a02c86e6401b195bbcabb6e95d6ae43669e12,0x15adde069459ab2012b44c7703119185b96b7f04ad59b39f4f6aea35fdbb9c5c7d876b5f89afb55b67e7da96ad489dc3"
+        "x": "0x09349f1cb5b2e55489dcd45a38545343451cc30a1681c57acd4fb0a6db125f8352c09f4a67eb7d1d8242cb7d3405f97b,0x18f0f87b40af67c056915dbaf48534c592524e82c1c2b50c3734d02c0172c80df780a60b5683759298a3303c5d942778",
+        "y": "0x02f2d9deb2c7742512f5b8230bf0fd83ea42279d7d39779543c1a43b61c885982b611f6a7a24b514995e8a098496b811,0x10a2ba341bc689ab947b7941ce6ef39be17acaab067bd32bd652b471ab0792c53a2bd03bdac47f96aaafe96e441f63c0"
       },
       "Q": {
-        "x": "0x0f4c4441758b65035fab9adeb84dc4fcbf48e218085111cbc9e3294dde67ba93411d747d090fbc5aa144900df054ed32,0x0bcf59db7917f351264cbc8825c04e88885b01f8228ecef238e39cd9d7e42c7a6b4aeeabacbfe43ea36f1a148c3517ae",
-        "y": "0x128fae582c1c32dc1199981981c9f2ff42343523192b82d3c010c6b06e419087449196cf4a79caa921db2ab10fc316b5,0x0cff0768048fef20c10c19679deb85fff097befdb18a47a21c2ee57eeebf046d4d9f3bdaff6f9c7d6c80e0700018b86e"
+        "x": "0x0d158306276e64752eb05c697c0e982c1f120d36a0001c20910632b8ef4de742ff03b77a1d5313c0c5b015249d804713,0x03511e20d69ecd16eb9ed9bcbb500593abdf9b9dae12621a3b7faffe3d2a78ecf9e1526b710ea9773a8b36e1c358f3e3",
+        "y": "0x1299a622ac19a0cd8215b9d3d64916770894d9af261e25b0c6dce3cd4025fa1ac58c4f20ca49f58db59ac4403f274dcc,0x0cebbb186aa40e6ee61380ea20f21a1ce304ad0a0ca2c5126be0ff18863ee17494e0da7e63eb8184b6d6e7c8b2a09bb4"
       },
       "msg": "abc",
       "u": [
-        "0x17ecd5d41a860b8886cb1210874b254f59945b089f774dcc14bc1aca7d4e3c975bce0d28510c442e9a932be5880ee5b1,0x0f105595e14847cc9a41fd70deb3240337678b266304100ec261add2585b991c7268bb1a325d2f871b327e8d04fd579b"
+        "0x045ab31ce4b5a8ba7c4b2851b64f063a66cd1223d3c85005b78e1beee65e33c90ceef0244e45fc45a5e1d6eab6644fdb,0x1870a7dbfd2a1deb74015a3546b20f598041bf5d5202997956a94a368d30d3f70f18cdaa1d33ce970a4e16af961cbdcb"
       ]
     },
     {
       "P": {
-        "x": "0x1498937f0ed18c49ebbcdee579b58ce235f3ab03be5dc809e1df25e2e0b4eb4c672f4eaf26df91f3755d6367df55d5be,0x0910b2d55e210122fab2d2dae81e6a440fd22e925e422aaf16a8fd28477bacb12aa888de0faeea203e372a1c1cd9578c",
-        "y": "0x033b1948575e70fed67fb4f7bd86b5452dfc0afeb74ecf5cab4a6872e33f0eade9564d3d5b9fcb9d4c498afda0bc037d,0x102631eb4e684d759312d7eab78598f487c2c10ad3d3552cb43ce6f09a11eb46e551864863077906d3ecfd921f1fe541"
+        "x": "0x149fe43777d34f0d25430dea463889bd9393bdfb4932946db23671727081c629ebb98a89604f3433fba1c67d356a4af7,0x19808ec5930a53c7cf5912ccce1cc33f1b3dcff24a53ce1cc4cba41fd6996dbed4843ccdd2eaf6a0cd801e562718d163",
+        "y": "0x04c0d6793a766233b2982087b5f4a254f261003ccb3262ea7c50903eecef3e871d1502c293f9e063d7d293f6384f4551,0x04783e391c30c83f805ca271e353582fdf19d159f6a4c39b73acbb637a9b8ac820cfbe2738d683368a7c07ad020e3e33"
       },
       "Q": {
-        "x": "0x110a8c50fb6b2df0146678e80de24089e0d619c45c488e0c688f136963a4190b76647e9e122c18ab7b60a88ca1281e9c,0x17f35d34544ad51d51f2ccfbda142addc678bf5551bf301dce3c3b934ecb6aa78b3814729282755a62e4680083736628",
-        "y": "0x0bd9c15e07f2a2bd5dacae74861afa19ea15d393fe7552d3ba45ef1396d37ff7967bdf67d93ea68baf849710bcd88147,0x18e9a587c3b76f53a62e8919101b6f2b25803333a53b2c8596db44929bd59376f0a170c5debea9f8a378107c2ee1d51b"
+        "x": "0x12e15bef85566a4587d120dc054c935f2ffb198aa0f70137b02c406ddbb80e01844e3efb7f4457f304d85410a5cb0e21,0x01a3026ebdf89e103658689c35316e87c2de54633bc5548104b48c87690cb15008dde3cb0386923ff9cf89022adfb6ff",
+        "y": "0x068beb96b5ff990c8a44bd85e7dd2739dffd8942d749db0ac7127374d4818b35e35266c708a74e904cc18c464fb0fa8a,0x0c9d5a6359f809813ffc2a17357a6f92d08fc6ccf098309ee27dd527ba8ce43087971b963da5c663e958b7bbec04b105"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x032ae17a23a76c94745a5460cd9f1191c0ebeec7adfc4df28b0833e536b7dbabf498dc076ff16cc11c6a6ef5105df693,0x1107a6f450c6c9580c720190b577f52c633cf5f3defb528ae873d3723bccc8fa433014e9120a1da31abc27c674f37ae4"
+        "0x0b6e6135a4cd31ba980ddbd115ac48abef7ec60e226f264d7befe002c165f3a496f36f76dd524efd75d17422558d10b4,0x088fe329b054db8a6474f21a7fbfdf17b4c18044db299d9007af582c3d5f17d00e56d99921d4b5640fce44b05219b5de"
       ]
     },
     {
       "P": {
-        "x": "0x18af6eedb7ed3be66c5a1d998ad4d9640f557b189558baec41f6e712ff2a39f795a35494b4b12343b7a1a2b17686d793,0x021f7faa0550e5a5d08338b4c0a5d30240dec7989fc7c77b6ffba9bfd5d64ce45af5aad8da8482bf0da91af4f29d371f",
-        "y": "0x0cc46cea229960bfbe25831162c27f96cf8bb14c017938e35b636987a306521915456fbd40633c6d5a30f61bce52a3f5,0x166c1abec65af593d291dbd05e5d7d28f1a9ffb73751d65f49d76084493f3da707ee2bbf54cf6de5bbaac2ffa0028c31"
+        "x": "0x0804152cbf8474669ad7d1796ab92d7ca21f32d8bed70898a748ed4e4e0ec557069003732fc86866d938538a2ae95552,0x0b8e0094c886487870372eb6264613a6a087c7eb9804fab789be4e47a57b29eb19b1983a51165a1b5eb025865e9fc63a",
+        "y": "0x09e5c8242dd7281ad32c03fe4af3f19167770016255fb25ad9b67ec51d62fade31a1af101e8f6172ec2ee8857662be3a,0x14c80f068ece15a3936bb00c3c883966f75b4e8d9ddde809c11f781ab92d23a2d1d103ad48f6f3bb158bf3e3a4063449"
       },
       "Q": {
-        "x": "0x0cf7bef1339955cf2139e61d3876d22bfcc89c44492b458b2d08a6bb4fa58755739a4b216bfd7604e203f4c31cfcdc00,0x0b80a0dee7817f29f8bf3374a3c033586d695391dc95280b2143d398817bbf9b76547c54b81fd2b8ad24a6afa1dd8524",
-        "y": "0x07bba42c7be028acf9111e51cfa6d98f2949f12635847e938b0f7980705da9abd1d77bbdaf86f90512e0139ac0e57a6b,0x0266340a1aaaf26dd5ec892f33dcb6a217dcde9b8d39dff5d277d93130ee3e33e43a2cb83665fee8648d610da2967fa5"
+        "x": "0x17b0481e72cb03d59686907d10243ca3208078151e4881c8754503587676512e182cc82b24e906a0b4ccf95e5adeb7fa,0x09f9a74ec1f83ee91991c40858051460f1253283f101afc155b4fb141af20ae84714cda88ee0bbcceb3cc010c2b3172a",
+        "y": "0x0cf1edfd25dfadc366eb5b92d6d300b68a9a01deb833b754fec39ec049b70e8b8023c4abb1386a8c8419d44d414d7416,0x0eb4061e6ee7136fa62bcb68df9b1750ad85fc225050f06669d7153bb96df7cea2eb1837aa2d482eeb1c4077c8885db9"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x0cda6b874f8c41862c078099aa76d607be51d913a2e3f997539a0993bda31892292818c74aa9be035f234df2576fe49a,0x0306162d24592a18fa8de2007d7b69d04bb7a71a5a7965d15bdcbaa4ddf9b599079fbdae9f67d55ab6dba044f9daf179"
+        "0x0f45b50647d67485295aa9eb2d91a877b44813677c67c8d35b2173ff3ba95f7bd0806f9ca8a1436b8b9d14ee81da4d7e,0x03df16a66a05e4c1188c234788f43896e0565bfb64ac49b9639e6b284cc47dad73c47bb4ea7e677db8d496beb907fbb6"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
index d108a06..69a8c29 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
@@ -12,85 +12,84 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SSWU",
-    "sgn0": "sgn0_be"
+    "name": "SSWU"
   },
   "randomOracle": true,
   "vectors": [
     {
       "P": {
-        "x": "0x0d3b02ee071b12d1e79138c3900ca3da7b8021ac462fe6ed68080dc9a5f1c5de46b7fe171e8b3e4e7537e7746757aeca,0x0d4733459fead6a1f30e5f92df08ecfd0db9bcd0f3e2f2de0f00c8f45e081420aa4392eade61eade57d7a68474672fc1",
-        "y": "0x09cc6f7b3074f0c82510e65d8fc58f6033e03ba7358005a13e2bbd7f429b080f29731ef08c3780c9e3c746578b96b05c,0x0011531b8e08900a4f6f612e1e27432961419ce6a5ee3ec904a53588982d36ec4ea37be80b6cb7d986b38faec67dbe44"
+        "x": "0x0a650bd36ae7455cb3fe5d8bb1310594551456f5c6593aec9ee0c03d2f6cb693bd2c5e99d4e23cbaec767609314f51d3,0x0fbdae26f9f9586a46d4b0b70390d09064ef2afe5c99348438a3c7d9756471e015cb534204c1b6824617a85024c772dc",
+        "y": "0x0d8d49e7737d8f9fc5cef7c4b8817633103faf2613016cb86a1f3fc29968fe2413e232d9208d2d74a89bf7a48ac36f83,0x02e5cf8f9b7348428cc9e66b9a9b36fe45ba0b0a146290c3a68d92895b1af0e1f2d9f889fb412670ae8478d8abd4c5aa"
       },
       "Q0": {
-        "x": "0x06828063f239b9607a9668fc0a59e5391c1bf24ba42ab5b480112666e3835c45f29401bea70d6f529d07e33bc017c1a4,0x04545e6b5318ec1c10f75791bc97142722370b851b7829987ada828de5a9b6353cb2c4f8540bf0821328c983e7eb887e",
-        "y": "0x06fc755b65fd277f7e1e4a6174dc11fedddf1baaefc07d04c3d120e15ca2ec61f489711c4af949bf6a5d26a885db05e3,0x068d9e1e428ed301e425e633603ea9ce5ff02df898aca1957fe5be1faf2ff42b64485cab41370a50c1e7e9742c0a2c6d"
+        "x": "0x090f7997311a1d4ec54520f81046063f4e9e7a64570133dc41c3600ade2a4d21aae59714cf290f95f90a98b658f5b64a,0x08427a6a0dc88a36698823d07ab25d11f95a9508cb5bb1ad2bd57bc02b5efb8c7b1da66ed02b0f915002446e24fd5d38",
+        "y": "0x10e03a54fd5ff7a0a69543aeeef42e22cb589e0b33455943cf84f0c5b28e93fe17c0bbba2fafb10aea29b28705eec303,0x053b939496e87877fb1569c911bf618056396fac2458757da71cd83fa152239d605c6a4e4e847295080ea3874f84a832"
       },
       "Q1": {
-        "x": "0x16af5b519e92362ce94c0ef76051510266c5ace22d2cf9c3c1ef20856e4669523df27c30e513444b436cef2082983814,0x03cb00c0a0370bd301cd45b0c08e6feea3adf07052e83a3f2ced57665d7484f5540db310f649387701731ff185b460da",
-        "y": "0x025310a94143c55175eb4929df2d8294b0268f3011850bdf46bdfb82749233e8dbb8070d623e3fb8397b079504d6c5aa,0x087d9d2c1cd911f8cd9844e60011a1d1c02d61a831bfd33b58c436d4305935abd3207c553c0145fd3ae1bf18c82011ce"
+        "x": "0x0df5643a19f8de7e8e45575551cfb8909f4a75722ec8fbc43cb8df284cdde9e2c61ea0c6116bdd86d84063c96fc7dc7f,0x1241a410598f1d57907850699a694720712feddb916f343db08f2c18481df46cbdf7afe8eaf214127e427736ea281c5b",
+        "y": "0x0ad66ed30cb6f55a83feed4b12c141bd41f593292403127b07e1bc6dabacd8ea53f8a322b5d4080e4393184c713865fa,0x0c4e6fb11ad2fe3a081a399df36094465aafb232f7564f4d35abb0092ef9ee855bcfdac2e6775cd7d383241f13ed856a"
       },
       "msg": "",
       "u": [
-        "0x1921dd796efec0b5f2ad9037e73b7470e6e7c85e6b7bf6e6827729442cd01aa55ac765ae451f497873400e90a814105c,0x0838662da53724510bb7d677b7caedbf3c4e19e55b42c9872c2af096272b26cb53cc522413cf4c54c1f7691bcdabfc4d",
-        "0x12bcf2aa2ec29a9dc0b77c942869af340047a27b57f549ecdd2e93fc5e63d0364fba13941725cbbac1d1e8c6e8605d5d,0x04e892eca8729b9a2b88b4b0b33e8c8d4ed52f7d0fc860e41f09de0a05c48f605a7a9d603b60db4f9ee49f888e4f3273"
+        "0x0ae8ca9aed945924c3a12f3b6f419cac381bae8f16044ab6c66b41999e4bd0ea169b44f2fce3634a0ddea05b9186c6b2,0x1134506e471554affe377f908c29fc7cd7d247b3a14f9e092b9f4c5b02577939ce01bd6b43d9d59d9a994e9fb5fb5096",
+        "0x0b28b14113885b1d8ad08f5da9111add00d8c496fb3d5d7b5d3b6558a058e9e62cd02dafa7a95f968cb3063f09fc0e21,0x03378e456f437ce445b6bc95121566d85b1b3b8ca057064fe7a8a1aad7e8a6e9f886cfb1704ad712e9042f4f002f4bd1"
       ]
     },
     {
       "P": {
-        "x": "0x0b6d276d0bfbddde617a9ab4c175b07c9c4aecad2cdd6cc9ca541b61334a69c58680ef5692bbad03d2f572838df32b66,0x139e9d78ff6d9d163f979d14a64c5e57f82f1ef7e42ece338b571a9e92c0666f0f6bf1a5fc21e2d32bcb6432eab7037c",
-        "y": "0x022f9ee5d596d06c5f2f735c3c5f743978f79fd57bf7d4291e221227f490d3f276066de9f9edc89c57e048ef4cf0ef72,0x14dd23517516a80d1d840e34f51dfb76946c7670fca0f36ad8ec9bde4ea82dfae119a21b076519bcc1c00152989a4d45"
+        "x": "0x1953ce6d4267939c7360756d9cca8eb34aac4633ef35369a7dc249445069888e7d1b3f9d2e75fbd468fbcbba7110ea02,0x03578447618463deb106b60e609c6f7cc446dc6035f84a72801ba17c94cd800583b493b948eff0033f09086fdd7f6175",
+        "y": "0x0882ab045b8fe4d7d557ebb59a63a35ac9f3d312581b509af0f8eaa2960cbc5e1e36bb969b6e22980b5cbdd0787fcf4e,0x0184d26779ae9d4670aca9b267dbd4d3b30443ad05b8546d36a195686e1ccc3a59194aea05ed5bce7c3144a29ec047c4"
       },
       "Q0": {
-        "x": "0x198d5f5fad8e1594ed98ee3d5f5b24b58e6cb8ae37372f6028e7beffa0e7a16b0958e13f92f322f513b85eacdd88d0c2,0x09288d195828e46e7c058b22115af5c1bde20cb7462a3f9d6488188fa937e2c0bee3aa188622312f87e12b48660a66d2",
-        "y": "0x16a0916a0c42492649701f0520c075d4cc66d74cd8fb4f9c6d2631cac1bb48e357bae0b97bb7f87f1b08539ac944f46a,0x0dd21353972061024a92db26e51cd97246c89a884ecad67a1ff8dd1da73a8397f54d41533ea2ac48ee4f5817cb09dd1a"
+        "x": "0x0c292ac371849207564e7b8f4edf47dc4b4d7a618dbacf6a322dc732f014cc2a22049eb69de11657c301cb4202b98541,0x0f37118e477c16005cae8f639e54119ff796eafe80461bf39ecce5c0192b93075febc80d4f73f9e0893adafa17b13b45",
+        "y": "0x15853304d7fd9f47df2ef6c4bd1fb0b3500386b23d1acc530be0c14e027f15b0aa83856d82edb723f3d857358ecffb80,0x0626fcfc6b3d8460df7ed2aeca6449cf6701dc7ff51c143ed20054ecf18732f4c5985455864c79a4065b13e26ecccf9f"
       },
       "Q1": {
-        "x": "0x17a29041f55a2b23b3a601b8d4f5a3e85b75cdc52650f26470884b8b367b20ef8f7e6f0ee8969b994f4132344a68f023,0x115d814e4f7973e7a960df53b494c2a0a1cd7a42ce6650bd7f46e55a2622dbf6528392ab9c8ff45d3fd97bd7b1dcfe67",
-        "y": "0x15749a8af1d35fcb409ffc3336670a8b47a117f81670394183c316d7bcd2a49b2253ced38b7d00763a2fe4afb51f0336,0x10624b1845ccd669e5edd403d68a603fb43e382c6570953dd9b9add472e422d1098eb45380fa870e14f6927252c4e667"
+        "x": "0x0bce3e2dd15f6acf55cce0e3a4cde190a6d45434a8b0ba7cf79ff37f737ed90dbfd2988a257db65e10e684e5876b50db,0x19c1ad3eb0abb3590087d706eb155a4cd166484e82cdccb2465ce193b15a27d919aaa37d1824a9a9d87f31fefca1baee",
+        "y": "0x110c9643a8dfd00123bb9e6a956426f26bedb0d430130026ce49b862431e80f5e306850239c857474f564915fc9a4ba6,0x1748ca13032a2c262295863897a15cd9a7e0baf003336bec6fc6e40b982d866fe3250619fdd2ceadb49fab8055f47e65"
       },
       "msg": "abc",
       "u": [
-        "0x0b7b2d371fc970671ddf7bc9ca4a70a1bd286af4487b497e460c0b44d405d73db576f8a08d59416cc976d4b1d0100775,0x0e86d0eb2d34c34fe8b2a1f2d999fa3dabcd504fdb4beb57e79756b08fd75b0a82660abc6026ecc4ccf327a522587b38",
-        "0x10376d048c060df1c5017a363144c482892fe2ce0061094327b8bbe49a713ce795726aa23b5402a271e9f1e7b9b6c7ba,0x0117f2ea63015e192d759f11a658a002e06112147d90f00d7429722456b9a1c63fef2dbe8df13168e3bd40af2fb959f3"
+        "0x0a7d239c9bdb41ed2ad810820a8b4f0703f60cf5833440cd684e386e235b0f092da91adbaa69562b911ebd3f820655f2,0x16302b56f5a9f538c7168cd5194957903b82be6749171f8de112c8bd3360ca24847d0567d6e42eae0c43a7fd8530b378",
+        "0x0a1cb4196dec71b1f704f3533cdf27f247e3ea175ddcc1ca6df0f45c587eb77efc6c493848f4df98e24a32753dfcf96b,0x07aac42db7f3dfbc5146c70ca0ac6157893abf4e2162e303510e0cefb8d024c24080b9c2a9896f6c03ffe680fc18b788"
       ]
     },
     {
       "P": {
-        "x": "0x0ded52c30aace28d3e9cc5c1b47861ae4dd4e9cd17622e0f5b9d584af0397cd0e3bae80d4ee2d9d4b18c390f63154dfd,0x046701a03f361a0b8392ca387585f7ee6534dcec9450a035e39dc37387d5ca079b9557447f7d9cad0bd9671cb65ada02",
-        "y": "0x07a5cf56c5ea1d69ad59c0e80cc16c0c1b27f02840b396eb0ea320f70e87f705c6fa70cfeb9719b14badbb058bec5a4c,0x0674d1f7c9e8e84d8d7a07b40231257571c43160fd566e8d24459d17ca52f6068e1b63aaae5359d8869d4abc66de66b6"
+        "x": "0x17b461fc3b96a30c2408958cbfa5f5927b6063a8ad199d5ebf2d7cdeffa9c20c85487204804fab53f950b2f87db365aa,0x195fad48982e186ce3c5c82133aefc9b26d55979b6f530992a8849d4263ec5d57f7a181553c8799bcc83da44847bdc8d",
+        "y": "0x174a3473a3af2d0302b9065e895ca4adba4ece6ce0b41148ba597001abb152f852dd9a96fb45c9de0a43d944746f833e,0x005cdf3d984e3391e7e969276fb4bc02323c5924a4449af167030d855acc2600cf3d4fab025432c6d868c79571a95bef"
       },
       "Q0": {
-        "x": "0x1729bbdeef9e902ab2e2bf6f90e3800231397ecc36b0b53d33ecb173bd682ef45a51e691d7c884965fb530cc85d6476d,0x07fd016eb7f3785362f75a0150d9e73d5ae13631c491075d73eab5c3b6ceb8391d909926d0c519fb83fbe889dae667eb",
-        "y": "0x15ee2194b053071cd1d40bacbb2650b5608d22d12ddeeae9fb11921e475ffea6d1c008fc390f231aa14589365c6937c7,0x15345785b7ba1db6cf6ec9f652dede47c86b6837b2c43f3a9e6984f95feecffb84bb5963df655068a0ad6b8d8a762fc6"
+        "x": "0x1552566a422494f9edd07e21ee59067ecf031f333b3961b710fac1245fd003552c294ac47ef982432f0f1e1e9d07c4b6,0x115a9de418d20ce3105eaa2db025d183cc679327c6d6a229960d536b9fce33d3242f9819680a9200265ec2dd02b44b19",
+        "y": "0x0cef664ee9270354c3bc06d1e0570e4d6663cc528711afca10118955990126f87917c87f7b9c4cf73aaf05c1b5875c6f,0x0b136f41d233ea420bc3658c4156f717fb190775d3690d139c0923c231e44af54d780119b8edf16038208b63feb1f3ee"
       },
       "Q1": {
-        "x": "0x18505ec8bfa125df7ea130e702eaa33a89961dd24ad06b3b3452da15f2394d0abec06aa3b4e9433c32fa8a7c6ef874ec,0x17c0d91f4c363a7ff183deeb4308fa5e8d61c0263b9d0ddcf304b2758e2b556695fe20636b4b7a2cd4909c145a81c884",
-        "y": "0x140b4d6603a96ef9de2a71a8ceec992aa72eb8c4f08d28de11310dcfd4d13dbb68734001417d0c1587b9082b593ab9ca,0x0ac81f1093f8be742b331c1c04e9cb0fb75ac72e87ae5da9fa395b043fb83fbdabe9e54331ec3a3a754f845939b118f6"
+        "x": "0x0332d5027c68f38ca78c6c63c013178fb58b31283a6135f6bf5629d18c76144accfd96905f51a49284f4ef622dfec003,0x04865f680c5f2203de00f95dd6652c9b3dc0d36361ee0df16a39a86d5f7cfc8df3674f3c3fddde88fb027353eac1a3dc",
+        "y": "0x1651e6cc8af2241989a9006dd59a9cd41fc1bbc3a7f9e32875889ae54913b8398dfa106aff43ff1cfa9019141d9ad565,0x09324bdbfedfb886899a7961f7827702743ef550f548bb89ab15d4b24c7c086196891fc300e3e39c21aec0257543a3fd"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x0022182b07cb11d26cbdab43e0d696297a7dfe1b8dd2fa8ded11f858bf25ab000adb1ec319cbfa42d1107a3ec9528b33,0x01160e11ac26a46322b4867a0d66cbb1d8b8f78e88a3771b7a832d18c65d65297692e9faa1f65719c9ea621578003c37",
-        "0x185e096fa6e05479e1f3ae4148fd4de985c73e414f9a9202d3930d59a09d90d87e545522a91a0d24c6aa3e2363a48a41,0x08e234820b6cdd9229490f5c1e05e82b8fe7b1efab9dfaabe3ea4158f0f8da855daf1e1f5382246187d317ccee520a0e"
+        "0x0e17df0242a3dd0e7454a4b580cafdc956650736b45181b329ca89ee2348570a1d7a221554c7122b91e6e3c3525d396d,0x0298e9fa0ff37440cd2862e91c0a27fed05087247acf79232f1a4eb7cf8f65997a92319a8cbd00f7b73ee9e82241eade",
+        "0x1200056764f11beacdb6009acaf823e100da27b4bfe45e94097a52c1fed615b32dbc5503f964ab5277a7c30d9a2bf0de,0x0d1d7feb418f29dbf4d4459c839dd33f904d4292d016f701b35e4a7611798c83de1b7deb1c6c1521e9142cc36a7d0579"
       ]
     },
     {
       "P": {
-        "x": "0x0161130ef4aa2f60f751e6b3dd48ac6e994d2d2613897c5dd26945bc72f33cc2977e1255c3f2dc0f1440d15a71c29b40,0x06db1818f132a61f5fe86d315faa8de4653049ac9cf7fbbc6d9987e5864d82a0156259d56192109bafddd5c30b9f01f5",
-        "y": "0x00f7fab0fedc978b974a38a1755244727b8a4eb31073653fa949594645ad181880d20ff0c91c4375b7e451fe803c9847,0x0964d550ee8752b6db99555ffcd442b4185267f31e3d57435ea73896a7a9fe952bd67f90fd75f4413212ac9640a7672c"
+        "x": "0x0a162306f3b0f2bb326f0c4fb0e1fea020019c3af796dcd1d7264f50ddae94cacf3cade74603834d44b9ab3d5d0a6c98,0x123b6bd9feeba26dd4ad00f8bfda2718c9700dc093ea5287d7711844644eb981848316d3f3f57d5d3a652c6cdc816aca",
+        "y": "0x15c1d4f1a685bb63ee67ca1fd96155e3d091e852a684b78d085fd34f6091e5249ddddbdcf2e7ec82ce6c04c63647eeb7,0x05483f3b96d9252dd4fc0868344dfaf3c9d145e3387db23fa8e449304fab6a7b6ec9c15f05c0a1ea66ff0efcc03e001a"
       },
       "Q0": {
-        "x": "0x08420c5b8d9f73ddac45b6ce050a8876e5014cb8783bc63a24eebab5e0ca75d547b51025ecfe75f4efadbc8d71c145c5,0x1915fda1fb71039148f5d346f1c36df1630a2f908881f29de32a5c2782eb6eb3c8cbe58f8c1bf8d348319347c6ec7635",
-        "y": "0x0e557684bd3e61db3f96df904c57ee1e8e45f5aecdda654ed741587082ad91860d311cae158569c217c56bbba3d3f25f,0x0acc1f70e15591005ab8bcdc7b1b19e3c16a6ee6c7a17ce83eaa2771971254be34726b266c076abab6b9b477ef790261"
+        "x": "0x089b04f318946ce75b5b8c98607041488005ed412a4a99e7106b340427d35682036cecc076827e700e47c17f65ee3f09,0x03bef411c75f97147673952b19ee293e28df019be2fdecf5db09afb7caad4a5e984750b19c2007b50ae0b26f83088e8b",
+        "y": "0x18b1ef96738c5df727e1fa2098178fe371751c0c169af30bdb95be22a0ecbf0a75c0e6c63e4a32f241250f877859c086,0x0d04c624db798ca46a352637fa76516c83a5d98e147a25f629fb1e02a9a453970e42d835ba765bd7d94a4a3f9f50e4a1"
       },
       "Q1": {
-        "x": "0x0cabb5826e6bf948e30cbb094b72685aa1d93ea49fdd9d54828b7ffb9df582e3d9405f33b9ae3ad3b6fd51863ff68c56,0x0604d687830b1dba2cd28c644709475c7a5427aa15278df2db06f59a48bcfb52061f77b6f5b637fc345e2bc64aa7e5ba",
-        "y": "0x11e8a23425631218f3249f1870a8b1a17d82f3224602e433ff04a5525e827582ac5898e81972e21618e41e5c5edc03f5,0x18f405a27aaf3803ef88b9f4d3e5d8eed901d980ebbefb71d5816ac2f1975c513965b7556ee44db2f74202ac178c72e4"
+        "x": "0x121b1257fbd3dda5f478b5de6aee2ca88780248c59afad1a9c9c9db5d03752792270cecc7cc676a1b91ee898b7f76977,0x17eadb5c134a1cc0305ad5d99f6e2a1cd906a2fdac318d4356527c70fc94242ddb664486c814ebd5959a2cf4225a783a",
+        "y": "0x00f0793bcfaf12e5d23fdd4173f7539e3cf182a0f5a1c98b488f59daca5ecf7b694912a93f6b81498a5c2282c09ee63f,0x081adf3c45b42c35fdb678c8bdec1d8c12f9d5a30b22cf52c1afc967d6ddc82fdae0673f76a5186a84f3602c7a22f6b8"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x0034f33d3e0b2bb1e396fa3716a02682ebfefe6b99e986c356c725f4bb787714f66fca8aac0581b538ae255aa69aa8b2,0x169a32a329b295e56423a29a2fa15b259f5e27f992c1391b3d333a4a050d8264cf146b1baa641e609ec748d74d6bfcd5",
-        "0x04028afd52de566f85dec8fd409112d34f09ed3b617b31bb23b0a96d76080d1dce671a910785cf63d4efcc20112f4a67,0x06d00ecaf61b0f972b521b223aeed36d1e4e1e6308b36dea9eeeb917619499d06615c275ea39cc4d7db697e4b697d40e"
+        "0x0ca92554c8c45581eac2eed7ec2db1fe757af0a2803dc8e63180600eed2516f64b1c0d850c72a75c417f58723815795b,0x12ef692f69b1d61854b80e071c7fd751b19da2c194ba0fbee9e68454073dd3693e2c56852938aa1b090991018ff15a94",
+        "0x11043d352059287fe7424285da213d4cc414df4d5592ee2507503088b3f89220697753ea8cd47fa13c9a15dbfb0ef20c,0x110efeacfff2801024c019cee7adbc3d8144c3b73c548ad8f0759c4976e0b3070293056f884dc0a1b3728546dddc6bcb"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json
index 25c4da1..ddb5176 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json
@@ -12,65 +12,64 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SVDW",
-    "sgn0": "sgn0_be"
+    "name": "SVDW"
   },
   "randomOracle": false,
   "vectors": [
     {
       "P": {
-        "x": "0x164c24901348f035811139a2ad95042bc85bb4b4481309431cd98503c951e9cb8f29d3c4ad0abeb31a3da4062f4b9027,0x0cbca2904d96a263308df43e2767c4165f0357a5f0abf3419acab6fcf2200002b0b018c574f9253716844947f2752c94",
-        "y": "0x12b642193b7beb7989fe98c06482effb8740d9e744ff317e050f758bf449d6dedfded2eb1b1b3314b8699b9ea41f9fab,0x0219ec9ba08594f6e1582fb6a6ffb795a92551b32191f146296d29497bbafba7b3aae8ab2f012a5780f72cb0d0380a78"
+        "x": "0x001f5fd916a2b24f6106bc49cc96d35eee8ede2f7f9699e316811519904e7b2803583f7078de54b1794d9f0704b85688,0x13ecdb8d57ecfbec3ea381839df152a26e9cce35b492daf3d007b3250ec02b64d8080b4c8016853b388cea0b5489bc25",
+        "y": "0x0c0d2918e5d653902be579f05c2b446a77878d778d03a226ef0b73412e793ecf6256e8cff50b8f5c8c7b3d5cbb8db2e4,0x03351116cbeb320b89c9633aeadabfc404090131811f1f9bfebe177a1920b1ebd5335eb4e0c140394cf00ce01ac778a4"
       },
       "Q": {
-        "x": "0x033aa78402bfe8ee9117ac5501b55e2d1cc133a36ff2351b0176e7f44b009260f9f984be5aff18207a751fee8347250f,0x0f6512f645a015b2917bcef9407299bc46e57344ec24877b681b2c7b3c8171bbd0efe0074fe5eaa7fc74983494f90521",
-        "y": "0x02ed21e9ce037653ba12b3996f085847db2daf80e0033013a67667c6c53983ee76af4946da08c7186164ed50d225551f,0x05f95d63b6f2d45bc79824359754d23c795f98be958384829ea72b473525f58bef08bbf1c09ad153628f2d3ca9f44bdc"
+        "x": "0x0e28eae4e4db410713f183018ead17eb7fdf149dcfc8d9bd010021cddee0d4988c9d3456d6c3dcb6c57eeddf65076edc,0x08b791576a8cc3b65818b7cb88188a1a63688c0724758a452a31e177b4900a750450ffa44f912c600b2bf45453a947d4",
+        "y": "0x117b6df28c7b9cd8d208c6c7ec1453e68c7c97230843e076f03941dd7f8c8e310f93fcf7560f2a490cf2f3c462f64b30,0x00849eb75f4b8f5c4b3ee6a34e267a3e2a0416f1d42e5bb57bb5fbcde448c01c632fea40524353cd7851dd8e4b4fcb8c"
       },
       "msg": "",
       "u": [
-        "0x12e76b1034fcb8958d47b2ff763642841556e09d524a6e1ac146009e7b0a60e859567d52629ea27abc86996632970e99,0x005f69bf4eb6ef49bd04d4ca394c77b9ad359646e2ed36e013dc9491a64f2d1207734d4b91b53fd71a32d9e966d46dce"
+        "0x0eef24c4eb118a5bae06055c1d98a9ef9ba4eb0f2bb749f63f2eedd71de7c7af27d3a6e4e17e5e2c611650521ee6b0b4,0x0908bd04d29ef7bfc7827b2e887ad025131aa38b1b96f15e8795475a477f6e82ec3c7e0546a36f31dfd2a0c031b0c707"
       ]
     },
     {
       "P": {
-        "x": "0x14662fda486645b71a497576120b99cd0c8fd72c52ade4b13ce4de57ca05acba0facf6bdc1a230539a96e97fbfdef9fd,0x0646f0fb608d82ba68075d6af75c61b762c5b47de2c620822e88acd296fcfecf125113392b582c48c9c4cec645e7e817",
-        "y": "0x097b57eed2bdcc07cf6518cc582af8604d284f51447d572f3c8b3c36c13f2f5ab3448d06a5e433a0a4753163469977b4,0x0d0e9f7c5c51da1a8b3211052b0562b0f19690027d2bf0df3f662ec9743b0b39c6b9be5b5bf6d224f7eff946b3c4a149"
+        "x": "0x0ad0765905e941f59e03a3c3684430c8bb3470b247a70b2e0fc50e3dd0d6a3aa4bc2a970660aeaee1514ddbd02cb3bb0,0x11ab385921eb2d52affc127ce814c5284410a68d390f497150729a717649673401d52f8da24baa71c696ffa904ce0c79",
+        "y": "0x13f087308db9972ec87a9cc3d4064cd630734809829e5035e83d6c12fa9bd4fae2af9509ca80e5b34d04deeae5b1aab3,0x0cbfbead826b4cf0bb5fb7a534aa700e18fc205c924b5ffbe105bb037fd27560c537c6c35184e53a56b392313a8ea036"
       },
       "Q": {
-        "x": "0x065cca134296b189b4587c38490d674900cac3cb7a6e14ff96f415eae6ce4ee51696910182471d2542b86bc707a40230,0x088edc31bb54b91389c1c057cc5b69e62eb06f72c3184834ce60bcdf1ee885ad8e03005230bfb15c89109209d8c7671b",
-        "y": "0x17c0ef47c0c7960baec68b33d1ce4e9a54c2c770956cc43afe93d8b4bb07d5205fca8f785d55010111367b529a13a67b,0x121a0b8aa8dc49fd8da99eb93d9d736e01e65a0e72c9144b3ba87416fdf125a355f38b5d98e98c20744cbae1c344386f"
+        "x": "0x0be2212e9e3f4cfc5b14f590e3f1e07daf0f37cf0859927063b98f009d4cd93d524334019b0627147fce0c977ac4b06c,0x0e792f3bdd691b2ec82c46b1d77978ee1f768465fe779805eaa1e83f3c2c278553cdd4f549318fd2784156820a24c287",
+        "y": "0x0fa287923f6386606d240fc06fae037b04324b63523cae055e9aacb8d70988580690407ba3e7055c1dae0db384808eae,0x08c9c5926bacd48744e8e365fb0f98e394d7a55b47d9c896ea96fea516b09f53afecae1fde28afb7033cf3d3aad74e7c"
       },
       "msg": "abc",
       "u": [
-        "0x108fd37b239357d783a30c9aeea3129316f236cfa8e279bbd921ea7c642ffbb69e4f731cbee57b2df7b17e9ec19c8c91,0x110587325ae905e360ad84368fe6aed5b8636bab77eaac3921c0468154c5d72ddd3ca2e9d57d393d55929344a34215c2"
+        "0x1197064aa416ed1d2236d5571ff99c5956085096acff695a1b59395b2db29cb97b465016b4a4c1ecbc53760a05f1c600,0x062e7c9bc14541239dff3d241091d3f0cb14c37698dccdd34b399835b2cbcd9fc7a3ebb25bf5c2ed6c867a3504d8e028"
       ]
     },
     {
       "P": {
-        "x": "0x0816a09925c45e39c3c04d3fdb331613f7308a0d5dec8e5496e4aec5e5a67458532f25dd07c6a793bc4be8be17a9fd56,0x0addce3d065de3f0e1b4ccad3e503b570412818094d1639329e7f4c6ad759bdcaff01f234ec3f1ebe71209a0773e4ca9",
-        "y": "0x1214b5de271352309fd0091b72eecdb6224f58af9c76ae47a2b21512fe194d5c08278bbfbbd3468ba4ef3abbdb0ffcf0,0x105bd74edfcf83e10663800fc4aca1f2de2e3197b6ad91c246c3c9828e24c44384747b95a8d156da7063df00546a6bad"
+        "x": "0x19d2e82a836c036fb0441e1c4ab657883526e732f0baae8b60e35abdb432ec59c1978ba52f36a1f93c821d9c249f1a01,0x077ebc79f190a4dbd11fa52f43fa8b339769e25b612d8c9cb1a9f4f487abb91b6e686b3fe3359f9b9864758623d0ccf5",
+        "y": "0x02eabe731541c963778438ce58d7fc2882f04709c048827ebb9da7f08db7b80a2aea077becb561302f03691c512aa9ba,0x114479c515e30ac4ed68f6950f31898e01a15765d76da4132eace76a3ab1d5922e22ba7333619a3ca044ee568bdb126e"
       },
       "Q": {
-        "x": "0x02da0a79d42b538d42ffc67176681d80ca8d0dc26974d3a30440ee92a362c13bbf737b414fbdf2fd8ce635a396e79ff0,0x0e91dd04cd2d2e112e503efec26f84183fca55101c36fa41226c72eab8e398a189c9cf2f4eda77f7c9a38a09a563b2f1",
-        "y": "0x0d3d3ca0d4ec0aff793a69c22e2abf333e8efc5a72b1d5179c19479e191daff895c95f32669672a1d3df38b1a184f8e8,0x069ab87711da7286d7c75f8cdd4b1e2719554d7866139e948851bc14d7e9124f6f969118bdd2ae3db9d8f997b59717e2"
+        "x": "0x17baf01f2408702e29324660ec3a7415367ac32a5364c1acb3a2b97f83923dfd7729b729cab2234e12137854bcd2f059,0x00316054f1f0f5dcc0b7fe04e16d59109098c6d0bf8f6c32bc5d3287439ea082bdba9269bae4437acacfe84a71a49d63",
+        "y": "0x11618a2b53afef2553e7afa57495ed03cb7d072e52067dc2368d17dabf149ec2f70198efc49c7545f9818827016d3408,0x0f1ebbdcbd6e2201799d869543362d8c7e1399dd14c9fe3b466b010c1b5edb30739b53f64abd24fc396328e9cdbd808e"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x183b05a0844e652153f50ef0ea7e12bd9174707faf7fa3ac3d4408e8f06b0c8bae4aa322a71614f7d0380986632f2261,0x011b40d28c312f5f62289fe083c493c84ac5c2e66f8be782c1d50493d30bab14fc88966dfe4d51f53049d1e7b221e0e7"
+        "0x04bd797baab9a7dec6a33e0f2ecf148bf13c9f0ed7d414db7f7e78bf654c7ff0366de76acf99b114b210004bd207ebd8,0x011cc2dcb9c22912dd0c3ca91cebefe5e57c24f2317dbd0ab5fe7ff6454d1dbe1a5e4e17d92e7bffad4fc12cbffb16b7"
       ]
     },
     {
       "P": {
-        "x": "0x0eb76ebb9399768c509108314b557659a38bc8187e7ab742adf8c672da98e2a7c9714e0e885070ccb7fbbabebf7a7bbb,0x04049cf80dd5f3a2734402d6ef6ce67f35189a4ace622dae7cf02b8b9662cd58f05dde5b6920fb93c6126c5895e9a3a5",
-        "y": "0x022d29c941c40481c8496f4b1df9fb708103c3170e99ffe41942e79ce8b0e35ecdce0e9281da60a685bafe07f9a635a7,0x023c57e63304ec8997a2b35ab78a2d060ffde49ff0235058ffdbf129946672e518bb31506c53dad9c8a30b751b6181bf"
+        "x": "0x12b242fc22a527edabca13f6e698d6476c24cf2a854c8bdd5da3bc00e190874b0db2a730ddd03f5fbe36ca85ba99c3b5,0x04f3a9d0fcae0a360c08ab6adb11fb3c154164ebe3900990b265dae899cf7869cf6930cfb71f0ca965eec11b226f9485",
+        "y": "0x0de39be8863c3e4d4d7a0536780004af090789f94e1430fadce34ea39330e7f276b327834be0fab8b95a68170bb252ed,0x0962ee9b5b45333ecd3fde52f26e4193eeb6b78d49c7fffa3d8c40052938e118d0e7b9affb8bb602fbcfe3b73524463a"
       },
       "Q": {
-        "x": "0x1764c36ebfdb830ad6bed870087c5969cc95e16ca57d572047f8bb17ba961d2264c86726ef69ce6122a4459a6025461c,0x0d27880f35312ee235f2dc9208cc679679261e7f909072c5b71b14e369e20dc0c52459ace34c23aa6842e9b4663073e7",
-        "y": "0x07e98c5d7eadaa88299ee4ecccf848ca9492db725c45696596c50000cdf4852cee8d4a0e3ec0ca4d7b048ab0d92a4dee,0x00b35c992495fa745f8a3b765a2e7d7ee06e7c4cdd6d26be78b06231a98cf9fd6b585d24b6f7a659c45e1acd64082af5"
+        "x": "0x152527c9fae465fddae8ec34e3f8441e5e1768cb316d121a277e182cc1995157359c0e4fdf151e77b070baa0ebab4dbf,0x057831fc9cadafae5d8500bddf6c7b1f4e7b7e0df77ff0e3cda3d1150e4a33403d293a9c2bb441a4424b26e3a7a78781",
+        "y": "0x10fadd422a4aa508bc54eb926a97336d4f0c17448ffc71ed4b0a34f6ce2546271ca86d2d701021c0d940cdf0cfca6f97,0x15cdafd712b63fc2bd0e47caa8ce68cf2a125ad70cc3a2a166e97c6b270070e7cf46e6207a9d9121eac906adbec4bff9"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x09619086497c2a6933c45e2d330c560562d87d3b2f77f1d2da51525fb630a0ba2bd03ea9ebeb65778a65b29f1092a99d,0x0c3c45a61a7938b2a8a645c48c37a2e2e957b5ef5bbe3f661e8bdcb50e962a548862335c8503d73c1d28c5dc598ea29f"
+        "0x0cd6693615b9cf94b465a00fee61765ab3a531dcd6ac6515255f133b46ad2faaa0fcefbcb2d683d6a63f2742a10c1bc7,0x116f472765841380180b72806c9c323ad7ef71ec044bde80dde1ea7b8d91b3aaa09112fdf2be583d1ab4aa409f7dfb63"
       ]
     }
   ]
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json
index 6d1955a..2671e51 100644
--- a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json
@@ -12,85 +12,84 @@
   "hash": "sha256",
   "k": "0x80",
   "map": {
-    "name": "SVDW",
-    "sgn0": "sgn0_be"
+    "name": "SVDW"
   },
   "randomOracle": true,
   "vectors": [
     {
       "P": {
-        "x": "0x0d2b7cb4e1b0f001de23bda54652814186434637442e61bd7ae665f78e3e8429a3b0abf727b6ffc1a7d5d7f5683c2517,0x0c6519468850b1b6b34c2ac7a67166d9c2b842df09105c8644d6d9be03880c56452e26dc82ee93d0db99946acc2675f4",
-        "y": "0x063e54fd52fde42a5d4a0739ce89956deb0aa4721237b581a79af5e6e847dc047e0b0a41502975e4c15bed99cdcdf0e8,0x0a04fe752f02d57217f2eca100582f9f60fe464aaec2e94624ff22a2522d562fc251e3e962b00f2a7cb544bad462487e"
+        "x": "0x1247e409b2a18aa704b37c891ad429af1e81a7d03d97c1651d072a63acc5585967939adfe6b41e608c4cf1444be4ebaf,0x1379e10a574e45e6e8ffc3d403bf975984237d4e0dd350a2209ee5025b738827620301e71bfe4449af7b9ea2a8fc0464",
+        "y": "0x0f171ce60457b1bf85847e48469e8a50e28b26e126201664b2eb962abe38c0eb2e1e84c953521c6e8cd82fe25fca520a,0x02663ec2937ebd48810bbd17d88f03e9abea73025d7a59c5b7a0db80ac3bde5b1b6fb55f825686d170702f9a0b354e7b"
       },
       "Q0": {
-        "x": "0x0440b705d56079686eace2e3d2fc6c26ed4349ddb574bbb13ef5c9c25c7a757b43a1243ecfc62f9cdd169d6360c21cad,0x061b98df942271495e7259a7010ed74c6bdf0f83fe225c7e60fa91b3699d32a99afa440f1ec380aacc8d703649631246",
-        "y": "0x12964591a5a374d4ed6f1306e1889d8ab5259e88928cf0900c6f4fc64ca2cd7d1cc992166f0515c7ce53dd52efe3ded2,0x1440790373a4369524884f589eff8c3ddeb82ad6032446072e75c3b09a300bfd9303a4794f6676ff2c73c796f9110557"
+        "x": "0x0c518ce5d2e9e96a19ce4737e4f60ef6273231e706540bca662697e16303f0066ace3544d272492b5c01ab2a20d08d0f,0x132f304e07b3a827b26eacbb0e3af39a32b260d95ca86e63aa2f8d0ba99b6f6ee5f15cbcd3afee9f9081879d5709c565",
+        "y": "0x021575725c8fb5107d5ad64c1f178d923e19203590dcb1b509af82ffbf367b9c4cccb89301f0aea987dc788d44547f55,0x00a2ba2f88f654fcde8197b94d1605c24515a5cb7823288d13760cc23e49c424db9a08d37e1e55c425f1334894ce0125"
       },
       "Q1": {
-        "x": "0x01146e5fe16047ea58369ff4e6f53ada22c23260cb46b4ac1b24a7054691835c6f45e3a8218ed67c68a2c492b35a89b6,0x196e511b97c1f3802e37478224bb5ce12082cee5dd8e5630ff194d8537c7b30ace746d39c051cf3f6a836a861f0fca71",
-        "y": "0x16860436cd82bd22c166a92a38bae79036e357ce185ddcc481cef46edf398d377b5d85f38325be63270cf09c31329583,0x067e5d9c24201fa688bb9101b96fff337625778d0a6cb00495fa5aa8840bfed134b7b1bbd03979538b9b9bb5222b8a99"
+        "x": "0x0fe40888ce7a67c99ba37194b2e62c77c9d2fb5d18d71faf81a4084b8edc805c30776a46dbe6b749ea170868bf4faadc,0x1918a1f78646dc0451cfdd37725fa080cfb9d9ea473b0f58a9929b7b31ab8da8547346a091a7e2b3d073e3cc38ce0b12",
+        "y": "0x152eebe67adbeb41ccc8a03926448c9dbe6692254203c6378f00a7e5bd56acdbde4ab9e8d1809aaf405bbe5ab395e385,0x070cc5025c561c1dfcca06ba88853300d4314db466e187e60cd1915c735bf2c6dc3bd0903d988d7d9b3b9e46dbe3ee1d"
       },
       "msg": "",
       "u": [
-        "0x178a86886823673336e71d5cb95ef38381506d64e1251fe3f66c2fae08f5c1b5d1f01a0f09cbb29e8d776345c7601941,0x1200915fc80bdf41b2723f5051a642fee4f548ebdd6f90da9d34d8f477fd17f84921be12497be94b9061bcc9e977a958",
-        "0x0c2b3e012f715a94fc08bd3757ba7c979d848c9719264d2a6b07f03be4f236da0f5017ee8b92fa4fac3ab88c64cce667,0x099e1f36e1dada16e9277160ba74552efaa0c939a629c16fc8ebda75421af560a7ede7cd4423f00ffc1a12c07ab05fa0"
+        "0x011a69c0b78b463729c1e9e6c7a543d4c10e1880a6a5c92748db6708c7492b170912c46abf43a50d6af40345ceeb16db,0x1216c67865d83536ff57ed9480ac3ee581b7edc25860f73e2ed967c40f5647a4bc25d54538e14a0404d550acdbe8056f",
+        "0x190bfaa5cd1654a6f71bcff0265236fc73a1a8c72f637b13fa9e3b7c69ad7a82de6419893f1a4f46b0aefeee08a5f877,0x001af2852d68aefb42258ae84e63fa04f45e0603a54d245882a2e2373484d49277d885983e300dcc8a7632c476f6654e"
       ]
     },
     {
       "P": {
-        "x": "0x0c2e41838e536c79576d6b34974204b591f0127354eac121b79029886a405615b273a6e1a78476d5d824d781b885af26,0x0dca051f4d106f072564729f74969ab9e557760e14c67c55ed38fb7e2f3f4b26af1ce227c963fd06a5c5c2745f082415",
-        "y": "0x12e8f2e906c3bac97820bd1cfad278d03321ba3d650a93cea80d4eea70271aff8f145dc6d7c32e4e945b4a213a551871,0x006d694e36dc47f3761ffc22d8a3cc66a9abe8851ad7dc42630a573f569692d46de02256b9bf98f1066be5ce38d97836"
+        "x": "0x14dc75415d6482bae5db292316e9fce2a9ac7c9591222ba12ef70fe4ad5ddd2a95b696857234d9114812394b60f8871a,0x121be08f8e5ebfd6bd080250aac7cde4ceb5672b5fd470bd8a92164e7b7fef93631da6bb514892cf913e5ba6bba00adc",
+        "y": "0x024233ce610d08957a91a989495af524ca3c4409e7f2fd38164ee7e76fc9694338370d90d2150f2e602bec35eda9e22d,0x00bd976560d390194db01606af280f74b6b4282d4bf3f6ed2718ac67ebe1507e52eab74fbdfdfdf0092c0d9a106969e5"
       },
       "Q0": {
-        "x": "0x056eff68c169148bf3cf4a1e3dcd47d05f172f54f0f0906759b98ee48897090c16127085c2f9a16dec9ef0b73e1e98ae,0x0245cec38af51ed121d2d2f9ba21469335fb2eddc2c084386477c53d2999c65182d43285464927b5f63465599955b283",
-        "y": "0x1597b2110dc452b8083728a6ed061340b27cef4b2f96c7c4c74e3f090577407f2d8e72dd12e5a642eb0e0116d50d2900,0x040a92bbe9662fa154a7706b0b208bbc5083e2909de5e0feb243c4aeb4c2abd9201d970fd586fe9fc3f7b70deeca38c0"
+        "x": "0x0d0c596608ea6ae9b18b6e55d21663933db8256234f5c2b3b3479b7bfc490f7828c98f883e1a63c58cdc0fc028d4661a,0x153ca080b13248f5f6b863a409ff2df352041c19f353f72dd0f3233a1ae2fdeea6e31a93a7a290a99a56a7cfe8448ff1",
+        "y": "0x012454a1f725b9b478ebdfaf0e56870fa99a15ff3e003c21a155042b44a39cc3a36421b7e11112da0a43e8528b15f820,0x0116d64afa9e422e1d966a93b0e3a0e40c4e34dc34a4c7b2f71e1520812f401baa979c5c62e67e4adf15ce4a507f7db1"
       },
       "Q1": {
-        "x": "0x0a231b6efadfd4cd9243b2d5f8d9820943f6616bd34dc48b677783f0d298211d06b9f25e7ebaf5c3d53009c99b2371bb,0x0397e8e732c84a631df79723dc4ce49aeb1a08857cfd4272ca2b41d840862588fb75ac2555f127b3852942d5be5d8f32",
-        "y": "0x0576ad544c7dff5cfb6fe52857e89f1ad5ee0f703826471a18c6e8a28f538a87de1d02cca1a4aa7c1a90f0f2e1efe9fa,0x16eae9ad925c008d00832bad8830eaf05a2e693ddcf1fbb5d2702515fbbac163f0b12369e5466bcb30153616cf1a9021"
+        "x": "0x0083e95f0c761f7303c593bfacddf994635f12704cec7d2a1e8ce9ce3186b20acad0a8f63ff94cefd67400c72751fa29,0x198853939c488f8d8e5bf0839aff9aee5513205a775a541ea3fbce3ebc27395f811147593a7b51e4b1874cf14c8a5c59",
+        "y": "0x145f9d0d73567c83a5fccb0b05afc9585d302e1fe2e60fa91c673e12a2e760e74c64eb88c7747030b1b50ec8b8111d7f,0x102641fb2d3f4866926783d40d04d3b0f5a6ec4f4aab132053499b50922a29dce7f535502e4038b1a8ce7ae79d2faacd"
       },
       "msg": "abc",
       "u": [
-        "0x0ecb785eea491ba407b29812dd080692d7f654fa9be80e1b930f90a2764157ec6522aec0ebeca35a440b524b1efe2ade,0x02f7de24231dbff773ec0ebdf9b1b7d84713ef0eff9ff8bc356163c34bc42e373abebb437568b9b8a7a9622f52f8f64d",
-        "0x09ed2dafb8141db58cf0e3038c1b5969742a15dfd3a8de689309ad49477a8c4d45f0b3029d216bef8197a615b89ee53d,0x0da9396afba6386ea945d8881d5d1b4e892ff506940d11f1c14e11008650abf458d6423185935f13e5304ac325996fed"
+        "0x08dde2c4f9306a44a460f832d9153c2eccbb8588a7ac35b8476b006be691ce1b340486a56f180be2a022f3cee642ea2a,0x05141fedc77647e15b94c7dd50010f0ab062f44dfb25bc4a127f94aeede48e4f5782c83a29c98295d27210c7ff74ba6c",
+        "0x0f6d3efdc539af5edd8b806160272c9699ab924f37d161509d4cfa5a589d796d7b05b78fe5994bd082aa6765ef468421,0x00ba433ee89bbbb64364644c770149bba3d8fc6de84e2c057fe7ea027fab92261a40a20214f4da43375f5d55d5c74361"
       ]
     },
     {
       "P": {
-        "x": "0x103b9ec29f230ce504d06b3d9efbebd5ef5cda2bbdbd09e66ed9979a84dd4ccbb86bdfdb4e9673b75af702cd933b9938,0x17bb4ca24579cf87c16a554bc92497a67390971ad25d60a09befa7799b01676cdb30308ec0ddae9e4a5ca485200bc01f",
-        "y": "0x161a632c2847e27715f550ea93ac9897dab5d7ad483cbf180efefaa232f2bba706bff16b1f1c3e0b9da9ff39e160e42f,0x047f0b3db455080f13114bb2bbe37d40abdc9850bdc724f27a9ffa7bbd8307739fa1b803d69c30da64586c102842a3ae"
+        "x": "0x185cad2867dc5c11b0f42842adc2bc16ebaf95c761b5d26541a089c19f54e5039ad911b2667de073c26d01911d203d58,0x05e0ac4290a0620d1b5d20b8b98ace6d1b198273e05a36daa18b3c591ded4bfebbff7a8bb3bc2b9de009d5e9d0a78a12",
+        "y": "0x025525d91f16601d32379f4d5cba4a256ad84d40423ef294dabdf73e351f86b583c848f974899815a40c569465c68c7f,0x09aa43a981af5885a0f86a1b9a143abbc1570d1bf342f8b506ff9f9bcc15dbb12a8ac062f7e37e06b90881b8cbc1f4e9"
       },
       "Q0": {
-        "x": "0x0ad81631edcdf51ac0df8426a5d49192326f94244df93b8f990b9d23c2fd654b8f310a8bc0b136b649271a2ed598aeb7,0x106a7d7e84ca907f28cdf2e2ab98a49d53aa70f512afc0c764fdffe778ff3538992546decf48142a790700c6eee5db70",
-        "y": "0x0d9c4f07a23d596b3735a7e275a4a8ed3ac7b6849d83adf78b2743c6cb180232d5f180f7e32422c5e81039f9d48f9cb3,0x0b4ee768a0d0525872db9e4c511da298691aa7a3360a38cfb89691da7c9a314a8d461e8cc8935d08b6fed60ef149e9d9"
+        "x": "0x10319d966d19e9017cd0be3c551e4001c3e9d75a25e1700c3443b7756ae94fe1d442d6b3839d505682fa82269c7e910e,0x1860d1ab41d2ffe81a587e6919b21348bb437a8ea88e932525c803d5c1ee68bf47f515c445ae102cde5cf5569de63970",
+        "y": "0x133af9a9ac415000202b1a1fc258aa773902a937fa09af32267cfcf32baaa002eb80b1aefa92ee759867cd9222c55ea6,0x07abb300d3f1a89f91e55b1abf628f83dd967a97d81d8938c876060455abb77dfc9ce41c5a0beb99e9feb684b9f18d4e"
       },
       "Q1": {
-        "x": "0x1351d14d9737ba5ded8fee48ee1e45c823eaec7b58600a5af7c3543c0b450c565db1e1d37732182dbcbbc31ea33e3e1f,0x0c5ddcd88ebee0861a91dde563a6785752fbc5f4e079665ca2c0567dac8f203ed81f609e27e223938a55534ba8693657",
-        "y": "0x146bbafa353ed101672c21e98fb2e1aa6f438c918d963b4f05e80c36cac3769ad25b49720b8566e1ea1eecff77b010cb,0x02613eb3f365b783461d0edc9b3212495ae6f4de190150b94bbecaa6d631a6ccdf09335ac6f6aba57d70ce06d1a6d615"
+        "x": "0x14f0b1e5f3d5b113514a1ce6eb17de28d84fb686ed72b9a3091a9be545977acaae253b65268c1057abccb2c47381a7b2,0x136ba736cfc5c767b74be4814e647516ef71e512623d481ec17c6d89d65f536ed679900bf8050bed93a5833df4c032f5",
+        "y": "0x10e035eb449a1ebbc06431ee73251c7a94b96f83102bacb8c3a6bbacf32486bd6715dcfdd1c1a5ac0058f4fd7930e22b,0x06e89c91fe9ed6c5f6184c5e3766d7393002d06cdffe4b084a5cb4fd4ed71fa5f82590927ff983ea84cb7229a688d071"
       },
       "msg": "abcdef0123456789",
       "u": [
-        "0x15788d0f014f083f4a6bad1e3ec01905fb81328fac060d575f9220ddb7fc495f6cca48e8f46c69153ef0152caa692bbe,0x0c50eaf8096785caee1e08ff3d9d46b8e4c1a1600406d4ab8c9c96c74c4d2b6b90fb5ddb0bdf7adabe0b176f75005df7",
-        "0x0274a965f4d5b3c5e1d35e426df580885eb9aeb4d0997afcb51d2aa908b7a7a5d2b608b4b054fbf77eb2ec8f6854d192,0x07be630ece05ab3536328fc3ccbbc7b8af99542ce0a7241bcf03723f9b45cbe16d3003dd28fcaaa4558f8f8f261a654a"
+        "0x11cb86b80f5715c34ebbbfd2b535a765de4e5e6de719f804b86e5d0e7415f00a2123397e06a9fe969ef09cd84c4d0146,0x10c642ecf452b47f5dcff39e3ab10d9b240d9511837f2d6eb152f86b2960a2fb8350f9d0387f8a8899a58bd2c5691b92",
+        "0x05c8d547790510132e87b818de01994a7dcccbafcccffbfe38ada5ba2573eda9308f4bad0fb1beb79b12c7329c18766b,0x11931693de41195bec4acae1beea0b9b2bf2e55902bebb8f08da8036989efacda79b275d0a5b06d42905826f99e05dfa"
       ]
     },
     {
       "P": {
-        "x": "0x125730d27604ffa5f1be4e6357f2dacf59803b6b8ce43b81eb2e42010e0765ea149ed52e5d8ad0847617bb87a3cfdbbc,0x033008748ad6e6d95b68e86d8e786609c1011729606e45ab0b5691eceb3d4c72a80e36792f74e907309f3550bd7b9a6e",
-        "y": "0x180de292e84a7ecc8361490a3f0d8bcf834e12d68529e437df782111f01c8c73c53c9a502eac6aa9dffceae1b7df55b8,0x07225c86be63f0b3eb8acf88ff4133fa9bb8c0b1d50c997ad33f57dcb9cd09cc4676da6f37fd7f4bfaa06bfca9bdb772"
+        "x": "0x19925c3d247512c84e3ced29498eada349e82ee96689d5977e627c5b75a904800d789d1848a0551fd1d8b300efef8663,0x07a1af1c92c0723656bb94b0ebae40d4c3e952b32473964710b9b9602b8dbd4e80a8950208fc2cb449daea25af54f138",
+        "y": "0x179c7387bd605a594a778eb6305ba2d96d69383104c41fd6c5b1517b1728959e78fef47260863497292e056b745d847a,0x174fd14a9224fc3a7fa9019b7c344557f67b98f40c4fe7cefffd99a57aac611de1456988947cbfa37728426d9eeaea52"
       },
       "Q0": {
-        "x": "0x17dab789594c9400a35e44e124a04eb15a273b7ff3385aeb5767cecf3a5d6ce03bee39e9b3d9eedef8dfc1c064465f04,0x0d2b1ae115243ae13e9018e065bfb4215671e2ea86792e78858f012264b642591f4839972f58c00309cbf54a6f2809c5",
-        "y": "0x19d7a9d430474d353c6ccf18db52263cd2fa4685e0194b3ec55672dfea3645c08feb3643dc8a4e995406e3b1108e7275,0x03ac4fde5674418babfbbc6bad412d789f018ad49135ef84e6cbb1b63eb9fb61d7d12caa9ccb4e710d1badff2fe47515"
+        "x": "0x15e925b755b1d7ffadb242ae97d8f3826a46b6cebb87fc5afafa75a041dce9dab92daff7c76a27fdaabee83b58302e7c,0x198976a1d24b585148aa5331536a8d9747584d2cd86bb424426c4ae7234aed4afb060f1e09d1ab36bbf7a439fc8da6d1",
+        "y": "0x16cda73b5ec6993795f393f19129e0f4e3de82f803ca55f21962162ac599e48e39f0ff78e8159a05d0eceabc6cf01291,0x05b52d7a1673bb8168c3bbad3d3652abca5d7e0027a667914668772ca6ca7e130b07ae7ea6b16695ed53e83789ca3a50"
       },
       "Q1": {
-        "x": "0x08d580532d837ce1cd78df4e3668b123eafd519b93e359ba64e0281740742649b76c960e5390e1fd4ea4abcc84afcaca,0x12a30881e5bca0c8f3f8159b1490e215a380eb70c71f14570e886f6ba2de770e26ce6634e00c9a98e14665f61820209f",
-        "y": "0x13192225f9eea2cb2c342e39654a115e5f4b002943cea6067d429e685317be5034edcfe71897728402fc28abb725eca9,0x01c62e5d5325ec325e75e7e0a60a86d489ee543b0709ccd76807cafd1d8041486c185a89f6ca72b96cb7eb193a3d5ef5"
+        "x": "0x031241efa254ea61dd01d9ac138fa90b5b5a60b1d37bdac7984f1a038e867acb39f10d616b012b2d64f2a907ccf7a2c5,0x10e01a11fd5e4af0c2f7d373dfd0b565055680087068bfe3d9694b443a76a472c409fd57e86647848615ed54bf85fac6",
+        "y": "0x173cec16ebaf7dc61a0c3fadd3a50bc19362dddfe166c6ff7a84443c04659c096be4982b3db1d7bb26ae16af4bfb532f,0x13e3154a7eee424063ec3826c681675942bd36b9f22898547414420bd69ba4e273090d4722297f6e5ba2729fba8cabd9"
       },
       "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
       "u": [
-        "0x00a73d9f99c991b8a95d533111700cb468bb9dfc7ecfa8879d278efd4f62907dc735a137ed26eac6fbd4730d16c525e7,0x011de2ac3ddd0fce82f81ff1506a4da615a545f5f1a38d76493489d043dec0298423741a607fd45b57526b2dbf7c0512",
-        "0x054e5964345b7e40826826b6c0773ae205596eed3f430649873afb7ff36a0a4583d947b5e1dcaaf64b62067814724329,0x0c022493d6de52b27b95ba1097b803e2834ce69555e25bda8df9a60bbd7cb8ef2d11eea6ea85856626a1f35c2ccccb95"
+        "0x1412f7dcbbd4b37d2818e3174f2e51c6767b4d93501208d905d625a6decfd1253c626575c44b838cd8801653909fa3a1,0x17bb0ac3a973bf8d3663102459b8dca358d9b971ebc700126f11110c83f644f0ac5a86f1c7cd6babceb1f3705447665a",
+        "0x0eaa03f98f9aa539262275d8862ce341537228572ea46dcd6e9e8662bd7f986948ddab6cf0594faa7b417b772ec96177,0x0fdb46860616bdbd8faff9859ae8d92f282f9633a4b5050c924d711f1b32a6cc20f431c207d47d66dd27fb6604c871b0"
       ]
     }
   ]
diff --git a/src/test_utils/test_vector_structs.rs b/src/test_utils/test_vector_structs.rs
index 5ea34fd..ab0261b 100644
--- a/src/test_utils/test_vector_structs.rs
+++ b/src/test_utils/test_vector_structs.rs
@@ -7,7 +7,6 @@ pub struct Field {
 #[derive(Deserialize)]
 pub struct Map {
     pub name: String,
-    pub sgn0: String,
 }
 
 #[derive(Deserialize)]


[incubator-milagro-crypto-rust] 29/44: Fix bls tests

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit f748c7b23e9a28d945b839e385e706ea6f50ba8d
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Mar 31 10:01:20 2020 +1100

    Fix bls tests
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/bls192.rs | 6 +++---
 src/bls256.rs | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/bls192.rs b/src/bls192.rs
index fb8e836..1f262a7 100644
--- a/src/bls192.rs
+++ b/src/bls192.rs
@@ -100,13 +100,13 @@ mod tests {
     use crate::test_utils::*;
 
     #[test]
-    fn test_bls() {
+    fn test_bls24() {
         let mut rng = create_rng();
 
         let mut s: [u8; BGS] = [0; BGS];
 
-        const G1S: usize = BFS + 1; /* Group 1 Size */
-        const G2S: usize = 4 * BFS; /* Group 2 Size */
+        const G1S: usize = BFS + 1; // Group 1 Size
+        const G2S: usize = 8 * BFS; // Group 2 Size
 
         let mut w: [u8; G2S] = [0; G2S];
         let mut sig: [u8; G1S] = [0; G1S];
diff --git a/src/bls256.rs b/src/bls256.rs
index b36566c..adad0da 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -98,13 +98,13 @@ mod tests {
     use crate::test_utils::*;
 
     #[test]
-    fn test_bls() {
+    fn test_bls48() {
         let mut rng = create_rng();
 
         let mut s: [u8; BGS] = [0; BGS];
 
-        const G1S: usize = BFS + 1; /* Group 1 Size */
-        const G2S: usize = 4 * BFS; /* Group 2 Size */
+        const G1S: usize = BFS + 1; // Group 1 Size
+        const G2S: usize = 16 * BFS; // Group 2 Size
 
         let mut w: [u8; G2S] = [0; G2S];
         let mut sig: [u8; G1S] = [0; G1S];


[incubator-milagro-crypto-rust] 38/44: Merge pull request #18 from sigp/copying

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 0a55e5d5ea1a8c9b628f989e0c5918d12dc71cf4
Merge: d6bd914 40b9037
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Wed Apr 22 09:42:52 2020 +0100

    Merge pull request #18 from sigp/copying
    
    Copying

 src/big.rs                  | 102 +++----
 src/bls381.rs               |  60 ++---
 src/bls381/iso.rs           | 158 +++++------
 src/dbig.rs                 |  42 +--
 src/ecdh.rs                 |  31 +--
 src/ecp.rs                  | 428 +++++++++++++-----------------
 src/ecp2.rs                 | 229 +++++++---------
 src/ecp4.rs                 | 272 +++++++++----------
 src/ecp8.rs                 | 440 +++++++++++++++----------------
 src/ff.rs                   |  55 ++--
 src/fp.rs                   | 134 ++++------
 src/fp12.rs                 | 448 ++++++++++++++-----------------
 src/fp16.rs                 | 273 +++++++++----------
 src/fp2.rs                  | 139 +++++-----
 src/fp24.rs                 | 510 +++++++++++++++++------------------
 src/fp4.rs                  | 308 ++++++++++------------
 src/fp48.rs                 | 630 +++++++++++++++++++++-----------------------
 src/fp8.rs                  | 303 ++++++++++-----------
 src/hash_to_curve.rs        |   4 +-
 src/mpin.rs                 |  23 +-
 src/mpin192.rs              |  21 +-
 src/mpin256.rs              |  21 +-
 src/pair.rs                 | 284 +++++++++-----------
 src/pair192.rs              | 250 ++++++++----------
 src/pair256.rs              | 322 ++++++++++------------
 src/roms/rom_bls381g1_32.rs |   4 +-
 src/roms/rom_bls381g1_64.rs |   4 +-
 src/roms/rom_bls381g2_32.rs |   4 +-
 src/roms/rom_bls381g2_64.rs |   4 +-
 29 files changed, 2456 insertions(+), 3047 deletions(-)


[incubator-milagro-crypto-rust] 34/44: Tidy up compiler warnings and remove clone from FF

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit e00159c4de34e6a7e589a6784467f59a39df9943
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Apr 21 10:58:10 2020 +1000

    Tidy up compiler warnings and remove clone from FF
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/big.rs  | 25 +++++++++----------------
 src/dbig.rs | 15 +++++----------
 src/ecp.rs  | 23 +++++++++++------------
 src/ff.rs   | 12 +++---------
 src/rsa.rs  | 10 +++++-----
 5 files changed, 33 insertions(+), 52 deletions(-)

diff --git a/src/big.rs b/src/big.rs
index f0696c7..2c935c6 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -617,7 +617,6 @@ impl Big {
     pub fn rmod(&mut self, n: &Big) {
         let mut k = 0;
         let mut m = n.clone();
-        let mut r = Big::new();
         self.norm();
         if Big::comp(self, &m) < 0 {
             return;
@@ -633,7 +632,7 @@ impl Big {
         while k > 0 {
             m.fshr(1);
 
-            r = self.clone();
+            let mut r = self.clone();
             r.sub(&m);
             r.norm();
             self.cmove(
@@ -653,7 +652,6 @@ impl Big {
         let mut e = Big::new_int(1);
         let mut b = self.clone();
         let mut m = n.clone();
-        let mut r = Big::new();
         self.zero();
 
         while Big::comp(&b, &m) >= 0 {
@@ -666,7 +664,7 @@ impl Big {
             m.fshr(1);
             e.fshr(1);
 
-            r = b.clone();
+            let mut r = b.clone();
             r.sub(&m);
             r.norm();
             let d = (1 - ((r.w[NLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
@@ -732,22 +730,18 @@ impl Big {
     /// 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 {
+        if p.parity() == 0 || self.iszilch() || Big::comp(p, &one) <= 0 {
             return 0;
         }
         self.norm();
 
-        x = self.clone();
-        n = p.clone();
+        let mut x = self.clone();
+        let mut n = p.clone();
         x.rmod(p);
 
         while Big::comp(&n, &one) > 0 {
-            if Big::comp(&x, &zilch) == 0 {
+            if x.iszilch() {
                 return 0;
             }
             let n8 = n.lastbits(3) as usize;
@@ -760,7 +754,7 @@ impl Big {
                 m += (n8 * n8 - 1) / 8
             }
             m += (n8 - 1) * ((x.lastbits(2) as usize) - 1) / 4;
-            t = n.clone();
+            let mut t = n.clone();
             t.rmod(&x);
             n = x.clone();
             x = t.clone();
@@ -781,7 +775,6 @@ impl Big {
         let mut v = p.clone();
         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) {
@@ -807,7 +800,7 @@ impl Big {
                 if Big::comp(&x1, &x2) >= 0 {
                     x1.sub(&x2)
                 } else {
-                    t = p.clone();
+                    let mut t = p.clone();
                     t.sub(&x2);
                     x1.add(&t);
                 }
@@ -818,7 +811,7 @@ impl Big {
                 if Big::comp(&x2, &x1) >= 0 {
                     x2.sub(&x1)
                 } else {
-                    t = p.clone();
+                    let mut t = p.clone();
                     t.sub(&x1);
                     x2.add(&t);
                 }
diff --git a/src/dbig.rs b/src/dbig.rs
index 689aeb8..6201d72 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -163,11 +163,9 @@ impl DBig {
         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;
+            return Big::new_dcopy(self);
         }
 
         loop {
@@ -181,7 +179,7 @@ impl DBig {
         while k > 0 {
             m.shr(1);
 
-            dr = self.clone();
+            let mut dr = self.clone();
             dr.sub(&m);
             dr.norm();
             self.cmove(
@@ -191,8 +189,7 @@ impl DBig {
 
             k -= 1;
         }
-        let r = Big::new_dcopy(self);
-        r
+        Big::new_dcopy(self)
     }
 
     /// return self / c
@@ -201,8 +198,6 @@ impl DBig {
         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 {
@@ -215,12 +210,12 @@ impl DBig {
             m.shr(1);
             e.shr(1);
 
-            dr = self.clone();
+            let mut dr = self.clone();
             dr.sub(&m);
             dr.norm();
             let d = (1 - ((dr.w[big::DNLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
             self.cmove(&dr, d);
-            r = a.clone();
+            let mut r = a.clone();
             r.add(&e);
             r.norm();
             a.cmove(&r, d);
diff --git a/src/ecp.rs b/src/ecp.rs
index 2c9b9db..1f1bed2 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -931,22 +931,21 @@ impl ECP {
         if CURVETYPE == CurveType::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 = self.clone();
 
             for i in (0..bts).rev() {
                 let b = ((e >> i) & 1) as isize;
-                P = R1.clone();
+                let mut P = R1.clone();
                 P.add(&R0);
                 R0.cswap(&mut R1, b);
                 R1 = P.clone();
                 R0.dbl();
                 R0.cswap(&mut R1, b);
             }
-            P = R0.clone();
+            let mut P = R0.clone();
             P.affine();
-            return P;
+            P
         }
     }
 
@@ -955,8 +954,7 @@ impl ECP {
         if e.iszilch() || self.is_infinity() {
             return ECP::new();
         }
-        let mut P = ECP::new();
-        if CURVETYPE == CurveType::Montgomery {
+        let mut T = if CURVETYPE == CurveType::Montgomery {
             /* use Ladder */
             let mut R0 = self.clone();
             let mut R1 = self.clone();
@@ -967,14 +965,14 @@ impl ECP {
 
             for i in (0..nb - 1).rev() {
                 let b = e.bit(i);
-                P = R1.clone();
+                let mut P = R1.clone();
                 P.dadd(&mut R0, &D);
                 R0.cswap(&mut R1, b);
                 R1 = P.clone();
                 R0.dbl();
                 R0.cswap(&mut R1, b);
             }
-            P = R0.clone();
+            R0.clone()
         } else {
             let mut W: [ECP; 8] = [
                 ECP::new(),
@@ -1024,7 +1022,7 @@ impl ECP {
             }
             w[nb] = t.lastbits(5) as i8;
 
-            P = W[((w[nb] as usize) - 1) / 2].clone();
+            let mut P = W[((w[nb] as usize) - 1) / 2].clone();
             for i in (0..nb).rev() {
                 Q.selector(&W, w[i] as i32);
                 P.dbl();
@@ -1034,9 +1032,10 @@ impl ECP {
                 P.add(&Q);
             }
             P.sub(&C); /* apply correction */
-        }
-        P.affine();
-        P
+            P
+        };
+        T.affine();
+        T
     }
 
     /* Return e.this+f.Q */
diff --git a/src/ff.rs b/src/ff.rs
index 0f23b87..c2b12cf 100644
--- a/src/ff.rs
+++ b/src/ff.rs
@@ -39,7 +39,6 @@ pub const P_OMASK: Chunk = (-1) << (P_MBITS % big::BASEBITS);
 pub const P_FEXCESS: Chunk = 1 << (big::BASEBITS * big::NLEN - P_MBITS - 1);
 pub const P_TBITS: usize = P_MBITS % big::BASEBITS;
 
-#[derive(Clone)]
 pub struct FF {
     v: Vec<Big>,
     length: usize,
@@ -145,20 +144,16 @@ impl FF {
 
     /* shift right by BIGBITS-bit words */
     pub fn shrw(&mut self, n: usize) {
-        let mut t = Big::new();
         for i in 0..n {
-            t = self.v[i + n].clone();
-            self.v[i] = t.clone();
+            self.v[i] = self.v[i + n].clone();
             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 = self.v[i].clone();
-            self.v[n + i] = t.clone();
+            self.v[n + i] = self.v[i].clone();
             self.v[i].zero();
         }
     }
@@ -205,9 +200,8 @@ impl FF {
     }
 
     pub fn rsinc(&mut self, n: usize) {
-        let mut t = Big::new();
         for i in 0..n {
-            t = self.v[i].clone();
+            let t = self.v[i].clone();
             self.v[n + i].add(&t);
         }
     }
diff --git a/src/rsa.rs b/src/rsa.rs
index 30bdcd0..a3022e0 100644
--- a/src/rsa.rs
+++ b/src/rsa.rs
@@ -121,7 +121,7 @@ pub fn key_pair(rng: &mut RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut Rsa
             prv.p.inc(4);
         }
 
-        p1 = prv.p.clone();
+        p1.copy(&prv.p);
         p1.dec(1);
 
         if p1.cfactor(e) {
@@ -139,7 +139,7 @@ pub fn key_pair(rng: &mut RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut Rsa
             prv.q.inc(4);
         }
 
-        q1 = prv.q.clone();
+        q1.copy(&prv.q);
         q1.dec(1);
 
         if q1.cfactor(e) {
@@ -152,7 +152,7 @@ pub fn key_pair(rng: &mut RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut Rsa
     pbc.n = FF::mul(&prv.p, &prv.q);
     pbc.e = e;
 
-    t = p1.clone();
+    t.copy(&p1);
     t.shr();
     prv.dp.set(e);
     prv.dp.invmodp(&t);
@@ -161,7 +161,7 @@ pub fn key_pair(rng: &mut RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut Rsa
     }
     prv.dp.norm();
 
-    t = q1.clone();
+    t.copy(&q1);
     t.shr();
     prv.dq.set(e);
     prv.dq.invmodp(&t);
@@ -170,7 +170,7 @@ pub fn key_pair(rng: &mut RAND, e: isize, prv: &mut RsaPrivateKey, pbc: &mut Rsa
     }
     prv.dq.norm();
 
-    prv.c = prv.p.clone();
+    prv.c.copy(&prv.p);
     prv.c.invmodp(&prv.q);
 }
 


[incubator-milagro-crypto-rust] 39/44: Add equality checks

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 1fd5b331db5cadb7efc3d09857051e904763f75e
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Tue Apr 28 17:17:38 2020 +1000

    Add equality checks
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/ecp.rs  | 2 ++
 src/ecp2.rs | 2 ++
 src/fp.rs   | 2 ++
 src/fp12.rs | 2 ++
 src/fp2.rs  | 2 ++
 src/fp4.rs  | 2 ++
 6 files changed, 12 insertions(+)

diff --git a/src/ecp.rs b/src/ecp.rs
index 609ab75..573e016 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -40,6 +40,8 @@ impl PartialEq for ECP {
     }
 }
 
+impl Eq for ECP {}
+
 impl fmt::Display for ECP {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
diff --git a/src/ecp2.rs b/src/ecp2.rs
index 25f7175..14d9d5e 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -39,6 +39,8 @@ impl PartialEq for ECP2 {
     }
 }
 
+impl Eq for ECP2 {}
+
 impl fmt::Display for ECP2 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
diff --git a/src/fp.rs b/src/fp.rs
index f1454c5..aa86eb6 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -38,6 +38,8 @@ impl PartialEq for FP {
     }
 }
 
+impl Eq for FP {}
+
 impl fmt::Display for FP {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "FP: [ {} ]", self.tostring())
diff --git a/src/fp12.rs b/src/fp12.rs
index e0dc648..254cb17 100644
--- a/src/fp12.rs
+++ b/src/fp12.rs
@@ -46,6 +46,8 @@ impl PartialEq for FP12 {
     }
 }
 
+impl Eq for FP12 {}
+
 impl FP12 {
     pub fn new() -> FP12 {
         FP12 {
diff --git a/src/fp2.rs b/src/fp2.rs
index 12920f4..72e1f8f 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -37,6 +37,8 @@ impl PartialEq for FP2 {
     }
 }
 
+impl Eq for FP2 {}
+
 impl fmt::Display for FP2 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "FP2: [ {}, {} ]", self.a, self.b)
diff --git a/src/fp4.rs b/src/fp4.rs
index 88b5d03..b4a24e4 100644
--- a/src/fp4.rs
+++ b/src/fp4.rs
@@ -34,6 +34,8 @@ impl PartialEq for FP4 {
     }
 }
 
+impl Eq for FP4 {}
+
 impl FP4 {
     pub fn new() -> FP4 {
         FP4 {


[incubator-milagro-crypto-rust] 44/44: Merge pull request #21 from sigp/hash-to-curve-07

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit d8f3bb9891d5cdf0b1c775e8166751cebda70fcc
Merge: c492975 9a2581f
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Tue May 5 07:38:39 2020 +0100

    Merge pull request #21 from sigp/hash-to-curve-07
    
    Update to hash-to-curve version 7 for BLS381

 src/bls381.rs                                      | 132 ++-------------------
 src/ecp.rs                                         |   2 +
 src/ecp2.rs                                        |   2 +
 src/fp.rs                                          |  23 ++--
 src/fp12.rs                                        |   2 +
 src/fp2.rs                                         |  19 ++-
 src/fp4.rs                                         |   2 +
 src/hash256.rs                                     |  10 +-
 src/hash384.rs                                     |  10 +-
 src/hash512.rs                                     |  10 +-
 src/hash_to_curve.rs                               |  87 ++++++++------
 src/roms/rom_bls381g1_32.rs                        |   4 +-
 src/roms/rom_bls381g1_64.rs                        |   6 +-
 src/roms/rom_bls381g2_32.rs                        |   6 +-
 src/roms/rom_bls381g2_64.rs                        |   6 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  67 ++++++-----
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  43 ++++---
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  67 ++++++-----
 src/test_utils/test_vector_structs.rs              |   1 -
 24 files changed, 331 insertions(+), 431 deletions(-)



[incubator-milagro-crypto-rust] 32/44: Write hash to curve functions for bls381 G1 and G2

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 17c208e2950553ac05e6fef7a9012c99e6c19369
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Sun Apr 5 22:50:01 2020 +1000

    Write hash to curve functions for bls381 G1 and G2
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 Cargo.lock                                         | 662 +++++++++++++++++++++
 Cargo.toml                                         |  16 +-
 src/big.rs                                         |  11 +-
 src/bls.rs                                         |   6 +-
 src/bls256.rs                                      |   6 +-
 src/bls381.rs                                      | 424 +++++++++++++
 src/bls381/iso.rs                                  | 335 +++++++++++
 src/dbig.rs                                        |  21 +-
 src/ecdh.rs                                        |   3 +-
 src/ecp.rs                                         |  23 +
 src/ecp2.rs                                        |  45 +-
 src/errors.rs                                      |   4 +
 src/fp.rs                                          |  76 ++-
 src/fp2.rs                                         |  23 +
 src/hash256.rs                                     | 266 ++++++++-
 src/hash384.rs                                     | 228 +++++--
 src/hash512.rs                                     | 296 ++++++++-
 src/hash_to_curve.rs                               | 307 ++++++++++
 src/lib.rs                                         |  45 +-
 src/nhs.rs                                         |   1 -
 src/roms/{rom_bls381_32.rs => rom_bls381g1_32.rs}  |  36 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g1_64.rs}  |  38 +-
 src/roms/{rom_bls381_32.rs => rom_bls381g2_32.rs}  |  38 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g2_64.rs}  |  38 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 src/test_utils/mod.rs                              |  20 +
 src/test_utils/test_vector_structs.rs              |  44 ++
 34 files changed, 3550 insertions(+), 158 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ccba62a..6f9d42d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,4 +3,666 @@
 [[package]]
 name = "amcl"
 version = "0.2.0"
+dependencies = [
+ "criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bitflags"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "bstr"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "byteorder"
+version = "1.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "cast"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "clap"
+version = "2.33.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "criterion"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "csv"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "either"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "getrandom"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "hex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "itertools"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "js-sys"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.68"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "log"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "maybe-uninit"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "memchr"
+version = "2.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "memoffset"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "oorandom"
+version = "11.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "plotters"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rayon"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex"
+version = "1.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.106"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "walkdir"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "web-sys"
+version = "0.3.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
+"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+"checksum bstr 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "2889e6d50f394968c8bf4240dc3f2a7eb4680844d27308f798229ac9d4725f41"
+"checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
+"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
+"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
+"checksum criterion 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc755679c12bda8e5523a71e4d654b6bf2e14bd838dfc48cde6559a05caf7d1"
+"checksum criterion-plot 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a01e15e0ea58e8234f96146b1f91fa9d0e4dd7a38da93ff7a75d42c0b9d3a545"
+"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
+"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
+"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
+"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
+"checksum csv 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "00affe7f6ab566df61b4be3ce8cf16bc2576bca0963ceb0955e45d514bf9a279"
+"checksum csv-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
+"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+"checksum hermit-abi 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
+"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
+"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
+"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
+"checksum js-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055"
+"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+"checksum libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
+"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
+"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
+"checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
+"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
+"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
+"checksum num_cpus 1.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
+"checksum oorandom 11.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebcec7c9c2a95cacc7cd0ecb89d8a8454eca13906f6deb55258ffff0adeb9405"
+"checksum plotters 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "4e3bb8da247d27ae212529352020f3e5ee16e83c0c258061d27b08ab92675eeb"
+"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
+"checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
+"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
+"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+"checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
+"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
+"checksum regex 1.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
+"checksum regex-automata 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
+"checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+"checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
+"checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
+"checksum serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)" = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9"
+"checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
+"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+"checksum tinytemplate 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57a3c6667d3e65eb1bc3aed6fd14011c6cbc3a0665218ab7f5daf040b9ec371a"
+"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
+"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+"checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
+"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+"checksum wasm-bindgen 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
+"checksum wasm-bindgen-backend 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
+"checksum wasm-bindgen-macro 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
+"checksum wasm-bindgen-macro-support 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
+"checksum wasm-bindgen-shared 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
+"checksum web-sys 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb"
+"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
+"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-util 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fa515c5163a99cc82bab70fd3bfdd36d827be85de63737b40fcef2ce084a436e"
+"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
diff --git a/Cargo.toml b/Cargo.toml
index 834aa83..132aec6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,15 +8,20 @@ license = "Apache-2.0"
 repository = "https://github.com/milagro-crypto/amcl"
 
 [dependencies]
+hex = "0.3"
+lazy_static = "1.2.0"
 
-[lib]
-name = "amcl"
-path = "src/lib.rs"
+[dev-dependencies]
+serde = "1.0"
+serde_json = "1.0"
+serde_derive = "1.0"
+criterion = "0.3.0"
+rand = "0.7.2"
 
 [features]
 default = ["bn254"]
 all = [
-  "anssi","bls24","bls48","bls381","bls383","bls461","bn254","bn254cx",
+  "anssi","bls24","bls48","bls381g1","bls381g2","bls383","bls461","bn254","bn254cx",
   "brainpool","c25519","c41417","ed25519","fp256BN","fp512BN","goldilocks","hifive",
   "nist256","nist384","nist521","nums256e","nums256w","nums384e","nums384w","nums512e",
   "nums512w","rsa2048","rsa3072","rsa4096","secp256k1",
@@ -24,7 +29,8 @@ all = [
 anssi = []
 bls24 = []
 bls48 = []
-bls381 = []
+bls381g1 = []
+bls381g2 = []
 bls383 = []
 bls461 = []
 bn254 = []
diff --git a/src/big.rs b/src/big.rs
index e4eca10..0c57d0a 100644
--- a/src/big.rs
+++ b/src/big.rs
@@ -436,7 +436,16 @@ impl Big {
     /// Convert from byte array starting at index `n` to Big
     pub fn frombytearray(b: &[u8], n: usize) -> Big {
         let mut m = Big::new();
-        for i in 0..(MODBYTES as usize) {
+
+        // Restrict length
+        let max_big = MODBYTES;
+        let len = if b.len() >= max_big {
+            max_big as usize
+        } else {
+            b.len()
+        };
+
+        for i in 0..len {
             m.fshl(8);
             m.w[0] += (b[i + n] & 0xff) as Chunk;
         }
diff --git a/src/bls.rs b/src/bls.rs
index 1bc71cb..c956441 100644
--- a/src/bls.rs
+++ b/src/bls.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::ecp::ECP;
-use super::ecp2::ECP2;
-use std::str;
 use super::big;
 use super::big::Big;
+use super::ecp::ECP;
+use super::ecp2::ECP2;
 use super::pair;
 use super::rom;
+use std::str;
 
 use rand::RAND;
 use sha3::SHA3;
diff --git a/src/bls256.rs b/src/bls256.rs
index 11fb5a1..785ad2d 100644
--- a/src/bls256.rs
+++ b/src/bls256.rs
@@ -17,13 +17,13 @@ specific language governing permissions and limitations
 under the License.
 */
 
-use super::ecp::ECP;
-use super::ecp8::ECP8;
-use std::str;
 use super::big;
 use super::big::Big;
+use super::ecp::ECP;
+use super::ecp8::ECP8;
 use super::pair256;
 use super::rom;
+use std::str;
 
 use rand::RAND;
 use sha3::SHA3;
diff --git a/src/bls381.rs b/src/bls381.rs
new file mode 100644
index 0000000..de56701
--- /dev/null
+++ b/src/bls381.rs
@@ -0,0 +1,424 @@
+/*
+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.
+*/
+
+/// BLS12-381
+///
+/// An implementation of BLS12-381 as specified by the following standard:
+/// https://github.com/cfrg/draft-irtf-cfrg-bls-signature
+pub mod iso;
+
+use self::iso::{iso11_to_ecp, iso3_to_ecp2};
+use super::big::Big;
+use super::ecp::ECP;
+use super::ecp2::ECP2;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::hash_to_curve::*;
+use super::pair;
+use super::rom::*;
+
+use rand::RAND;
+use sha3::SHA3;
+use sha3::SHAKE256;
+use std::str;
+
+// BLS API Functions
+pub const BFS: usize = MODBYTES as usize;
+pub const BGS: usize = MODBYTES as usize;
+pub const BLS_OK: isize = 0;
+pub const BLS_FAIL: isize = -1;
+
+// Hash a message to an ECP point, using SHA3
+#[allow(non_snake_case)]
+fn bls_hashit(m: &str) -> ECP {
+    let mut sh = SHA3::new(SHAKE256);
+    let mut hm: [u8; BFS] = [0; BFS];
+    let t = m.as_bytes();
+    for i in 0..m.len() {
+        sh.process(t[i]);
+    }
+    sh.shake(&mut hm, BFS);
+    let P = ECP::mapit(&hm);
+    P
+}
+
+/// Generate key pair, private key s, public key w
+pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
+    let q = Big::new_ints(&CURVE_ORDER);
+    let g = ECP2::generator();
+    let sc = Big::randomnum(&q, &mut rng);
+    sc.tobytes(s);
+    pair::g2mul(&g, &sc).tobytes(w);
+    BLS_OK
+}
+
+/// Sign message m using private key s to produce signature sig.
+pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
+    let d = bls_hashit(m);
+    let mut sc = Big::frombytes(&s);
+    pair::g1mul(&d, &mut sc).tobytes(sig, true);
+    BLS_OK
+}
+
+/// Verify signature given message m, the signature sig, and the public key w
+pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
+    let hm = bls_hashit(m);
+    let mut d = ECP::frombytes(&sig);
+    let g = ECP2::generator();
+    let pk = ECP2::frombytes(&w);
+    d.neg();
+
+    // Use new multi-pairing mechanism
+    let mut r = pair::initmp();
+    pair::another(&mut r, &g, &d);
+    pair::another(&mut r, &pk, &hm);
+    let mut v = pair::miller(&r);
+
+    //.. or alternatively
+    //    let mut v = pair::ate2(&g, &d, &pk, &hm);
+
+    v = pair::fexp(&v);
+    if v.isunity() {
+        return BLS_OK;
+    }
+    BLS_FAIL
+}
+
+/*************************************************************************************************
+* Functions for hashing to curve when signatures are on ECP
+*************************************************************************************************/
+/// Hash to Curve
+///
+/// Takes a message as input and converts it to a Curve Point
+/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+pub fn hash_to_curve_g1(msg: &[u8]) -> ECP {
+    let u =
+        hash_to_field_fp(msg, 2, DST).expect("hash to field should not fail for given parameters");
+    let mut q0 = map_to_curve_g1(u[0]);
+    let q1 = map_to_curve_g1(u[1]);
+    q0.add(&q1);
+    let p = q0.mul(&H_EFF_G1);
+    p
+}
+
+// Simplified SWU for Pairing-Friendly Curves
+//
+// Take a field point and map it to a Curve Point.
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+fn map_to_curve_g1(u: FP) -> ECP {
+    let (x, y) = simplified_swu_fp(u);
+    iso11_to_ecp(&x, &y)
+}
+
+/*************************************************************************************************
+* Functions for hashing to curve when signatures are on ECP2
+*************************************************************************************************/
+/// Hash to Curve
+///
+/// Takes a message as input and converts it to a Curve Point
+/// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3
+pub fn hash_to_curve_g2(msg: &[u8]) -> ECP2 {
+    let u =
+        hash_to_field_fp2(msg, 2, DST).expect("hash to field should not fail for given parameters");
+    let mut q0 = map_to_curve_g2(u[0]);
+    let q1 = map_to_curve_g2(u[1]);
+    q0.add(&q1);
+    q0.clear_cofactor();
+    q0
+}
+
+// Simplified SWU for Pairing-Friendly Curves
+//
+// Take a field point and map it to a Curve Point.
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+fn map_to_curve_g2(u: FP2) -> ECP2 {
+    let (x, y) = simplified_swu_fp2(u);
+    iso3_to_ecp2(&x, &y)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test_utils::*;
+
+    // The following tests were exported from
+    // https://github.com/kwantam/bls_sigs_ref/tree/master/python-impl
+    // Format: [(input, output)]
+    // input: [u0_a, u0_b, u1_a, u1_b]
+    // output: [x_a, x_b, y_a, y_b]
+    pub const TESTS: [([&str; 4], [&str; 4]); 4] =
+        [
+            // Test 0
+            (
+                // Input
+                [
+                    "004ad233c619209060e40059b81e4c1f92796b05aa1bc6358d65e53dc0d657dfbc713d4030b0b6d9234a6634fd1944e7",
+                    "0e2386c82713441bc3b06a460bd81850f4bf376ea89c80b18c0881e855c58dc8e83b2fd23af983f4786508e30c42af01",
+                    "08a6a75e0a8d32f1e096f29047ea879dd34a5504218d7ce92c32c244786822fb73fbf708d167ad86537468249ec6df48",
+                    "07016d0e5e13cd65780042c6f7b4c74ae1c58da438c99582696818b5c229895b893318dcb87d2a65e557d4ebeb408b70"
+                ],
+                // Output
+                [
+                    "04861c41efcc5fc56e62273692b48da25d950d2a0aaffb34eff80e8dbdc2d41ca38555ceb8554368436aea47d16056b5",
+                    "09db5217528c55d982cf05fc54242bdcd25f1ebb73372e00e16d8e0f19dc3aeabdeef2d42d693405a04c37d60961526a",
+                    "177d05b95e7879a7ddbd83c15114b5a4e9846fde72b2263072dc9e60db548ccbadaacb92cc4952d4f47425fe3c5e0172",
+                    "0fc82c99b928ed9df12a74f9215c3df8ae1e9a3fa54c00897889296890b23a0edcbb9653f9170bf715f882b35c0b4647"
+                ]
+            ),
+            // Test 1
+            (
+                // Input
+                [
+                    "083c57b3ee2ecba5bbf874bb03897827f949096efceea00f002c979de7e5e9429fcf1f3323d4c8c548cd6f8ecb1a5c1d",
+                    "0344fdfe8e1401867a275b3bef7e6ec52450968ab8a1293938fe3d5712dda67c85afeb91d85ab83fcdbebba4dc913e44",
+                    "1361b5ee134c6bee4e287e63f852b6e48546dcf0684af7cf3e7653a3427a609f769ce4d9d99a638b6ae432130fa43104",
+                    "18425b12c2ab5de136eb493b88ca950a45cab942505b5dd59a8b3ae8ec34c40ada65ff2719b1fcda9769fb22882002f9"
+                ],
+                // Output
+                [
+                    "15f7a5c1168ad5ab67ff285c80fa8dd932ca88d9f8b3803c6c7b1f525d2dd5d01f2418259ae167c17c514d55e4707ddb",
+                    "04378269c7364a6cefcdafdb87b004d3ebf6853f46687e46f29f23196d47a176c6f858be34c9f9a3608c74e804f6c686",
+                    "023d9d46abe82bc0ac7c104d9519c037ff72893b8371d72ab92378f60a2361d7171df6b33500828c88923ddb1aab7fa5",
+                    "1015adfeece3613836bf82541ea560c701e197b3d081e2c242b217d809f4ac0ca787b402537a66c0d1f6b76e1b19e94b"
+                ]
+            ),
+            // Test 2
+            (
+                // Input
+                [
+                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+                    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+                ],
+                // Output
+                [
+                    "19da1b4d47efeeb154f8968b43da2125376e0999ba722141419b03fd857490562fa42a5d0973956d1932dd20c1e0a284",
+                    "18426da25dadd359adfda64fbaddac4414da2a841cb467935289877db450fac424361efb2e7fb141b7b98e6b2f888aef",
+                    "0c2f8d431770d9be9b087c36fc5b66bb83ce6372669f48294193ef646105e0f21d17b134e7d1ad9c18f54b81f6a3707b",
+                    "03257c3be77016e69b75905a97871008a6dfd2e324a6748c48d3304380156987bd0905991824936fcfe34ab25c3b6caa"
+                ]
+            ),
+            // Test 3
+            (
+                // Input
+                [
+                    "05495a3dfa360cb809c1904530db1986aea4bf356e634b40b51e0ee5fcb6cb75085a72a0626873a426470067627c6418",
+                    "11e63b587bedb59c2140518565950bdf881d75c0cccdcedcd9f4b71f2cfede3e5fdbe0261b015562d5edeaa11b7b2b76",
+                    "116c87bbeece66871eb6c2a51bc4327b10ffe470b49c28ef8eef624da766caa2cc9ff6c7042b26b2efd3404f5a81a140",
+                    "010450a90c17ba2997b645ef340fb5b207d6c915b34a93d93e75ee905d6d203d4aac046e10bd4d94a215604ade7afa8e"
+                ],
+                // Output
+                [
+                    "0f1614a6e91c3e00799098fded2f2cfd72cb585cbdaec41b478509913c6772266a764f00b24a7f99607948a4b69b4d8f",
+                    "13ca2148705ca7ba49c92ab8985d7babcc8afc6bf8e397fb829f5fe3f49e51c41332ba4389f5ba66667310b22bea16c9",
+                    "026a743ee00eec8c7ef63351f4a3b26b2f029c10130385efc56ce53d0788db32ff5296ab77f9c389bd196cce8fc1e888",
+                    "0d458d80897e922f3e7e15cfa66a0d3645d95788bddb7478af3f1b5ca662c348b0e9ffdb88fabfdb74f103fea0c2d793"
+                ]
+            )
+        ];
+
+    #[test]
+    fn test_map_to_curve_g2() {
+        // Only run when signatures are on G2
+        if BLS_SIG_G1 {
+            return;
+        }
+
+        for test in &TESTS {
+            // Input u0 and u1
+            let a = Big::frombytes(&hex::decode(test.0[0]).unwrap());
+            let b = Big::frombytes(&hex::decode(test.0[1]).unwrap());
+            let u0 = FP2::new_bigs(&a, &b);
+            let a = Big::frombytes(&hex::decode(test.0[2]).unwrap());
+            let b = Big::frombytes(&hex::decode(test.0[3]).unwrap());
+            let u1 = FP2::new_bigs(&a, &b);
+
+            // Map to Curve
+            let (iso3_0_x, iso3_0_y) = simplified_swu_fp2(u0);
+            let (iso3_1_x, iso3_1_y) = simplified_swu_fp2(u1);
+
+            // 3-Isogeny Map
+            let mut q0 = iso3_to_ecp2(&iso3_0_x, &iso3_0_y);
+            let q1 = iso3_to_ecp2(&iso3_1_x, &iso3_1_y);
+            q0.add(&q1);
+
+            // Clear Cofactor
+            q0.clear_cofactor();
+
+            // Check expected values
+            let a = Big::frombytes(&hex::decode(test.1[0]).unwrap());
+            let b = Big::frombytes(&hex::decode(test.1[1]).unwrap());
+            let check_x = FP2::new_bigs(&a, &b);
+            let a = Big::frombytes(&hex::decode(test.1[2]).unwrap());
+            let b = Big::frombytes(&hex::decode(test.1[3]).unwrap());
+            let check_y = FP2::new_bigs(&a, &b);
+            let check_e = ECP2::new_fp2s(&check_x, &check_y);
+
+            assert!(q0.equals(&check_e));
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "bls381g2")]
+    fn test_hash_to_curve_g2() {
+        // Only run when signatures are on G2
+        if BLS_SIG_G1 {
+            return;
+        }
+
+        // Read hash to curve test vector
+        let reader = json_reader(H2C_SUITE);
+        let test_vectors: Bls12381Ro = serde_json::from_reader(reader).unwrap();
+
+        // Iterate through each individual case
+        for case in test_vectors.vectors {
+            // Execute hash to curve
+            let u = hash_to_field_fp2(case.msg.as_bytes(), 2, test_vectors.dst.as_bytes()).unwrap();
+            let q0 = map_to_curve_g2(u[0]);
+            let q1 = map_to_curve_g2(u[1]);
+            let mut r = q0.clone();
+            r.add(&q1);
+            let mut p = r.clone();
+            p.clear_cofactor();
+
+            // Verify hash to curve outputs
+            // Check u
+            assert_eq!(case.u.len(), u.len());
+            for (i, u_str) in case.u.iter().enumerate() {
+                // Convert case 'u[i]' to FP2
+                let u_str_parts: Vec<&str> = u_str.split(',').collect();
+                let a = Big::frombytes(&hex::decode(&u_str_parts[0].get(2..).unwrap()).unwrap());
+                let b = Big::frombytes(&hex::decode(&u_str_parts[1].get(2..).unwrap()).unwrap());
+                let expected_u_i = FP2::new_bigs(&a, &b);
+
+                // Verify u[i]
+                assert_eq!(expected_u_i, u[i]);
+            }
+
+            // Check Q0
+            let x_str_parts: Vec<&str> = case.Q0.x.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_x = FP2::new_bigs(&a, &b);
+
+            let y_str_parts: Vec<&str> = case.Q0.y.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_y = FP2::new_bigs(&a, &b);
+
+            let expected_q0 = ECP2::new_fp2s(&expected_x, &expected_y);
+            assert_eq!(expected_q0, q0);
+
+            // Check Q1
+            let x_str_parts: Vec<&str> = case.Q1.x.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_x = FP2::new_bigs(&a, &b);
+
+            let y_str_parts: Vec<&str> = case.Q1.y.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_y = FP2::new_bigs(&a, &b);
+
+            let expected_q1 = ECP2::new_fp2s(&expected_x, &expected_y);
+            assert_eq!(expected_q1, q1);
+
+            // Check P
+            let x_str_parts: Vec<&str> = case.P.x.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&x_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&x_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_x = FP2::new_bigs(&a, &b);
+
+            let y_str_parts: Vec<&str> = case.P.y.split(',').collect();
+            let a = Big::frombytes(&hex::decode(&y_str_parts[0].get(2..).unwrap()).unwrap());
+            let b = Big::frombytes(&hex::decode(&y_str_parts[1].get(2..).unwrap()).unwrap());
+            let expected_y = FP2::new_bigs(&a, &b);
+
+            let expected_p = ECP2::new_fp2s(&expected_x, &expected_y);
+            assert_eq!(expected_p, p);
+        }
+    }
+
+    #[test]
+    #[cfg(feature = "bls381g1")]
+    fn test_hash_to_curve_g1() {
+        // Only run when signatures are on G2
+        if !BLS_SIG_G1 {
+            return;
+        }
+
+        // Read hash to curve test vector
+        let reader = json_reader(H2C_SUITE);
+        let test_vectors: Bls12381Ro = serde_json::from_reader(reader).unwrap();
+
+        // Iterate through each individual case
+        for case in test_vectors.vectors {
+            // Execute hash to curve
+            let u = hash_to_field_fp(case.msg.as_bytes(), 2, test_vectors.dst.as_bytes()).unwrap();
+            let q0 = map_to_curve_g1(u[0]);
+            let q1 = map_to_curve_g1(u[1]);
+            let mut r = q0.clone();
+            r.add(&q1);
+            let p = r.mul(&H_EFF_G1);
+
+            // Verify hash to curve outputs
+            // Check u
+            assert_eq!(case.u.len(), u.len());
+            for (i, u_str) in case.u.iter().enumerate() {
+                // Convert case 'u[i]' to FP
+                let a = Big::frombytes(&hex::decode(&u_str.get(2..).unwrap()).unwrap());
+                let expected_u_i = FP::new_big(&a);
+
+                // Verify u[i]
+                assert_eq!(expected_u_i, u[i]);
+            }
+
+            // Check Q0
+            let a = Big::frombytes(&hex::decode(&case.Q0.x.get(2..).unwrap()).unwrap());
+            let expected_x = FP::new_big(&a);
+
+            let a = Big::frombytes(&hex::decode(&case.Q0.y.get(2..).unwrap()).unwrap());
+            let expected_y = FP::new_big(&a);
+
+            let expected_q0 = ECP::new_fps(expected_x, expected_y);
+            assert_eq!(expected_q0, q0);
+
+            // Check Q1
+            let a = Big::frombytes(&hex::decode(&case.Q1.x.get(2..).unwrap()).unwrap());
+            let expected_x = FP::new_big(&a);
+
+            let a = Big::frombytes(&hex::decode(&case.Q1.y.get(2..).unwrap()).unwrap());
+            let expected_y = FP::new_big(&a);
+
+            let expected_q1 = ECP::new_fps(expected_x, expected_y);
+            assert_eq!(expected_q1, q1);
+
+            // Check P
+            let a = Big::frombytes(&hex::decode(&case.P.x.get(2..).unwrap()).unwrap());
+            let expected_x = FP::new_big(&a);
+
+            let a = Big::frombytes(&hex::decode(&case.P.y.get(2..).unwrap()).unwrap());
+            let expected_y = FP::new_big(&a);
+
+            let expected_p = ECP::new_fps(expected_x, expected_y);
+            assert_eq!(expected_p, p);
+        }
+    }
+}
diff --git a/src/bls381/iso.rs b/src/bls381/iso.rs
new file mode 100644
index 0000000..b00fb3d
--- /dev/null
+++ b/src/bls381/iso.rs
@@ -0,0 +1,335 @@
+/*
+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 super::super::big::Big;
+use super::super::ecp::ECP;
+use super::super::ecp2::ECP2;
+use super::super::fp::FP;
+use super::super::fp2::FP2;
+
+/**************************************************
+* 3-Isogeny Constants
+**************************************************/
+lazy_static! {
+    // ISO-3 Mapping values
+    pub static ref ISO3_XNUM: [FP2; 4] = [
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap()),
+            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::new(),
+            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e").unwrap()),
+            &Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1").unwrap()),
+            &Big::new()
+        )
+    ];
+    pub static ref ISO3_XDEN: [FP2; 4] = [
+        FP2::new_bigs(
+            &Big::new(),
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::new_int(12),
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f").unwrap())
+        ),
+        FP2::new_int(1),
+        FP2::new(),
+    ];
+    pub static ref ISO3_YNUM: [FP2; 4] = [
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap()),
+            &Big::frombytes(&hex::decode("1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::new(),
+            &Big::frombytes(&hex::decode("05c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c").unwrap()),
+            &Big::frombytes(&hex::decode("08ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10").unwrap()),
+            &Big::new()
+        )
+    ];
+    pub static ref ISO3_YDEN: [FP2; 4] = [
+        FP2::new_bigs(
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap()),
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::new(),
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3").unwrap())
+        ),
+        FP2::new_bigs(
+            &Big::new_int(18),
+            &Big::frombytes(&hex::decode("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99").unwrap())
+        ),
+        FP2::new_ints(1, 0)
+    ];
+
+    // ISO-11 Mapping values
+    pub static ref ISO11_XNUM: [FP; 12] = [
+        FP::new_big(
+            &Big::frombytes(&hex::decode("11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0d54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0e99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0d6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("080d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("06e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229").unwrap()),
+        ),
+    ];
+    pub static ref ISO11_XDEN: [FP; 11] = [
+        FP::new_big(
+            &Big::frombytes(&hex::decode("08ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0b2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("03425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0e7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0a10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641").unwrap())
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("095fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a").unwrap())
+        ),
+        FP::new_int(1),
+    ];
+    pub static ref ISO11_YNUM: [FP; 16] = [
+        FP::new_big(
+            &Big::frombytes(&hex::decode("090d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("00cc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("01f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("08cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("04ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("09fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0e1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0b182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("05c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604").unwrap()),
+        ),
+    ];
+    pub static ref ISO11_YDEN: [FP; 16] = [
+        FP::new_big(
+            &Big::frombytes(&hex::decode("16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("058df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0be0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("08d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("04d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0accbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0ad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("02660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7").unwrap()),
+        ),
+        FP::new_big(
+            &Big::frombytes(&hex::decode("0e0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f").unwrap()),
+        ),
+        FP::new_int(1),
+    ];
+}
+
+/// Mapping from 11-Isogeny Curve to BLS12-381 ECP
+///
+/// Adjusted from https://eprint.iacr.org/2019/403
+/// to convert projectives to (XZ, YZ, Z)
+pub fn iso11_to_ecp(iso_x: &FP, iso_y: &FP) -> ECP {
+    let polynomials_coefficients: [&[FP]; 4] =
+        [&*ISO11_XNUM, &*ISO11_XDEN, &*ISO11_YNUM, &*ISO11_YDEN];
+
+    // x-num, x-den, y-num, y-den
+    let mut mapped_vals: [FP; 4] = [FP::new(), FP::new(), FP::new(), FP::new()];
+
+    // Horner caculation for evaluating polynomials
+    for (i, coefficients) in polynomials_coefficients[..].iter().enumerate() {
+        mapped_vals[i] = coefficients[coefficients.len() - 1].clone();
+        for k in coefficients.iter().rev().skip(1) {
+            mapped_vals[i].mul(&iso_x);
+            mapped_vals[i].add(&k);
+        }
+    }
+
+    // y-num multiplied by y
+    mapped_vals[2].mul(&iso_y);
+
+    let mut z = mapped_vals[1].clone(); // x-den
+    z.mul(&mapped_vals[3]); // x-den * y-den
+
+    let mut x = mapped_vals[0].clone(); // x-num
+    x.mul(&mapped_vals[3]); // x-num * y-den
+
+    let mut y = mapped_vals[2].clone(); // y-num
+    y.mul(&mapped_vals[1]); // y-num * x-den
+
+    ECP::new_projective(x, y, z)
+}
+
+/// Mapping from 3-Isogeny Curve to BLS12-381 ECP2
+///
+/// Adjusted from https://eprint.iacr.org/2019/403
+/// to convert projectives to (XZ, YZ, Z)
+pub fn iso3_to_ecp2(iso_x: &FP2, iso_y: &FP2) -> ECP2 {
+    let polynomials_coefficients: [&[FP2; 4]; 4] =
+        [&*ISO3_XNUM, &*ISO3_XDEN, &*ISO3_YNUM, &*ISO3_YDEN];
+
+    // x-num, x-den, y-num, y-den
+    let mut mapped_vals: [FP2; 4] = [FP2::new(), FP2::new(), FP2::new(), FP2::new()];
+
+    // Horner caculation for evaluating polynomials
+    for (i, coefficients) in polynomials_coefficients[..].iter().enumerate() {
+        mapped_vals[i] = coefficients[coefficients.len() - 1].clone();
+        for k in coefficients.iter().rev().skip(1) {
+            mapped_vals[i].mul(&iso_x);
+            mapped_vals[i].add(&k);
+        }
+    }
+
+    // y-num multiplied by y
+    mapped_vals[2].mul(&iso_y);
+
+    let mut z = mapped_vals[1].clone(); // x-den
+    z.mul(&mapped_vals[3]); // x-den * y-den
+
+    let mut x = mapped_vals[0].clone(); // x-num
+    x.mul(&mapped_vals[3]); // x-num * y-den
+
+    let mut y = mapped_vals[2].clone(); // y-num
+    y.mul(&mapped_vals[1]); // y-num * x-den
+
+    ECP2::new_projective(x, y, z)
+}
diff --git a/src/dbig.rs b/src/dbig.rs
index 2479637..26b29bd 100644
--- a/src/dbig.rs
+++ b/src/dbig.rs
@@ -20,7 +20,7 @@ under the License.
 use super::super::arch;
 use super::super::arch::Chunk;
 use super::big;
-use super::big::Big;
+use super::big::{Big, MODBYTES};
 
 #[derive(Copy)]
 pub struct DBig {
@@ -301,4 +301,23 @@ impl DBig {
         }
         s
     }
+
+    // convert from byte array to DBig
+    pub fn frombytes(b: &[u8]) -> DBig {
+        let mut m = DBig::new();
+
+        // Restrict length
+        let max_dbig = 2 * MODBYTES;
+        let len = if b.len() >= max_dbig {
+            max_dbig as usize
+        } else {
+            b.len()
+        };
+
+        for i in 0..len {
+            m.shl(8);
+            m.w[0] += (b[i] & 0xff) as Chunk;
+        }
+        m
+    }
 }
diff --git a/src/ecdh.rs b/src/ecdh.rs
index 934ea82..78e88a9 100644
--- a/src/ecdh.rs
+++ b/src/ecdh.rs
@@ -226,7 +226,7 @@ pub fn pbkdf2(sha: usize, pass: &[u8], salt: &[u8], rep: usize, olen: usize, k:
 /// 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
+    // 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];
@@ -754,7 +754,6 @@ mod tests {
 
     #[test]
     fn test_ecdh() {
-
         let mut rng = create_rng();
 
         let pw = "M0ng00se";
diff --git a/src/ecp.rs b/src/ecp.rs
index 07e19be..609ab75 100644
--- a/src/ecp.rs
+++ b/src/ecp.rs
@@ -131,6 +131,29 @@ impl ECP {
         return E;
     }
 
+    // construct this from (x,y), set to 0 if not on curve
+    pub fn new_fps(x: FP, y: FP) -> ECP {
+        let mut point = ECP {
+            x,
+            y,
+            z: FP::new_int(1),
+        };
+
+        let rhs = ECP::rhs(&point.x);
+        let mut y2 = point.y.clone();
+        y2.sqr();
+        if !y2.equals(&rhs) {
+            point.inf();
+        }
+        point
+    }
+
+    // Create new point from (x, y, z)
+    // Assumes coordinates are valid
+    pub fn new_projective(x: FP, y: FP, z: FP) -> ECP {
+        ECP { x, y, z }
+    }
+
     /* set this=O */
     pub fn inf(&mut self) {
         self.x.zero();
diff --git a/src/ecp2.rs b/src/ecp2.rs
index b0892e4..25f7175 100644
--- a/src/ecp2.rs
+++ b/src/ecp2.rs
@@ -94,6 +94,11 @@ impl ECP2 {
         return E;
     }
 
+    // Construct from (X, Y, Z) with no gaurentee of correctness.
+    pub fn new_projective(x: FP2, y: FP2, z: FP2) -> ECP2 {
+        ECP2 { x, y, z }
+    }
+
     /* Test this=O? */
     pub fn is_infinity(&self) -> bool {
         self.x.iszilch() && self.z.iszilch()
@@ -722,15 +727,20 @@ impl ECP2 {
             x.inc(1);
             x.norm();
         }
+        Q.clear_cofactor();
+        Q
+    }
+
+    pub fn clear_cofactor(&mut self) {
         let mut X = FP2::new_bigs(&Big::new_ints(&rom::FRA), &Big::new_ints(&rom::FRB));
         if ecp::SEXTIC_TWIST == SexticTwist::MType {
             X.inverse();
             X.norm();
         }
-        x = Big::new_ints(&rom::CURVE_BNX);
+        let x = Big::new_ints(&rom::CURVE_BNX);
 
         if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bn {
-            let mut T = Q.mul(&x);
+            let mut T = self.mul(&x);
             if ecp::SIGN_OF_X == SignOfX::NegativeX {
                 T.neg();
             }
@@ -740,38 +750,37 @@ impl ECP2 {
             K.add(&T);
 
             K.frob(&X);
-            Q.frob(&X);
-            Q.frob(&X);
-            Q.frob(&X);
-            Q.add(&T);
-            Q.add(&K);
+            self.frob(&X);
+            self.frob(&X);
+            self.frob(&X);
+            self.add(&T);
+            self.add(&K);
             T.frob(&X);
             T.frob(&X);
-            Q.add(&T);
+            self.add(&T);
         }
         if ecp::CURVE_PAIRING_TYPE == CurvePairingType::Bls {
-            let mut xQ = Q.mul(&x);
+            let mut xQ = self.mul(&x);
             let mut x2Q = xQ.mul(&x);
 
             if ecp::SIGN_OF_X == SignOfX::NegativeX {
                 xQ.neg();
             }
             x2Q.sub(&xQ);
-            x2Q.sub(&Q);
+            x2Q.sub(&self);
 
-            xQ.sub(&Q);
+            xQ.sub(&self);
             xQ.frob(&X);
 
-            Q.dbl();
-            Q.frob(&X);
-            Q.frob(&X);
+            self.dbl();
+            self.frob(&X);
+            self.frob(&X);
 
-            Q.add(&x2Q);
-            Q.add(&xQ);
+            self.add(&x2Q);
+            self.add(&xQ);
         }
 
-        Q.affine();
-        return Q;
+        self.affine();
     }
 
     pub fn generator() -> ECP2 {
diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..71a30fa
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,4 @@
+#[derive(Debug)]
+pub enum AmclError {
+    HashToFieldError,
+}
diff --git a/src/fp.rs b/src/fp.rs
index 95cddff..f1454c5 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -118,7 +118,7 @@ impl FP {
         format!("{} {}", self.xes, self.x.tostring())
     }
 
-    // convert back to regular form
+    /// convert back to regular form
     pub fn redc(&self) -> Big {
         if MODTYPE != ModType::PseudoMersenne && MODTYPE != ModType::GeneralisedMersenne {
             let mut d = DBig::new_scopy(&(self.x));
@@ -127,8 +127,7 @@ impl FP {
         Big::new_copy(&(self.x))
     }
 
-    // reduce a DBig to a Big using the appropriate form of the modulus
-    // dd
+    /// reduce a DBig to a Big using the appropriate form of the modulus
     pub fn modulo(d: &mut DBig) -> Big {
         if MODTYPE == ModType::PseudoMersenne {
             let mut b = Big::new();
@@ -198,12 +197,12 @@ impl FP {
         Big::new()
     }
 
-    // convert to string
+    /// convert to string
     pub fn tostring(&self) -> String {
         self.redc().tostring()
     }
 
-    // reduce this mod Modulus
+    /// reduce this mod Modulus
     pub fn reduce(&mut self) {
         let mut m = Big::new_ints(&rom::MODULUS);
         let mut r = Big::new_copy(&m);
@@ -230,42 +229,43 @@ impl FP {
         self.xes = 1;
     }
 
-    // test this=0?
+    /// test this=0?
     pub fn iszilch(&self) -> bool {
         let mut a = FP::new_copy(self);
         a.reduce();
         a.x.iszilch()
     }
 
-    // copy from FP b
+    /// copy from FP b
     pub fn copy(&mut self, b: &FP) {
         self.x.copy(&(b.x));
         self.xes = b.xes;
     }
 
-    // copy from Big b
+    /// copy from Big b
     pub fn bcopy(&mut self, b: &Big) {
         self.x.copy(&b);
         self.nres();
     }
 
-    // set this=0
+    /// set this=0
     pub fn zero(&mut self) {
         self.x.zero();
         self.xes = 1;
     }
 
-    // set this=1
+    /// set this=1
     pub fn one(&mut self) {
         self.x.one();
         self.nres()
     }
 
-    // normalise this
+    /// normalise this
     pub fn norm(&mut self) {
         self.x.norm();
     }
-    // swap FPs depending on d
+
+    /// swap FPs depending on d
     pub fn cswap(&mut self, b: &mut FP, d: isize) {
         self.x.cswap(&mut (b.x), d);
         let mut c = d as i32;
@@ -275,14 +275,14 @@ impl FP {
         b.xes ^= t;
     }
 
-    // copy FPs depending on d
+    /// copy FPs depending on d
     pub fn cmove(&mut self, b: &FP, d: isize) {
         self.x.cmove(&(b.x), d);
         let c = d as i32;
         self.xes ^= (self.xes ^ b.xes) & (-c);
     }
 
-    // this*=b mod Modulus
+    /// this*=b mod Modulus
     pub fn mul(&mut self, b: &FP) {
         if i64::from(self.xes) * i64::from(b.xes) > i64::from(FEXCESS) {
             self.reduce()
@@ -306,9 +306,9 @@ impl FP {
         ((((v + (v >> 4)) & 0xF0F0F0F).wrapping_mul(0x1010101)) >> 24) as usize
     }
 
-    // find approximation to quotient of a/m
-    // Out by at most 2.
-    // Note that MAXXES is bounded to be 2-bits less than half a word
+    /// Find approximation to quotient of a/m
+    /// Out by at most 2.
+    /// Note that MAXXES is bounded to be 2-bits less than half a word
     fn quo(n: &Big, m: &Big) -> isize {
         let hb = arch::CHUNK / 2;
 
@@ -324,7 +324,7 @@ impl FP {
         }
     }
 
-    // this = -this mod Modulus
+    /// this = -this mod Modulus
     pub fn neg(&mut self) {
         let mut p = Big::new_ints(&rom::MODULUS);
         let sb = FP::logb2((self.xes - 1) as u32);
@@ -337,7 +337,7 @@ impl FP {
         }
     }
 
-    // this*=c mod Modulus, where c is a small int
+    /// this*=c mod Modulus, where c is a small int
     pub fn imul(&mut self, c: isize) {
         let mut cc = c;
         let mut s = false;
@@ -366,7 +366,7 @@ impl FP {
         }
     }
 
-    // self*=self mod Modulus
+    /// self*=self mod Modulus
     pub fn sqr(&mut self) {
         if i64::from(self.xes) * i64::from(self.xes) > i64::from(FEXCESS) {
             self.reduce()
@@ -377,7 +377,7 @@ impl FP {
         self.xes = 2
     }
 
-    // self+=b
+    /// self+=b
     pub fn add(&mut self, b: &FP) {
         self.x.add(&(b.x));
         self.xes += b.xes;
@@ -386,7 +386,7 @@ impl FP {
         }
     }
 
-    // self+=self
+    /// self+=self
     pub fn dbl(&mut self) {
         self.x.dbl();
         self.xes += self.xes;
@@ -395,20 +395,20 @@ impl FP {
         }
     }
 
-    // self-=b
+    /// self-=b
     pub fn sub(&mut self, b: &FP) {
         let mut n = FP::new_copy(b);
         n.neg();
         self.add(&n);
     }
 
-    // self=b-self
+    /// self=b-self
     pub fn rsub(&mut self, b: &FP) {
         self.neg();
         self.add(&b);
     }
 
-    // self/=2 mod Modulus
+    /// self/=2 mod Modulus
     pub fn div2(&mut self) {
         if self.x.parity() == 0 {
             self.x.fshr(1);
@@ -420,8 +420,9 @@ impl FP {
         }
     }
 
-    // See eprint paper https://eprint.iacr.org/2018/1038
-    // return this^(p-3)/4 or this^(p-5)/8
+    /// Return this^(p-3)/4 or this^(p-5)/8
+    ///
+    /// https://eprint.iacr.org/2018/1038
     pub fn fpow(&self) -> FP {
         let ac: [isize; 11] = [1, 2, 3, 6, 12, 15, 30, 60, 120, 240, 255];
         let mut xp: [FP; 11] = [
@@ -570,7 +571,8 @@ impl FP {
         }
         r
     }
-    // self=1/self mod Modulus
+
+    /// self=1/self mod Modulus
     pub fn inverse(&mut self) {
         if MODTYPE == ModType::PseudoMersenne || MODTYPE == ModType::GeneralisedMersenne {
             let mut y = self.fpow();
@@ -594,7 +596,7 @@ impl FP {
         }
     }
 
-    // return TRUE if self==a
+    /// return TRUE if self==a
     pub fn equals(&self, a: &FP) -> bool {
         let mut f = FP::new_copy(self);
         let mut s = FP::new_copy(a);
@@ -606,7 +608,7 @@ impl FP {
         return false;
     }
 
-    // return self^e mod Modulus
+    /// return self^e mod Modulus
     pub fn pow(&mut self, e: &mut Big) -> FP {
         let mut tb: [FP; 16] = [
             FP::new(),
@@ -662,7 +664,7 @@ impl FP {
         return r;
     }
 
-    // return sqrt(this) mod Modulus
+    /// return sqrt(this) mod Modulus
     pub fn sqrt(&mut self) -> FP {
         self.reduce();
 
@@ -702,10 +704,20 @@ impl FP {
             return r;
         }
     }
-    // return jacobi symbol (this/Modulus)
+
+    /// return jacobi symbol (this/Modulus)
     pub fn jacobi(&self) -> isize {
         let p = Big::new_ints(&rom::MODULUS);
         let mut w = self.redc();
         return w.jacobi(&p);
     }
+
+    /// Checks if the field value is negative
+    ///
+    /// Negative if a > -a
+    pub fn is_neg(&mut self) -> bool {
+        let mut neg_a = self.clone();
+        neg_a.neg();
+        Big::comp(&self.redc(), &neg_a.redc()) > 0
+    }
 }
diff --git a/src/fp2.rs b/src/fp2.rs
index 87a0db1..12920f4 100644
--- a/src/fp2.rs
+++ b/src/fp2.rs
@@ -64,6 +64,13 @@ impl FP2 {
         return f;
     }
 
+    pub fn new_ints(a: isize, b: isize) -> FP2 {
+        let mut f = FP2::new();
+        f.a.copy(&FP::new_int(a));
+        f.b.copy(&FP::new_int(b));
+        return f;
+    }
+
     pub fn new_copy(x: &FP2) -> FP2 {
         let mut f = FP2::new();
         f.a.copy(&x.a);
@@ -406,4 +413,20 @@ impl FP2 {
         self.copy(&t);
         self.div2();
     }
+
+    // ((a + b) , (a - b))
+    pub fn spmt(&mut self) {
+        let b = self.b.clone();
+        self.b = self.a.clone();
+        self.a.add(&b);
+        self.b.sub(&b);
+    }
+
+    // b > -b OR if b is 0 then a > -a
+    pub fn is_neg(&mut self) -> bool {
+        if self.b.iszilch() {
+            return self.a.is_neg();
+        }
+        self.b.is_neg()
+    }
 }
diff --git a/src/hash256.rs b/src/hash256.rs
index 5df85d9..5860524 100644
--- a/src/hash256.rs
+++ b/src/hash256.rs
@@ -37,6 +37,15 @@ const HASH256_K: [u32; 64] = [
     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
 ];
 
+/// The block size of each round.
+const BLOCK_SIZE: usize = 64;
+/// Ipad Byte
+const IPAD_BYTE: u8 = 0x36;
+/// Opad Byte
+const OPAD_BYTE: u8 = 0x5c;
+/// Hash Length in Bytes
+const HASH_BYTES: usize = 32;
+
 pub struct HASH256 {
     length: [u32; 2],
     h: [u32; 8],
@@ -75,7 +84,7 @@ impl HASH256 {
     }
 
     fn transform(&mut self) {
-        /* basic transformation step */
+        // basic transformation step
         for j in 16..64 {
             self.w[j] = HASH256::theta1(self.w[j - 2])
                 .wrapping_add(self.w[j - 7])
@@ -91,7 +100,7 @@ impl HASH256 {
         let mut g = self.h[6];
         let mut hh = self.h[7];
         for j in 0..64 {
-            /* 64 times - mush it up */
+            // 64 times - mush it up
             let t1 = hh
                 .wrapping_add(HASH256::sig1(e))
                 .wrapping_add(HASH256::ch(e, f, g))
@@ -117,9 +126,9 @@ impl HASH256 {
         self.h[7] = self.h[7].wrapping_add(hh);
     }
 
-    /* Initialise Hash function */
+    /// Initialise Hash function
     pub fn init(&mut self) {
-        /* initialise */
+        // initialise
         for i in 0..64 {
             self.w[i] = 0
         }
@@ -145,7 +154,7 @@ impl HASH256 {
         return nh;
     }
 
-    /* process a single byte */
+    /// Process a single byte
     pub fn process(&mut self, byt: u8) {
         /* process the next message byte */
         let cnt = ((self.length[0] / 32) % 16) as usize;
@@ -161,15 +170,14 @@ impl HASH256 {
         }
     }
 
-    /* process an array of bytes */
-
+    /// Process an array of bytes
     pub fn process_array(&mut self, b: &[u8]) {
         for i in 0..b.len() {
             self.process(b[i])
         }
     }
 
-    /* process a 32-bit integer */
+    /// Process a 32-bit integer
     pub fn process_num(&mut self, n: i32) {
         self.process(((n >> 24) & 0xff) as u8);
         self.process(((n >> 16) & 0xff) as u8);
@@ -177,9 +185,9 @@ impl HASH256 {
         self.process((n & 0xff) as u8);
     }
 
-    /* Generate 32-byte Hash */
-    pub fn hash(&mut self) -> [u8; 32] {
-        /* pad message and finish - supply digest */
+    /// Generate 32-byte Hash
+    pub fn hash(&mut self) -> [u8; HASH_BYTES] {
+        // pad message and finish - supply digest
         let mut digest: [u8; 32] = [0; 32];
         let len0 = self.length[0];
         let len1 = self.length[1];
@@ -191,26 +199,238 @@ impl HASH256 {
         self.w[15] = len0;
         self.transform();
         for i in 0..32 {
-            /* convert to bytes */
+            // convert to bytes
             digest[i] = ((self.h[i / 4] >> (8 * (3 - i % 4))) & 0xff) as u8;
         }
         self.init();
         return digest;
     }
+
+    /// Generate a HMAC
+    ///
+    /// https://tools.ietf.org/html/rfc2104
+    pub fn hmac(key: &[u8], text: &[u8]) -> [u8; HASH_BYTES] {
+        let mut k = key.to_vec();
+
+        // Verify length of key < BLOCK_SIZE
+        if k.len() > BLOCK_SIZE {
+            // Reduce key to 32 bytes by hashing
+            let mut hash256 = HASH256::new();
+            hash256.init();
+            hash256.process_array(&k);
+            k = hash256.hash().to_vec();
+        }
+
+        // Prepare inner and outer paddings
+        // inner = (ipad XOR k)
+        // outer = (opad XOR k)
+        let mut inner = vec![IPAD_BYTE; BLOCK_SIZE];
+        let mut outer = vec![OPAD_BYTE; BLOCK_SIZE];
+        for (i, byte) in k.iter().enumerate() {
+            inner[i] = inner[i] ^ byte;
+            outer[i] = outer[i] ^ byte;
+        }
+
+        // Concatenate inner with text = (ipad XOR k || text)
+        inner.extend_from_slice(text);
+
+        // hash inner = H(ipad XOR k || text)
+        let mut hash256 = HASH256::new();
+        hash256.init();
+        hash256.process_array(&inner);
+        let inner = hash256.hash();
+
+        // Concatenate outer with hash of inner = (opad XOR k) || H(ipad XOR k || text)
+        outer.extend_from_slice(&inner);
+
+        // Final hash = H((opad XOR k) || H(ipad XOR k || text))
+        let mut hash256 = HASH256::new();
+        hash256.init();
+        hash256.process_array(&outer);
+        hash256.hash()
+    }
+
+    /// HKDF-Extract
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extract(salt: &[u8], ikm: &[u8]) -> [u8; HASH_BYTES] {
+        HASH256::hmac(salt, ikm)
+    }
+
+    /// HKDF-Extend
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extend(prk: &[u8], info: &[u8], l: u8) -> Vec<u8> {
+        // n = cieling(l / 32)
+        let mut n = l / (HASH_BYTES as u8);
+        if n * (HASH_BYTES as u8) < l {
+            n += 1;
+        }
+
+        let mut okm: Vec<u8> = vec![];
+        let mut previous = vec![]; // T(0) = []
+
+        for i in 0..n as usize {
+            // Concatenate (T(i) || info || i)
+            let mut text: Vec<u8> = previous;
+            text.extend_from_slice(info);
+            text.push((i + 1) as u8); // Note: i <= 254
+
+            // T(i+1) = HMAC(PRK, T(i) || info || i)
+            previous = HASH256::hmac(prk, &text).to_vec();
+            okm.extend_from_slice(&previous);
+        }
+
+        // Reduce length to size L
+        okm.resize(l as usize, 0);
+        okm
+    }
 }
 
-//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
-/*
-fn main() {
-    let s = String::from("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
-    let test = s.into_bytes();
-    let mut sh=HASH256::new();
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_hmac_simple() {
+        let text = [0x0a];
+        let key = [0x0b];
+        let expected =
+            hex::decode("b1746117c186405d121d52866f48270fdeb2177d67f6922f0a031e0101658624")
+                .unwrap();
+
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_empty() {
+        let text = [];
+        let key = [];
+        let expected =
+            hex::decode("b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad")
+                .unwrap();
 
-    for i in 0..test.len(){
-        sh.process(test[i]);
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
     }
 
-    let digest=sh.hash();
-    for i in 0..32 {print!("{:02x}",digest[i])}
+    #[test]
+    fn test_hmac_32_byte_key() {
+        let text = [0x0a];
+        let key = hex::decode("abababababababababababababababababababababababababababababababab")
+            .unwrap();
+        let expected =
+            hex::decode("43997a72e7b3b1c19e5566c940d5f2961c96802b58a3da2acd19dcc1a90a8d05")
+                .unwrap();
+
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_64_byte_key() {
+        let text = [0x0a];
+        let key = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+        let expected =
+            hex::decode("93a88773df742079e3512f3d10f4f8ac674e24c4eda78df46c2376dd3946750b")
+                .unwrap();
+
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_65_byte_key() {
+        let text = [0x0a];
+        let key = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0B").unwrap();
+        let expected =
+            hex::decode("7c8dd5068bcff3347dd13a7493247444635b51cf000b18f37a74a55cec3413fb")
+                .unwrap();
+
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_65_byte_text() {
+        let text = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0B").unwrap();
+        let key = [0x0b];
+        let expected =
+            hex::decode("f04344808f2fcdafe1c20272a29b1ce4be00c916a2c14700b82b81c6eae9dd96")
+                .unwrap();
+
+        let output = HASH256::hmac(&key, &text);
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hkdf_case_1() {
+        // From https://tools.ietf.org/html/rfc5869
+        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+        let salt = hex::decode("000102030405060708090a0b0c").unwrap();
+        let expected_prk =
+            hex::decode("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5")
+                .unwrap();
+
+        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap();
+        let l = 42;
+        let expected_okm = hex::decode(
+            "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+        )
+        .unwrap();
+
+        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+
+    #[test]
+    fn test_hkdf_case_2() {
+        // From https://tools.ietf.org/html/rfc5869
+        let ikm = hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f")
+            .unwrap();
+        let salt = hex::decode("606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf")
+            .unwrap();
+        let expected_prk =
+            hex::decode("06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244")
+                .unwrap();
+
+        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = hex::decode("b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
+            .unwrap();
+        let l = 82;
+        let expected_okm = hex::decode("b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87")
+            .unwrap();
+
+        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+
+    #[test]
+    fn test_hkdf_case_3() {
+        // From https://tools.ietf.org/html/rfc5869
+        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+        let salt = vec![];
+        let expected_prk =
+            hex::decode("19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04")
+                .unwrap();
+
+        let output_prk = HASH256::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = vec![];
+        let l = 42;
+        let expected_okm = hex::decode(
+            "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
+        )
+        .unwrap();
+
+        let output_okm = HASH256::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
 }
-*/
diff --git a/src/hash384.rs b/src/hash384.rs
index 2e3729e..5c349a1 100644
--- a/src/hash384.rs
+++ b/src/hash384.rs
@@ -109,6 +109,15 @@ const HASH384_K: [u64; 80] = [
     0x6c44198c4a475817,
 ];
 
+/// The block size of each round.
+const BLOCK_SIZE: usize = 128;
+/// Ipad Byte
+const IPAD_BYTE: u8 = 0x36;
+/// Opad Byte
+const OPAD_BYTE: u8 = 0x5c;
+/// Hash Length in Bytes
+const HASH_BYTES: usize = 48;
+
 pub struct HASH384 {
     length: [u64; 2],
     h: [u64; 8],
@@ -132,27 +141,27 @@ impl HASH384 {
     }
 
     fn sig0(x: u64) -> u64 {
-        return HASH384::s(28, x) ^ HASH384::s(34, x) ^ HASH384::s(39, x);
+        return Self::s(28, x) ^ Self::s(34, x) ^ Self::s(39, x);
     }
 
     fn sig1(x: u64) -> u64 {
-        return HASH384::s(14, x) ^ HASH384::s(18, x) ^ HASH384::s(41, x);
+        return Self::s(14, x) ^ Self::s(18, x) ^ Self::s(41, x);
     }
 
     fn theta0(x: u64) -> u64 {
-        return HASH384::s(1, x) ^ HASH384::s(8, x) ^ HASH384::r(7, x);
+        return Self::s(1, x) ^ Self::s(8, x) ^ Self::r(7, x);
     }
 
     fn theta1(x: u64) -> u64 {
-        return HASH384::s(19, x) ^ HASH384::s(61, x) ^ HASH384::r(6, x);
+        return Self::s(19, x) ^ Self::s(61, x) ^ Self::r(6, x);
     }
 
     fn transform(&mut self) {
-        /* basic transformation step */
+        // basic transformation step
         for j in 16..80 {
-            self.w[j] = HASH384::theta1(self.w[j - 2])
+            self.w[j] = Self::theta1(self.w[j - 2])
                 .wrapping_add(self.w[j - 7])
-                .wrapping_add(HASH384::theta0(self.w[j - 15]))
+                .wrapping_add(Self::theta0(self.w[j - 15]))
                 .wrapping_add(self.w[j - 16]);
         }
         let mut a = self.h[0];
@@ -166,11 +175,11 @@ impl HASH384 {
         for j in 0..80 {
             /* 64 times - mush it up */
             let t1 = hh
-                .wrapping_add(HASH384::sig1(e))
-                .wrapping_add(HASH384::ch(e, f, g))
+                .wrapping_add(Self::sig1(e))
+                .wrapping_add(Self::ch(e, f, g))
                 .wrapping_add(HASH384_K[j])
                 .wrapping_add(self.w[j]);
-            let t2 = HASH384::sig0(a).wrapping_add(HASH384::maj(a, b, c));
+            let t2 = Self::sig0(a).wrapping_add(Self::maj(a, b, c));
             hh = g;
             g = f;
             f = e;
@@ -190,9 +199,9 @@ impl HASH384 {
         self.h[7] = self.h[7].wrapping_add(hh);
     }
 
-    /* Initialise Hash function */
+    /// Initialise Hash function
     pub fn init(&mut self) {
-        /* initialise */
+        // initialise
         for i in 0..64 {
             self.w[i] = 0
         }
@@ -208,8 +217,8 @@ impl HASH384 {
         self.h[7] = HASH384_H7;
     }
 
-    pub fn new() -> HASH384 {
-        let mut nh = HASH384 {
+    pub fn new() -> Self {
+        let mut nh = Self {
             length: [0; 2],
             h: [0; 8],
             w: [0; 80],
@@ -218,7 +227,7 @@ impl HASH384 {
         return nh;
     }
 
-    /* process a single byte */
+    /// Process a single byte
     pub fn process(&mut self, byt: u8) {
         /* process the next message byte */
         let cnt = ((self.length[0] / 64) % 16) as usize;
@@ -234,15 +243,14 @@ impl HASH384 {
         }
     }
 
-    /* process an array of bytes */
-
+    /// Process an array of bytes
     pub fn process_array(&mut self, b: &[u8]) {
         for i in 0..b.len() {
             self.process(b[i])
         }
     }
 
-    /* process a 32-bit integer */
+    /// Process a 32-bit integer
     pub fn process_num(&mut self, n: i32) {
         self.process(((n >> 24) & 0xff) as u8);
         self.process(((n >> 16) & 0xff) as u8);
@@ -250,10 +258,10 @@ impl HASH384 {
         self.process((n & 0xff) as u8);
     }
 
-    /* Generate 48-byte Hash */
-    pub fn hash(&mut self) -> [u8; 48] {
+    /// Generate 48-byte Hash
+    pub fn hash(&mut self) -> [u8; HASH_BYTES] {
         /* pad message and finish - supply digest */
-        let mut digest: [u8; 48] = [0; 48];
+        let mut digest: [u8; 48] = [0; HASH_BYTES];
         let len0 = self.length[0];
         let len1 = self.length[1];
         self.process(0x80);
@@ -263,26 +271,178 @@ impl HASH384 {
         self.w[14] = len1;
         self.w[15] = len0;
         self.transform();
-        for i in 0..48 {
-            /* convert to bytes */
+        for i in 0..HASH_BYTES {
+            // convert to bytes
             digest[i] = ((self.h[i / 8] >> (8 * (7 - i % 8))) & 0xff) as u8;
         }
         self.init();
         return digest;
     }
+
+    /// Generate a HMAC
+    ///
+    /// https://tools.ietf.org/html/rfc2104
+    pub fn hmac(key: &[u8], text: &[u8]) -> [u8; HASH_BYTES] {
+        let mut k = key.to_vec();
+
+        // Verify length of key < BLOCK_SIZE
+        if k.len() > BLOCK_SIZE {
+            // Reduce key to 64 bytes by hashing
+            let mut hash384 = Self::new();
+            hash384.init();
+            hash384.process_array(&k);
+            k = hash384.hash().to_vec();
+        }
+
+        // Prepare inner and outer paddings
+        // inner = (ipad XOR k)
+        // outer = (opad XOR k)
+        let mut inner = vec![IPAD_BYTE; BLOCK_SIZE];
+        let mut outer = vec![OPAD_BYTE; BLOCK_SIZE];
+        for (i, byte) in k.iter().enumerate() {
+            inner[i] = inner[i] ^ byte;
+            outer[i] = outer[i] ^ byte;
+        }
+
+        // Concatenate inner with text = (ipad XOR k || text)
+        inner.extend_from_slice(text);
+
+        // hash inner = H(ipad XOR k || text)
+        let mut hash384 = Self::new();
+        hash384.init();
+        hash384.process_array(&inner);
+        let inner = hash384.hash();
+
+        // Concatenate outer with hash of inner = (opad XOR k) || H(ipad XOR k || text)
+        outer.extend_from_slice(&inner);
+
+        // Final hash = H((opad XOR k) || H(ipad XOR k || text))
+        let mut hash384 = Self::new();
+        hash384.init();
+        hash384.process_array(&outer);
+        hash384.hash()
+    }
+
+    /// HKDF-Extract
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extract(salt: &[u8], ikm: &[u8]) -> [u8; HASH_BYTES] {
+        Self::hmac(salt, ikm)
+    }
+
+    /// HKDF-Extend
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extend(prk: &[u8], info: &[u8], l: u8) -> Vec<u8> {
+        // n = cieling(l / 48)
+        let mut n = l / (HASH_BYTES as u8);
+        if n * (HASH_BYTES as u8) < l {
+            n += 1;
+        }
+
+        let mut okm: Vec<u8> = vec![];
+        let mut previous = vec![]; // T(0) = []
+
+        for i in 0..n as usize {
+            // Concatenate (T(i) || info || i)
+            let mut text: Vec<u8> = previous;
+            text.extend_from_slice(info);
+            text.push((i + 1) as u8); // Note: i <= 254
+
+            // T(i+1) = HMAC(PRK, T(i) || info || i)
+            previous = Self::hmac(prk, &text).to_vec();
+            okm.extend_from_slice(&previous);
+        }
+
+        // Reduce length to size L
+        okm.resize(l as usize, 0);
+        okm
+    }
 }
 
-//09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039
-/*
-fn main() {
-    let s = String::from("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
-    let test = s.into_bytes();
-    let mut sh=HASH384::new();
+#[cfg(test)]
+mod tests {
+    // TODO: Test HKDF
+    use super::*;
+
+    #[test]
+    fn test_hash384_simple() {
+        let text = [0x01];
+        let mut hash384 = HASH384::new();
+        hash384.init();
+        hash384.process_array(&text);
+        let output = hash384.hash().to_vec();
 
-    for i in 0..test.len(){
-        sh.process(test[i]);
+        let expected =
+            hex::decode("8d2ce87d86f55fcfab770a047b090da23270fa206832dfea7e0c946fff451f819add242374be551b0d6318ed6c7d41d8")
+                .unwrap();
+
+        assert_eq!(expected, output);
     }
 
-    let digest=sh.hash();
-    for i in 0..48 {print!("{:02x}",digest[i])}
-} */
+    #[test]
+    fn test_hash384_empty() {
+        let text = [];
+        let mut hash384 = HASH384::new();
+        hash384.init();
+        hash384.process_array(&text);
+        let output = hash384.hash().to_vec();
+
+        let expected =
+            hex::decode("38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b")
+                .unwrap();
+
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hash384_long() {
+        let text = hex::decode("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e01").unwrap();
+        let mut hash384 = HASH384::new();
+        hash384.init();
+        hash384.process_array(&text);
+        let output = hash384.hash().to_vec();
+
+        let expected =
+            hex::decode("1793c4989b4e68154c7159bee9756e5b72dbc0bd57c7583bb09c9a1c111f46fcaf8ef9faf1715e1eff36526c6c15a1f1")
+                .unwrap();
+
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_simple() {
+        let text = [0x01];
+        let key = [0x01];
+        let expected =
+            hex::decode("52650d924c6c3ed9f7b0fc64107e139d0d9254e8ecfb32e5780535897532ccee5272d61ec5d2abd19fa60e9f69f8711d")
+                .unwrap();
+
+        let output = HASH384::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_empty() {
+        let text = [];
+        let key = [];
+        let expected =
+            hex::decode("6c1f2ee938fad2e24bd91298474382ca218c75db3d83e114b3d4367776d14d3551289e75e8209cd4b792302840234adc")
+                .unwrap();
+
+        let output = HASH384::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_long() {
+        let text = hex::decode("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e01").unwrap();
+        let key = [0x01];
+        let expected =
+            hex::decode("dee07cba20bcf23f3913c6a885ac08b90702e2c5765f64040b336375c5ad35cce89e9c9f62983be516447e35e65de70c")
+                .unwrap();
+
+        let output = HASH384::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+}
diff --git a/src/hash512.rs b/src/hash512.rs
index 4eb0689..34970a7 100644
--- a/src/hash512.rs
+++ b/src/hash512.rs
@@ -109,6 +109,15 @@ const HASH512_K: [u64; 80] = [
     0x6c44198c4a475817,
 ];
 
+/// The block size of each round.
+const BLOCK_SIZE: usize = 128;
+/// Ipad Byte
+const IPAD_BYTE: u8 = 0x36;
+/// Opad Byte
+const OPAD_BYTE: u8 = 0x5c;
+/// Hash Length in Bytes
+const HASH_BYTES: usize = 64;
+
 pub struct HASH512 {
     length: [u64; 2],
     h: [u64; 8],
@@ -132,27 +141,27 @@ impl HASH512 {
     }
 
     fn sig0(x: u64) -> u64 {
-        return HASH512::s(28, x) ^ HASH512::s(34, x) ^ HASH512::s(39, x);
+        return Self::s(28, x) ^ Self::s(34, x) ^ Self::s(39, x);
     }
 
     fn sig1(x: u64) -> u64 {
-        return HASH512::s(14, x) ^ HASH512::s(18, x) ^ HASH512::s(41, x);
+        return Self::s(14, x) ^ Self::s(18, x) ^ Self::s(41, x);
     }
 
     fn theta0(x: u64) -> u64 {
-        return HASH512::s(1, x) ^ HASH512::s(8, x) ^ HASH512::r(7, x);
+        return Self::s(1, x) ^ Self::s(8, x) ^ Self::r(7, x);
     }
 
     fn theta1(x: u64) -> u64 {
-        return HASH512::s(19, x) ^ HASH512::s(61, x) ^ HASH512::r(6, x);
+        return Self::s(19, x) ^ Self::s(61, x) ^ Self::r(6, x);
     }
 
     fn transform(&mut self) {
         /* basic transformation step */
         for j in 16..80 {
-            self.w[j] = HASH512::theta1(self.w[j - 2])
+            self.w[j] = Self::theta1(self.w[j - 2])
                 .wrapping_add(self.w[j - 7])
-                .wrapping_add(HASH512::theta0(self.w[j - 15]))
+                .wrapping_add(Self::theta0(self.w[j - 15]))
                 .wrapping_add(self.w[j - 16]);
         }
         let mut a = self.h[0];
@@ -166,11 +175,11 @@ impl HASH512 {
         for j in 0..80 {
             /* 64 times - mush it up */
             let t1 = hh
-                .wrapping_add(HASH512::sig1(e))
-                .wrapping_add(HASH512::ch(e, f, g))
+                .wrapping_add(Self::sig1(e))
+                .wrapping_add(Self::ch(e, f, g))
                 .wrapping_add(HASH512_K[j])
                 .wrapping_add(self.w[j]);
-            let t2 = HASH512::sig0(a).wrapping_add(HASH512::maj(a, b, c));
+            let t2 = Self::sig0(a).wrapping_add(Self::maj(a, b, c));
             hh = g;
             g = f;
             f = e;
@@ -208,8 +217,8 @@ impl HASH512 {
         self.h[7] = HASH512_H7;
     }
 
-    pub fn new() -> HASH512 {
-        let mut nh = HASH512 {
+    pub fn new() -> Self {
+        let mut nh = Self {
             length: [0; 2],
             h: [0; 8],
             w: [0; 80],
@@ -270,19 +279,262 @@ impl HASH512 {
         self.init();
         return digest;
     }
+
+    /// Generate a HMAC
+    ///
+    /// https://tools.ietf.org/html/rfc2104
+    pub fn hmac(key: &[u8], text: &[u8]) -> [u8; 64] {
+        let mut k = key.to_vec();
+
+        // Verify length of key < BLOCK_SIZE
+        if k.len() > BLOCK_SIZE {
+            // Reduce key to 64 bytes by hashing
+            let mut hash512 = Self::new();
+            hash512.init();
+            hash512.process_array(&k);
+            k = hash512.hash().to_vec();
+        }
+
+        // Prepare inner and outer paddings
+        // inner = (ipad XOR k)
+        // outer = (opad XOR k)
+        let mut inner = vec![IPAD_BYTE; BLOCK_SIZE];
+        let mut outer = vec![OPAD_BYTE; BLOCK_SIZE];
+        for (i, byte) in k.iter().enumerate() {
+            inner[i] = inner[i] ^ byte;
+            outer[i] = outer[i] ^ byte;
+        }
+
+        // Concatenate inner with text = (ipad XOR k || text)
+        inner.extend_from_slice(text);
+
+        // hash inner = H(ipad XOR k || text)
+        let mut hash512 = Self::new();
+        hash512.init();
+        hash512.process_array(&inner);
+        let inner = hash512.hash();
+
+        // Concatenate outer with hash of inner = (opad XOR k) || H(ipad XOR k || text)
+        outer.extend_from_slice(&inner);
+
+        // Final hash = H((opad XOR k) || H(ipad XOR k || text))
+        let mut hash512 = Self::new();
+        hash512.init();
+        hash512.process_array(&outer);
+        hash512.hash()
+    }
+
+    /// HKDF-Extract
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extract(salt: &[u8], ikm: &[u8]) -> [u8; HASH_BYTES] {
+        Self::hmac(salt, ikm)
+    }
+
+    /// HKDF-Extend
+    ///
+    /// https://tools.ietf.org/html/rfc5869
+    pub fn hkdf_extend(prk: &[u8], info: &[u8], l: u8) -> Vec<u8> {
+        // n = cieling(l / 64)
+        let mut n = l / (HASH_BYTES as u8);
+        if n * (HASH_BYTES as u8) < l {
+            n += 1;
+        }
+
+        let mut okm: Vec<u8> = vec![];
+        let mut previous = vec![]; // T(0) = []
+
+        for i in 0..n as usize {
+            // Concatenate (T(i) || info || i)
+            let mut text: Vec<u8> = previous;
+            text.extend_from_slice(info);
+            text.push((i + 1) as u8); // Note: i <= 254
+
+            // T(i+1) = HMAC(PRK, T(i) || info || i)
+            previous = Self::hmac(prk, &text).to_vec();
+            okm.extend_from_slice(&previous);
+        }
+
+        // Reduce length to size L
+        okm.resize(l as usize, 0);
+        okm
+    }
 }
 
-//8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909
-/*
-fn main() {
-    let s = String::from("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
-    let test = s.into_bytes();
-    let mut sh=HASH512::new();
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_hash512_simple() {
+        let text = [0x01];
+        let mut hash512 = HASH512::new();
+        hash512.init();
+        hash512.process_array(&text);
+        let output = hash512.hash().to_vec();
+
+        let expected =
+            hex::decode("7b54b66836c1fbdd13d2441d9e1434dc62ca677fb68f5fe66a464baadecdbd00576f8d6b5ac3bcc80844b7d50b1cc6603444bbe7cfcf8fc0aa1ee3c636d9e339")
+                .unwrap();
 
-    for i in 0..test.len(){
-        sh.process(test[i]);
+        assert_eq!(expected, output);
     }
 
-    let digest=sh.hash();
-    for i in 0..64 {print!("{:02x}",digest[i])}
-} */
+    #[test]
+    fn test_hash512_empty() {
+        let text = [];
+        let mut hash512 = HASH512::new();
+        hash512.init();
+        hash512.process_array(&text);
+        let output = hash512.hash().to_vec();
+
+        let expected =
+            hex::decode("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+                .unwrap();
+
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hash512_long() {
+        let text = hex::decode("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e01").unwrap();
+        let mut hash512 = HASH512::new();
+        hash512.init();
+        hash512.process_array(&text);
+        let output = hash512.hash().to_vec();
+
+        let expected =
+            hex::decode("ca3088651246c66ac9c7a8afd727539ab2d8ce9234b5e1fec311e1e435d6d9eb152e41e8e9ad953dd737d0271ad2b0299cbd6f4eb9536de34c3a01411766c7be")
+                .unwrap();
+
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_simple() {
+        let text = [0x01];
+        let key = [0x01];
+        let expected =
+            hex::decode("503deb5732606d9595e308c8893fe56923fe470fc57021cf252dacb0ad15de020943e139d7a84e77956d34df3cc78142c090b959049a813cb19627c5b49c5761")
+                .unwrap();
+
+        let output = HASH512::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_empty() {
+        let text = [];
+        let key = [];
+        let expected =
+            hex::decode("b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47")
+                .unwrap();
+
+        let output = HASH512::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hmac_long() {
+        let text = hex::decode("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e01").unwrap();
+        let key = [0x01];
+        let expected =
+            hex::decode("d4a8d1b936eb79e6f56b85306e62dea59a54e81690a616e804eaefe2b1e0d7319eecd68494913b3a7e78755a0e1716bb0f0f3b60a810c65f61a909562811d372")
+                .unwrap();
+
+        let output = HASH512::hmac(&key, &text).to_vec();
+        assert_eq!(expected, output);
+    }
+
+    #[test]
+    fn test_hkdf_case_a() {
+        // From https://www.kullo.net/blog/hkdf-sha-512-test-vectors/
+        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+        let salt = hex::decode("000102030405060708090a0b0c").unwrap();
+        let expected_prk =
+            hex::decode("665799823737ded04a88e47e54a5890bb2c3d247c7a4254a8e61350723590a26c36238127d8661b88cf80ef802d57e2f7cebcf1e00e083848be19929c61b4237")
+            .unwrap();
+
+        let output_prk = HASH512::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = hex::decode("f0f1f2f3f4f5f6f7f8f9").unwrap();
+        let l = 42;
+        let expected_okm = hex::decode(
+            "832390086cda71fb47625bb5ceb168e4c8e26a1a16ed34d9fc7fe92c1481579338da362cb8d9f925d7cb",
+        )
+        .unwrap();
+
+        let output_okm = HASH512::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+
+    #[test]
+    fn test_hkdf_case_b() {
+        // From https://www.kullo.net/blog/hkdf-sha-512-test-vectors/
+        let ikm = hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f").unwrap();
+        let salt = hex::decode("606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf").unwrap();
+        let expected_prk =
+            hex::decode("35672542907d4e142c00e84499e74e1de08be86535f924e022804ad775dde27ec86cd1e5b7d178c74489bdbeb30712beb82d4f97416c5a94ea81ebdf3e629e4a")
+            .unwrap();
+
+        let output_prk = HASH512::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = hex::decode("b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff").unwrap();
+        let l = 82;
+        let expected_okm = hex::decode(
+                "ce6c97192805b346e6161e821ed165673b84f400a2b514b2fe23d84cd189ddf1b695b48cbd1c8388441137b3ce28f16aa64ba33ba466b24df6cfcb021ecff235f6a2056ce3af1de44d572097a8505d9e7a93",
+            )
+            .unwrap();
+
+        let output_okm = HASH512::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+
+    #[test]
+    fn test_hkdf_case_c() {
+        // From https://www.kullo.net/blog/hkdf-sha-512-test-vectors/
+        let ikm = hex::decode("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b").unwrap();
+        let salt = vec![];
+        let expected_prk =
+            hex::decode("fd200c4987ac491313bd4a2a13287121247239e11c9ef82802044b66ef357e5b194498d0682611382348572a7b1611de54764094286320578a863f36562b0df6")
+            .unwrap();
+
+        let output_prk = HASH512::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = vec![];
+        let l = 42;
+        let expected_okm = hex::decode(
+            "f5fa02b18298a72a8c23898a8703472c6eb179dc204c03425c970e3b164bf90fff22d04836d0e2343bac",
+        )
+        .unwrap();
+
+        let output_okm = HASH512::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+
+    #[test]
+    fn test_hkdf_case_d() {
+        // From https://www.kullo.net/blog/hkdf-sha-512-test-vectors/
+        let ikm = hex::decode("0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c").unwrap();
+        let salt = vec![];
+        let expected_prk =
+            hex::decode("5346b376bf3aa9f84f8f6ed5b1c4f489172e244dac303d12f68ecc766ea600aa88495e7fb605803122fa136924a840b1f0719d2d5f68e29b242299d758ed680c")
+            .unwrap();
+
+        let output_prk = HASH512::hkdf_extract(&salt, &ikm).to_vec();
+        assert_eq!(expected_prk, output_prk);
+
+        let info = vec![];
+        let l = 42;
+        let expected_okm = hex::decode(
+            "1407d46013d98bc6decefcfee55f0f90b0c7f63d68eb1a80eaf07e953cfc0a3a5240a155d6e4daa965bb",
+        )
+        .unwrap();
+
+        let output_okm = HASH512::hkdf_extend(&expected_prk, &info, l);
+        assert_eq!(expected_okm, output_okm);
+    }
+}
diff --git a/src/hash_to_curve.rs b/src/hash_to_curve.rs
new file mode 100644
index 0000000..fe8d962
--- /dev/null
+++ b/src/hash_to_curve.rs
@@ -0,0 +1,307 @@
+use super::big::Big;
+use super::dbig::DBig;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::rom::{
+    HASH_ALGORITHM, HASH_TYPE, L, MODULUS, SSWU_A1, SSWU_A2, SSWU_B1, SSWU_B2, SSWU_Z1, SSWU_Z2,
+    Z_PAD,
+};
+
+use errors::AmclError;
+use hash256::HASH256;
+use hash384::HASH384;
+use hash512::HASH512;
+
+/// Oversized DST padding
+pub const OVERSIZED_DST: &[u8] = b"H2C-OVERSIZE-DST-";
+
+#[derive(Copy, Clone)]
+pub enum HashAlgorithm {
+    Sha256,
+    Sha384,
+    Sha512,
+}
+
+/// Hash a message
+pub fn hash(msg: &[u8], hash_function: HashAlgorithm) -> Vec<u8> {
+    match hash_function {
+        HashAlgorithm::Sha256 => {
+            let mut hash = HASH256::new();
+            hash.init();
+            hash.process_array(msg);
+            hash.hash().to_vec()
+        }
+        HashAlgorithm::Sha384 => {
+            let mut hash = HASH384::new();
+            hash.init();
+            hash.process_array(msg);
+            hash.hash().to_vec()
+        }
+        HashAlgorithm::Sha512 => {
+            let mut hash = HASH512::new();
+            hash.init();
+            hash.process_array(msg);
+            hash.hash().to_vec()
+        }
+    }
+}
+
+// Hash To Field - Fp
+//
+// Take a message as bytes and convert it to a Field Point
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+pub fn hash_to_field_fp(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP>, AmclError> {
+    let m = 1;
+    let p = Big::new_ints(&MODULUS);
+
+    let len_in_bytes = count * m * L;
+    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+
+    let mut u: Vec<FP> = Vec::with_capacity(count as usize);
+    for i in 0..count as usize {
+        let elm_offset = L as usize * i * m as usize;
+        let mut dbig = DBig::frombytes(&pseudo_random_bytes[elm_offset..elm_offset + L as usize]);
+        let e: Big = dbig.dmod(&p);
+        u.push(FP::new_big(&e));
+    }
+    Ok(u)
+}
+
+// Hash To Field - Fp2
+//
+// Take a message as bytes and convert it to a vector of Field Points with extension degree 2.
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
+pub fn hash_to_field_fp2(msg: &[u8], count: usize, dst: &[u8]) -> Result<Vec<FP2>, AmclError> {
+    let m = 2;
+    let p = Big::new_ints(&MODULUS);
+
+    let len_in_bytes = count * m * L;
+
+    let pseudo_random_bytes = expand_message_xmd(msg, len_in_bytes, dst, HASH_ALGORITHM)?;
+
+    let mut u: Vec<FP2> = Vec::with_capacity(count as usize);
+    for i in 0..count as usize {
+        let mut e: Vec<Big> = Vec::with_capacity(m as usize);
+        for j in 0..m as usize {
+            let elm_offset = L as usize * (j + i * m as usize);
+            let mut big =
+                DBig::frombytes(&pseudo_random_bytes[elm_offset..elm_offset + L as usize]);
+            e.push(big.dmod(&p));
+        }
+        u.push(FP2::new_bigs(&e[0], &e[1]));
+    }
+    Ok(u)
+}
+
+// Expand Message XMD
+//
+// Take a message and convert it to pseudo random bytes of specified length
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.3.1
+pub fn expand_message_xmd(
+    msg: &[u8],
+    len_in_bytes: usize,
+    dst: &[u8],
+    hash_algorithm: HashAlgorithm,
+) -> Result<Vec<u8>, AmclError> {
+    // ell = ceiling(len_in_bytes / b_in_bytes)
+    let ell = (len_in_bytes + HASH_TYPE - 1) / HASH_TYPE;
+
+    // Error if length of output less than 255 bytes
+    if ell >= 255 {
+        return Err(AmclError::HashToFieldError);
+    }
+
+    // Create DST prime as (dst.len() || dst)
+    let dst_prime = if dst.len() > 256 {
+        // DST too long, shorten to H("H2C-OVERSIZE-DST-" || dst)
+        let mut tmp = OVERSIZED_DST.to_vec();
+        tmp.extend_from_slice(dst);
+        let mut prime = vec![32u8; 1];
+        prime.append(&mut hash(&tmp, hash_algorithm));
+        prime
+    } else {
+        // DST correct size, prepend length as a single byte
+        let mut prime = vec![dst.len() as u8; 1];
+        prime.extend_from_slice(dst);
+        prime
+    };
+
+    let mut pseudo_random_bytes: Vec<u8> = vec![];
+    let mut b: Vec<Vec<u8>> = vec![vec![]; 2];
+
+    // Set b[0] to H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime)
+    let mut tmp = Z_PAD.to_vec();
+    tmp.extend_from_slice(msg);
+    let l_i_b_str: &[u8] = &(len_in_bytes as u16).to_be_bytes();
+    tmp.extend_from_slice(l_i_b_str);
+    tmp.push(0u8);
+    tmp.extend_from_slice(&dst_prime);
+    b[0] = hash(&tmp, hash_algorithm);
+
+    // Set b[1] to H(b_0 || I2OSP(1, 1) || DST_prime)
+    tmp = b[0].clone();
+    tmp.push(1u8);
+    tmp.extend_from_slice(&dst_prime);
+    b[1] = hash(&tmp, hash_algorithm);
+
+    pseudo_random_bytes.extend_from_slice(&b[1]);
+
+    for i in 2..=ell {
+        // Set b[i] to H(strxor(b_0, b_(i - 1)) || I2OSP(i, 1) || DST_prime)
+        tmp = b[0]
+            .iter()
+            .enumerate()
+            .map(|(j, b_0)| {
+                // Perform strxor(b[0], b[i-1])
+                b_0 ^ b[i - 1][j] // b[i].len() will all be 32 bytes as they are SHA256 output.
+            })
+            .collect();
+        tmp.push(i as u8); // i < 256
+        tmp.extend_from_slice(&dst_prime);
+        b.push(hash(&tmp, hash_algorithm));
+
+        pseudo_random_bytes.extend_from_slice(&b[i]);
+    }
+
+    // Take required length
+    Ok(pseudo_random_bytes[..len_in_bytes as usize].to_vec())
+}
+
+// Simplified Shallue-van de Woestijne-Ulas Method - Fp
+//
+// Returns projectives as (XZ, YZ, Z)
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+pub fn simplified_swu_fp(u: FP) -> (FP, FP) {
+    // tmp1 = Z * u^2
+    // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
+    let mut tmp1 = u.clone();
+    let is_neg_u = tmp1.is_neg();
+    tmp1.sqr();
+    tmp1.mul(&SSWU_Z1);
+    let mut tv1 = tmp1.clone();
+    tv1.sqr();
+    tv1.add(&tmp1);
+    tv1.inverse();
+
+    // x = (-B / A) * (1 + tv1)
+    let mut x = tv1.clone();
+    x.add(&FP::new_int(1));
+    x.mul(&SSWU_B1); // b * (Z^2 * u^4 + Z * u^2 + 1)
+    x.neg();
+    let mut a_inverse = SSWU_A1.clone();
+    a_inverse.inverse();
+    x.mul(&a_inverse);
+
+    // Deal with case where Z^2 * u^4 + Z * u^2 == 0
+    if tv1.iszilch() {
+        // x = B / (Z * A)
+        x = SSWU_Z1.clone();
+        x.inverse();
+        x.mul(&SSWU_B1);
+        x.mul(&a_inverse);
+    }
+
+    // gx = x^3 + A * x + B
+    let mut gx = x.clone();
+    gx.sqr();
+    gx.add(&SSWU_A1);
+    gx.mul(&x);
+    gx.add(&SSWU_B1);
+
+    // y = sqrt(gx)
+    let mut y = gx.clone();
+    let mut y = y.sqrt();
+
+    // Check y is valid square root
+    let mut y2 = y.clone();
+    y2.sqr();
+    if !gx.equals(&y2) {
+        // x = x * Z^2 * u
+        x.mul(&tmp1);
+
+        // gx = x^3 + A * x + B
+        let mut gx = x.clone();
+        gx.sqr();
+        gx.add(&SSWU_A1);
+        gx.mul(&x);
+        gx.add(&SSWU_B1);
+
+        y = gx.sqrt();
+        y2 = y.clone();
+        y2.sqr();
+        assert_eq!(gx, y2, "Hash to Curve SSWU failure - no square roots");
+    }
+
+    // Negate y if y and t are opposite in sign
+    if is_neg_u != y.is_neg() {
+        y.neg();
+    }
+
+    (x, y)
+}
+
+// Simplified Shallue-van de Woestijne-Ulas Method - Fp2
+//
+// Returns projectives as (X, Y)
+// https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-6.6.2
+pub fn simplified_swu_fp2(u: FP2) -> (FP2, FP2) {
+    // tmp1 = Z * u^2
+    // tv1 = 1 / (Z^2 * u^4 + Z * u^2)
+    let mut tmp1 = u.clone();
+    let is_neg_u = tmp1.is_neg();
+    tmp1.sqr();
+    tmp1.mul(&SSWU_Z2);
+    let mut tv1 = tmp1.clone();
+    tv1.sqr();
+    tv1.add(&tmp1);
+    tv1.inverse();
+
+    // x = (-B / A) * (1 + tv1)
+    let mut x = tv1.clone();
+    x.add(&FP2::new_ints(1, 0));
+    x.mul(&SSWU_B2); // b * (Z^2 * u^4 + Z * u^2 + 1)
+    x.neg();
+    let mut a_inverse = SSWU_A2.clone();
+    a_inverse.inverse();
+    x.mul(&a_inverse);
+
+    // Deal with case where Z^2 * u^4 + Z * u^2 == 0
+    if tv1.iszilch() {
+        // x = B / (Z * A)
+        x = SSWU_Z2.clone();
+        x.inverse();
+        x.mul(&SSWU_B2);
+        x.mul(&a_inverse);
+    }
+
+    // gx = x^3 + A * x + B
+    let mut gx = x.clone();
+    gx.sqr();
+    gx.add(&SSWU_A2);
+    gx.mul(&x);
+    gx.add(&SSWU_B2);
+
+    // y = sqrt(gx)
+    let mut y = gx.clone();
+    if !y.sqrt() {
+        // x = x * Z^2 * u
+        x.mul(&tmp1);
+
+        // gx = x^3 + A * x + B
+        let mut gx = x.clone();
+        gx.sqr();
+        gx.add(&SSWU_A2);
+        gx.mul(&x);
+        gx.add(&SSWU_B2);
+
+        y = gx;
+        assert!(y.sqrt(), "Hash to Curve SSWU failure - no square roots");
+    }
+
+    // Negate y if y and t are opposite in sign
+    if is_neg_u != y.is_neg() {
+        y.neg();
+    }
+
+    (x, y)
+}
diff --git a/src/lib.rs b/src/lib.rs
index 9849b2b..6575763 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,12 @@
+#[macro_use]
+extern crate lazy_static;
+
+#[cfg(test)]
+extern crate serde_json;
+#[cfg(test)]
+#[macro_use]
+extern crate serde_derive;
+
 pub mod aes;
 #[cfg(target_pointer_width = "32")]
 #[path = "arch/arch32.rs"]
@@ -5,6 +14,7 @@ pub mod arch;
 #[cfg(target_pointer_width = "64")]
 #[path = "arch/arch64.rs"]
 pub mod arch;
+pub mod errors;
 pub mod gcm;
 pub mod hash256;
 pub mod hash384;
@@ -85,18 +95,42 @@ pub mod bls383 {
     pub mod pair;
 }
 
-#[cfg(feature = "bls381")]
+#[cfg(feature = "bls381g1")]
 #[path = "./"]
-pub mod bls381 {
+pub mod bls381g1 {
     #[cfg(target_pointer_width = "32")]
-    #[path = "roms/rom_bls381_32.rs"]
+    #[path = "roms/rom_bls381g1_32.rs"]
     pub mod rom;
     #[cfg(target_pointer_width = "64")]
-    #[path = "roms/rom_bls381_64.rs"]
+    #[path = "roms/rom_bls381g1_64.rs"]
     pub mod rom;
 
     pub mod big;
-    pub mod bls;
+    pub mod bls381;
+    pub mod dbig;
+    pub mod ecp;
+    pub mod ecp2;
+    pub mod fp;
+    pub mod fp12;
+    pub mod fp2;
+    pub mod fp4;
+    pub mod hash_to_curve;
+    pub mod mpin;
+    pub mod pair;
+}
+
+#[cfg(feature = "bls381g2")]
+#[path = "./"]
+pub mod bls381g2 {
+    #[cfg(target_pointer_width = "32")]
+    #[path = "roms/rom_bls381g2_32.rs"]
+    pub mod rom;
+    #[cfg(target_pointer_width = "64")]
+    #[path = "roms/rom_bls381g2_64.rs"]
+    pub mod rom;
+
+    pub mod big;
+    pub mod bls381;
     pub mod dbig;
     pub mod ecp;
     pub mod ecp2;
@@ -104,6 +138,7 @@ pub mod bls381 {
     pub mod fp12;
     pub mod fp2;
     pub mod fp4;
+    pub mod hash_to_curve;
     pub mod mpin;
     pub mod pair;
 }
diff --git a/src/nhs.rs b/src/nhs.rs
index 9a7f856..338582e 100644
--- a/src/nhs.rs
+++ b/src/nhs.rs
@@ -751,5 +751,4 @@ mod tests {
         }
         println!("");
     }
-
 }
diff --git a/src/roms/rom_bls381_32.rs b/src/roms/rom_bls381g1_32.rs
similarity index 82%
copy from src/roms/rom_bls381_32.rs
copy to src/roms/rom_bls381g1_32.rs
index e282e9d..f72806d 100644
--- a/src/roms/rom_bls381_32.rs
+++ b/src/roms/rom_bls381g1_32.rs
@@ -18,7 +18,10 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bls381::big::NLEN;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::hash_to_curve::HashAlgorithm;
+use bls381g2::big::{Big, NLEN};
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
@@ -205,5 +208,34 @@ pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
 pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
 pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
-pub const HASH_TYPE: usize = 32;
+pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
 pub const AESKEY: usize = 16;
+
+/// Signatures on G1: true, Signatures on G2: false
+pub const BLS_SIG_G1: bool = true;
+
+// BLS Standard Constants
+/// L = ceil(ceil(log2(Q) + 128) / 8)
+pub const L: usize = 64;
+/// Hash to Curve Suite
+pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
+/// Domain Separation Tag
+pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
+/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+pub const Z_PAD: [u8; 64] = [0u8; 64];
+
+lazy_static! {
+    // G1 h_eff
+    pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
+    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+    pub static ref SSWU_Z1: FP = FP::new_int(11);
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+    pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+    pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+}
diff --git a/src/roms/rom_bls381_64.rs b/src/roms/rom_bls381g1_64.rs
similarity index 76%
copy from src/roms/rom_bls381_64.rs
copy to src/roms/rom_bls381g1_64.rs
index 4d95fdb..51bd4b9 100644
--- a/src/roms/rom_bls381_64.rs
+++ b/src/roms/rom_bls381g1_64.rs
@@ -18,7 +18,10 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bls381::big::NLEN;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::hash_to_curve::HashAlgorithm;
+use bls381g1::big::{Big, NLEN};
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
@@ -207,5 +210,36 @@ pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
 pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
 pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
-pub const HASH_TYPE: usize = 32;
+pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
 pub const AESKEY: usize = 16;
+
+/// Signatures on G1: true, Signatures on G2: false
+pub const BLS_SIG_G1: bool = true;
+
+// BLS Standard Constants
+/// L = ceil(ceil(log2(Q) + 128) / 8)
+pub const L: usize = 64;
+/// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+pub const B_IN_BYTES: usize = 32;
+/// Hash to Curve Suite
+pub const H2C_SUITE: &str = "BLS12381G1_XMD:SHA-256_SSWU_RO_";
+/// Domain Separation Tag
+pub const DST: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_";
+/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+pub const Z_PAD: [u8; 64] = [0u8; 64];
+
+lazy_static! {
+    // G1 h_eff
+    pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
+    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+    pub static ref SSWU_Z1: FP = FP::new_int(11);
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+    pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+    pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+}
diff --git a/src/roms/rom_bls381_32.rs b/src/roms/rom_bls381g2_32.rs
similarity index 81%
rename from src/roms/rom_bls381_32.rs
rename to src/roms/rom_bls381g2_32.rs
index e282e9d..af198a8 100644
--- a/src/roms/rom_bls381_32.rs
+++ b/src/roms/rom_bls381g2_32.rs
@@ -18,7 +18,10 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bls381::big::NLEN;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::hash_to_curve::HashAlgorithm;
+use bls381g2::big::{Big, NLEN};
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 29
@@ -205,5 +208,36 @@ pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
 pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
 pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
-pub const HASH_TYPE: usize = 32;
+pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
 pub const AESKEY: usize = 16;
+
+/// Signatures on G1: true, Signatures on G2: false
+pub const BLS_SIG_G1: bool = false;
+
+// BLS Standard Constants
+/// L = ceil(ceil(log2(Q) + 128) / 8)
+pub const L: usize = 64;
+/// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+pub const B_IN_BYTES: usize = 32;
+/// Hash to Curve Suite
+pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
+/// Domain Separation Tag
+pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
+/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+pub const Z_PAD: [u8; 64] = [0u8; 64];
+
+lazy_static! {
+    // G1 h_eff
+    pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
+    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+    pub static ref SSWU_Z1: FP = FP::new_int(11);
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+    pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+    pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+}
diff --git a/src/roms/rom_bls381_64.rs b/src/roms/rom_bls381g2_64.rs
similarity index 76%
rename from src/roms/rom_bls381_64.rs
rename to src/roms/rom_bls381g2_64.rs
index 4d95fdb..e3d6815 100644
--- a/src/roms/rom_bls381_64.rs
+++ b/src/roms/rom_bls381g2_64.rs
@@ -18,7 +18,10 @@ under the License.
 */
 
 use super::super::arch::Chunk;
-use bls381::big::NLEN;
+use super::fp::FP;
+use super::fp2::FP2;
+use super::hash_to_curve::HashAlgorithm;
+use bls381g2::big::{Big, NLEN};
 use types::{CurvePairingType, CurveType, ModType, SexticTwist, SignOfX};
 
 // Base Bits= 58
@@ -207,5 +210,36 @@ pub const CURVE_PAIRING_TYPE: CurvePairingType = CurvePairingType::Bls;
 pub const SEXTIC_TWIST: SexticTwist = SexticTwist::MType;
 pub const ATE_BITS: usize = 65;
 pub const SIGN_OF_X: SignOfX = SignOfX::NegativeX;
-pub const HASH_TYPE: usize = 32;
+pub const HASH_ALGORITHM: HashAlgorithm = HashAlgorithm::Sha256; // Hash algorithm for hash to curve
+pub const HASH_TYPE: usize = 32; // Output size of hash algorithm
 pub const AESKEY: usize = 16;
+
+/// Signatures on G1: true, Signatures on G2: false
+pub const BLS_SIG_G1: bool = false;
+
+// BLS Standard Constants
+/// L = ceil(ceil(log2(Q) + 128) / 8)
+pub const L: usize = 64;
+/// b_in_bytes = ceil(b / 8), where b is bits outputted from SHA256
+pub const B_IN_BYTES: usize = 32;
+/// Hash to Curve Suite
+pub const H2C_SUITE: &str = "BLS12381G2_XMD:SHA-256_SSWU_RO_";
+/// Domain Separation Tag
+pub const DST: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
+/// Z_PAD is a vector of zeros of length equal to the hash block size (64).
+pub const Z_PAD: [u8; 64] = [0u8; 64];
+
+lazy_static! {
+    // G1 h_eff
+    pub static ref H_EFF_G1: Big = Big::frombytes(&mut hex::decode("d201000000010001").unwrap());
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A1: FP = FP::new_big(&Big::frombytes(&hex::decode("00144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d").unwrap()));
+    pub static ref SSWU_B1: FP = FP::new_big(&Big::frombytes(&hex::decode("12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0").unwrap()));
+    pub static ref SSWU_Z1: FP = FP::new_int(11);
+
+    // Curve parameters of G2 ISO-3: y^2 = x^3 + ax + b
+    pub static ref SSWU_A2: FP2 = FP2::new_ints(0, 240);
+    pub static ref SSWU_B2: FP2 = FP2::new_ints(1012, 1012);
+    pub static ref SSWU_Z2: FP2 = FP2::new_ints(-2, -1);
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
new file mode 100644
index 0000000..cba0e19
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
@@ -0,0 +1,77 @@
+{
+  "L": "0x40",
+  "Z": "0xb",
+  "ciphersuite": "BLS12381G1_XMD:SHA-256_SSWU_NU_",
+  "curve": "BLS12381G1",
+  "dst": "BLS12381G1_XMD:SHA-256_SSWU_NU_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x1",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SSWU",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": false,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x115281bd55a4103f31c8b12000d98149598b72e5da14e953277def263a24bc2e9fd8fa151df73ea3800f9c8cbb9b245c",
+        "y": "0x0796506faf9edbf1957ba8d667a079cab0d3a37e302e5132bd25665b66b26ea8556a0cfb92d6ae2c4890df0029b455ce"
+      },
+      "Q": {
+        "x": "0x0dddf77f320e7848a457358ab8d3b84cbaf19307be26b91a10c211651691cd736b1f59d77aed3954f857f108d6966f5b",
+        "y": "0x0450ab32020649f22a2fca166a1d8a59d4c93f1eb078a4bedd6c48027b9933507a2a8ae4d915305f58ede781283325a9"
+      },
+      "msg": "",
+      "u": [
+        "0x0ccb6bda9b602ab82aae21c0291623e2f639648a6ada1c76d8ffb664130fd18d98a2cc6160624148827a9726678e7cd4"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x04a7a63d24439ade3cd16eaab22583c95b061136bd5013cf109d92983f902c31f49c95cbeb97222577e571e97a68a32e",
+        "y": "0x09a8aa8d6e4b409bbe9a6976c016688269024d6e9d378ed25e8b4986194511f479228fa011ec88b8f4c57a621fc12187"
+      },
+      "Q": {
+        "x": "0x12897a9a513b12303a7f0f3a3cc7c838d16847a31507980945312bede915848159bd390b16b8e378b398e31a385d9180",
+        "y": "0x1372530cc0811d70071e50640281aa8aaf96ee09c01281ccfead92296cb9dacf5054aa51dbea730e46239e709042a15d"
+      },
+      "msg": "abc",
+      "u": [
+        "0x08accd9a1bd4b75bb2e9f014ac354a198cbf607f0061d00a6286f5544cf4f9ecc1439e3194f570cbbc7b96d1a754f231"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x05c59faaf88187f51cd9cc6c20ca47ac66cc38d99af88aef2e82d7f35104168916f200a79562e64bc843f83cdc8a4675",
+        "y": "0x0b10472100a4aaa665f35f044b14a234b8f74990fa029e3dd06aa60b232fd9c232564ceead8cdb72a8a0320fc1071845"
+      },
+      "Q": {
+        "x": "0x08459bd42a955d6e247fce6c81eda0ad9645f9e666d141a71f0afa3fbc509b2c58550fe077d073cc752493400399fddd",
+        "y": "0x169d35a8c6bb915ae910f4c6cde359622746b0c8b2b241b411d0e92ef991d3e6a7b0fafabb93c1de2e3997d6e362ce8a"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x0a359cf072db3a39acf22f086d825fcf49d0daf241d98902342380fc5130b44e55de8f684f300bc11c44dee526413363"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x10147709f8d4f6f2fa6f957f6c6533e3bf9069c01be721f9421d88e0f02d8c617d048c6f8b13b81309d1ef6b56eeddc7",
+        "y": "0x1048977c38688f1a3acf48ae319216cb1509b6a29bd1e7f3b2e476088a280e8c97d4a4c147f0203c7b3acb3caa566ae8"
+      },
+      "Q": {
+        "x": "0x08c937d529c01ab2398b85b0bff6da465ed6265d4944dbbef7d383eea40157927082739c7b5417027d2225c6cb9d5ef0",
+        "y": "0x059047d83b5ea1ff7f0665b406acede27f233d3414055cbff25b37614b679f08fd6d807b5956edec6abad36c5321d99e"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x181d09392c52f7740d5eaae52123c1dfa4808343261d8bdbaf19e7773e5cdfd989165cd9ecc795500e5da2437dde2093"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
new file mode 100644
index 0000000..43785d3
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
@@ -0,0 +1,97 @@
+{
+  "L": "0x40",
+  "Z": "0xb",
+  "ciphersuite": "BLS12381G1_XMD:SHA-256_SSWU_RO_",
+  "curve": "BLS12381G1",
+  "dst": "BLS12381G1_XMD:SHA-256_SSWU_RO_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x1",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SSWU",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": true,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x14738daf70f5142df038c9e3be76f5d71b0db6613e5ef55cfe8e43e27f840dc75de97092da617376a9f598e7a0920c47",
+        "y": "0x12645b7cb071943631d062b22ca61a8a3df2a8bdac4e6fcd2c18643ef37a98beacf770ce28cb01c8abf5ed63d1a19b53"
+      },
+      "Q0": {
+        "x": "0x02f2686965a4dd27ccb11119f2e131aefee818744a414d23ecef4db1407991fdf058f0affaee18fd586a9ab81060ae20",
+        "y": "0x0341a16c88a39b3d111b36b7cf885b7147b1d54b9201faaba5b47d7839bcf433cc35bb1f7b8e55aa9382a52fe4d84370"
+      },
+      "Q1": {
+        "x": "0x1357bddd2bc6c8e752f3cf498ffe29ae87d8ff933701ae76f82d2839b0d9aee5229d4fff54dfb8223be0d88fa4485863",
+        "y": "0x09ba0ec3c78cf1e65330721f777b529aef27539642c39be11f459106b890ec5eb4a21c5d94885603e822cfa765170857"
+      },
+      "msg": "",
+      "u": [
+        "0x14700e34d15178550475044b044b4e41ca8d52a655c34f8afea856d21d499f48c9370d2bae4ae8351305493e48d36ab5",
+        "0x17e2da57f6fd3f11dba6119db4cd26b03e63e67b4e42db678d9c41fdfcaff00ba336d8563abcd9da6c17d2e1784ee858"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x01fea27a940188120178dfceec87dca78b745b6e73757be21c54d6cee6f07e3d5a465cf425c9d34dccfa95acffa86bf2",
+        "y": "0x18def9271f5fd253380c764a6818e8b6524c3d35864fcf963d85031225d62bf8cd0abeb326c3c62fec56f6100fa04367"
+      },
+      "Q0": {
+        "x": "0x119cc1d21e3e494d388a8718fe9f8ec6d8ff134486ce5c1f97129797616c4b8125f0dc568c59836cbf064496136438bc",
+        "y": "0x19e6c998825ee57b82c4808e4df477680f0f254c9edce228104422494a4e5d40d11ee676f6b861b6c49cf7de9d777aef"
+      },
+      "Q1": {
+        "x": "0x0d1783f40bd83461b921c3fcd0e9ba326ef75272b122cf44338f0060d7179995a38ea9c66f3ce800e2f693d2634a4524",
+        "y": "0x017b2566d55fa7ee43844f1fa068cb0a11d5889c11607d939da046697c8ba25cf71054c2a8eb2189d3680485a39f5bdd"
+      },
+      "msg": "abc",
+      "u": [
+        "0x10c84aa245c74ee20579a27e63199be5d19cdfb5e44c6b587765931605d7790a1df6e1433f78bcddb4edb8553374f75e",
+        "0x0f73433dcc2b5f9905c49d905bd62e1a1529b057c77194e56d196860d9d645167e0430aec9d3c70de31dd046fcab4a20"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0bdbca067fc4458a1206ecf3e235b400449c5693dd99e99a9793da076cb65e1b796bc279c892ae1c320c3783e25062d2",
+        "y": "0x12ca3f12b93b0028390a4ef4fa7083cb23f66ca42423e6e53987620e1d57c23a0ad6a14db1f709d0494c7d5122e0632f"
+      },
+      "Q0": {
+        "x": "0x1614d05720a39379fb89469883f90ae3e50995def9e17f8f8566a3f6cfb4fe88267eac1dc7834406fc597965065ef100",
+        "y": "0x1060e5aab331ac4940693a936ea80029bb2c4a3945add7ae35bce805e767af827c4a9ffcb5842fbc50ab234716d895f6"
+      },
+      "Q1": {
+        "x": "0x0f612cda21cee750b1ccff361a4ce047e70d9a9e152e96a60aa29b5d8a5dcd25f7c5bd71bb56bd34e6a8af7532afaa4f",
+        "y": "0x1878f926302468949ef290b4fee621d1172e072eda1b42e366df68fc87f53c35583dbc043009e0b38a04a9b1ff617efe"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x11503eb4a558d0d2c5fc7cdddb51ba715c33577cf1a7f2f21a7eee6d2a570332bbbe53ae3392c9f8d8f6c172ae484692",
+        "0x0efd59b8d98be7c491dfdb9d2a669e32e9bb348f8a64dbf7e47708dd5d40f484b1439109a3f96230bf63af72b908c43d"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0a81ca09b6a8c05712396801e6432a87b14ab1f764fa519e9f515816607283fe2a653a191fc1c8fee89cd30195e7a8e1",
+        "y": "0x11c7f1b59bb552692288da6557d1b5c72a448101faf56dd4125d8422af1425c4ddeecfbd5200525064657a79bdd0c3ed"
+      },
+      "Q0": {
+        "x": "0x0a817078e7f30f08e94a25c2a1947160db1fe52042626660b8252cd339e678a1fecc0e6da60390a203532bd089a426b6",
+        "y": "0x097bd5d6ae3f5b5d0ba5e4099485caa2c505a1d900e4525af10254b3927ae0c82611be944ff8fdc6b278aab9e17ee27c"
+      },
+      "Q1": {
+        "x": "0x1098f203da72c58dca61ffd52a3de82603d3154c527df51c2efe6298ea0eeaa065d57ba3a809b5e32d9d56dade119006",
+        "y": "0x0bcbd9df3505f049476f060c1d1c958fe8b34e426fd7e75424c9e227d9c4d3edbd5eddb8b1e89cc91b4a7bd3275d4d70"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x134dc7f817cc08c5a3128892385ff6e9dd55f5e39d9a2d74ac74058d5dfc025d507806ab5d9254bd2334defbb477400d",
+        "0x0eeaf2c6f4c1ca5cc039d99cb94234f67e65968f36d9dd77e95da55dadd085b50fbb11489167ded9157e5aac0d99d5be"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json
new file mode 100644
index 0000000..9e9e234
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_NU_.json
@@ -0,0 +1,77 @@
+{
+  "L": "0x40",
+  "Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa8",
+  "ciphersuite": "BLS12381G1_XMD:SHA-256_SVDW_NU_",
+  "curve": "BLS12381G1",
+  "dst": "BLS12381G1_XMD:SHA-256_SVDW_NU_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x1",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SVDW",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": false,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x126690faf7d2cc7838d18f58ae94e9eab1d042fb93ed7245aee5a1a3ecac3f1935df62b807f9bd7be1018492b4ccd087",
+        "y": "0x0d2fe772107e935ddfb916da6dd69cb3c9b112cbd7452a3da77e16620f58c06db9c1eb19ab031995c96dc2d0c16b5031"
+      },
+      "Q": {
+        "x": "0x10c4561604827f4687f7bf5a365411577c6c0298910d6a67685c675f1dd0b59ac5fbb46b729b3389499aaaf5b11bfc06",
+        "y": "0x114963eba7ffc5e3bc4c86a1dbf73b4952bfd60fa94449b2adc81dee0e974e4afd228a1af4fb1d4ede14cdc727deed0c"
+      },
+      "msg": "",
+      "u": [
+        "0x1754372e423dd665efc2703d235a5b42ad5609ee9872c303a0b900b152d5ae8d64c2d67764a6f188b87d61445cf5634c"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x03929609010843a52432b815cb5fb90d6a5ee8a10cc75c70d6f1bd64642a0057d2e69187ea3fff0a34e7e72b1cef5948",
+        "y": "0x196b4734ee0b1845619e8b871c0a2ea556660dab119868ad5542dc5b782b0df61cb6d2a1b2cd174a80cbc9f8cde6d470"
+      },
+      "Q": {
+        "x": "0x0f5b63a00bd63757fab41dbc9b47b679650d903a83934eb920a13097d58dd5f82068c059bf1de52971373c3cc83c427e",
+        "y": "0x03f2547ce0337e25a9fad27335f499b054cc1ab3e1c29366959599b5d362602bedcce56c0e039c4ec0fbbdf041564892"
+      },
+      "msg": "abc",
+      "u": [
+        "0x0a55c5bc65256c488bb068e3b1d5d2fc4acb3017da1f7d9a3a9036eb5880123b0aad219aedb4836eab28e7a85d171054"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x107485fecc3be4b92f8cc35f1782c67742d055c379e6bcb77836396edebe728aec4ecad0290bd1bbd5be7047ccb8554c",
+        "y": "0x0603d69e02982c8a0edc6fd84848fa9d9c75a0d7a372eb1ea2672245ee2d9ed672cd1a564fec3cb77758b966316d5c09"
+      },
+      "Q": {
+        "x": "0x09c7ef760508a7d4a226869cae2c556a8773ebf5d4bbba33b0cffbbba598105bf7549cd33d52ded62be72f718ab0ac9c",
+        "y": "0x0aa4882a7806cac7bb3bd6404000066b7c6ff14dc590efa26f2740b1af2f3be2b50e1d5b99b37d723d9d3b0cf089bf62"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x06983540e75c0e7a36976a66cbfee71e05c9ea2cbdb3b0f25aa9329e02ee95895fcde7262dae46c370c148e1027c4819"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x06c214d69a4ecd4fd0230f2dd2a8988daff27c597acee1ec5e6045e0848894d1435f5c143f4226fbc27a2045921c2499",
+        "y": "0x179e0869d8c73643e0bc27ebe3178ee297ad366c9a4f416a0b0ac2265ff763fbd8c0bf37e637d081190352f4c1961f74"
+      },
+      "Q": {
+        "x": "0x0598fd95bcd0a790e6921a51f212f5194781521cf32fcea581be2a5cbfd2a8fda8828141a24168689a273d258b1fe083",
+        "y": "0x04d0dbee266de33d9bee538d188e209476ebe3b34e58a19d0ea6ae542219b3f3549685ef3eef82991feb23ddde098285"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x011a4d12d373940b946029aef4bbdbb880810b25370d1f5b171e2d68091fabc9a4c8fc4f39c9b0ef98c34b5f90070a9d"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json
new file mode 100644
index 0000000..8384f86
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G1_XMD:SHA-256_SVDW_RO_.json
@@ -0,0 +1,97 @@
+{
+  "L": "0x40",
+  "Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa8",
+  "ciphersuite": "BLS12381G1_XMD:SHA-256_SVDW_RO_",
+  "curve": "BLS12381G1",
+  "dst": "BLS12381G1_XMD:SHA-256_SVDW_RO_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x1",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SVDW",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": true,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x045f87745ff759f9197e131ad83d47d635dc36a3e0c7e4a1be5e1effe5e63ac69c8f34e6c3aef9c5cf28224922788367",
+        "y": "0x06125886a03f883740a078313d5fa6e4a68b9c0394eb75f77c65fc8b44db3f4ef933ac6adf341bc45fabc7907afcb832"
+      },
+      "Q0": {
+        "x": "0x0d8deaf1a9fe87c5710466d0cd554b243a041a97c15228f1c65be6244b5e1a575f4ab2762a1cc9ff18d45d4f1494e2c6",
+        "y": "0x090dce51930eff6bccfc7cc2920f180c398b0a97085ff9e4841367e701a0f28616bef537203d27b0656f3b7ee52ee0ac"
+      },
+      "Q1": {
+        "x": "0x0a36d0d4051eb32d253b069d1d15c5b69cefbb75bf38d66d43b37432b34f88b2553bf063c6533ca87112c3e95c295ebf",
+        "y": "0x0bdc425e77f44ac13587b17dab2b1b9d3e3501be1fe1c56c7f3701fbe53b43a37263c04fd9aa1b7f58b1b63fe6cb29fd"
+      },
+      "msg": "",
+      "u": [
+        "0x04a74117c448f7aad70bd41328b3856de638c0e10c9ff344295a04b90db0f2afe80ff2da62e091793d6e52bc70b28d47",
+        "0x06f44093874c190fff1e893c847a59601d5d5ac0aebd85ba36b3906a93173e0d2fcf6bed8013ee2679ca337f21f8f053"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x009a357691a6f7b2917d9a34ba64d896d40b49733fcb3207f8c146e20fffb47823198a26b6ceeb01215fc3422908020e",
+        "y": "0x03fe44c894c107a8547826b60f577b90f80c63f899ef9dcff94daadae180ad803609337c9ec97d6d9b8ba306df7a9849"
+      },
+      "Q0": {
+        "x": "0x01b50bac3377c4e764fda5fcbe9bb477c3becb8cf18a3026a88ab2a0fbf6d8164d60d85ac9e67b6712fbb26b10ec4597",
+        "y": "0x11acedae54a20e1f8d58fd074e1b7de957203f56365b52a09824ff9f8d191356914818bdb35faffe8657ad24e1f5db5f"
+      },
+      "Q1": {
+        "x": "0x16bb1fce160d3fb5194b275a907cb03bfbe8713e830f2a573acc26782c65c9a6e88d96c6489c96dc6f65815cb5ab2662",
+        "y": "0x159720d02fef12d1a40b1c91336908d72b0eb1fe54a16a914c5ae9710a8fa8dfad035ac6c39708c88318fe26113f28d5"
+      },
+      "msg": "abc",
+      "u": [
+        "0x145191560d1db38062a0a2e29469d71eb035f888cd4bb2792ddf88ad63c93320738a3e4c6e199bb286e26efaad665a0f",
+        "0x17f7bbcbcf64dedb58af6560e2b2d08a678e4a57a0b042978840abb77f25b33090035675ac30bb461a8955a9d1ebb411"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x04eb09680fe48598533932907810fb7681e60b3689cb138454bec627490c5089b6dd755556e52a36c3817e98b62d7497",
+        "y": "0x1763dd8bf6823d9a22124d22a4ab3d93d8a9603ec80b4a40905b26664b16033fa6e73a6155c9bc4c6faa42bf911ffba1"
+      },
+      "Q0": {
+        "x": "0x164e16e858fa1e1a4ea52152ffe0a42f1e6ae1258dd830eb7aa66434d7d5689da945e29c61766ae213bc1878363a3d4c",
+        "y": "0x077cc4c8f74f33a0e6036d32c4407b3021b0be82e0eba80a1fc119f69a071c52f25764dbd72f2cafb420264c079b7691"
+      },
+      "Q1": {
+        "x": "0x06a856de4eb5651a21c68c7e85796c16e417d7d97cb3e1b74bbc4042b340e647fc41cc570bd160fe9917d32a47bc8b5e",
+        "y": "0x15c4e89949bbdb253d333018a1417150f8a78187c343f5bbdf25d962c513df1d96ee1059facab028549ebe7716164466"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x06ed3e25d860fc574e482bbc0a09c5f44216ad44d75ea499cf905efe4bc3c5fd3e94df483d17501395f325d3c8ea7925",
+        "0x1426c02b7de4bedb4a301c7d2d4a270f672a8fc448471f2c3dfcf43846b102e592ad6e055c2d5149fcbc21f5fb6002c0"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0915842b42c2c4d3b509823c60c1fad834784ff451855f43390b80c3b6985d76aadc6ecfbb4b42a07921410d6821f0bb",
+        "y": "0x052873ee0b444dd8337ce403636d680cff1e9402b7a1ce2ab210bff11a83fe4e14216fe96efe3f344c1a2ec0fc1b2c5f"
+      },
+      "Q0": {
+        "x": "0x15901778217bbe602fe603edfa0518009197445f34dd2184450fb2a1a5088945c32d31f6a9fcd9e3c4333557a11c18a3",
+        "y": "0x126fc2597e155f4aeeacb7a039b5a0012be2cc1433d8c097b6c8e9e6be9b5f279c0decb019a6995345e607a36681f8a3"
+      },
+      "Q1": {
+        "x": "0x0dcb7e280b34f7caf24928ecb126a3bacbfeb4b70612d60bc7cd36467ad58cf33925e9c78635cdb7a024c0a3031846c1",
+        "y": "0x066bbc62980e8bf7664f2b84ee69f3ed2c1a49ef1f8c0d35d709ef1ed149f79cc93a65ccde5194d333710496f087d41d"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x0da5000e88db641d86b6aa2711b88b9bcf45fc95689dec569bd9ae6aac6b19e96620920f3fb806d0e72a111889983c11",
+        "0x0367d0cf2689a9e972f01d9d325a3e1bdcee67af7f39fb71030869457ea93d0039e58bb92cd058e45ced781def78ac79"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
new file mode 100644
index 0000000..95bcfc4
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
@@ -0,0 +1,77 @@
+{
+  "L": "0x40",
+  "Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa9,0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
+  "ciphersuite": "BLS12381G2_XMD:SHA-256_SSWU_NU_",
+  "curve": "BLS12381G2",
+  "dst": "BLS12381G2_XMD:SHA-256_SSWU_NU_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x2",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SSWU",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": false,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x170919c7845a9e623cef297e17484606a3eb2ae21ed8a21ff2b258861daefa3ac36955c0b374c6f4925868920d9c5f0b,0x04264ddf941f7c9ea5ad62027c72b194c6c3f62a92fcdb56ddc9de7990489af1f81c576e7f451c2cd416102253e040f0",
+        "y": "0x0ce03abe6c55ff0640b2b303440d88bd1a2b0cbfe3274b2802c1f58b1085e4dd8795c9c4d9c166d2f033e3c438e7f8a9,0x02d03d852629f70563e3a653ccc2e114439f551a2fd87c8136eb205b84e22c3f40507beccdcdc52c921b69a57968ec7c"
+      },
+      "Q": {
+        "x": "0x029b6b7335975135a3dd653cb5f865f8e1a6fd0e806f83f08078426d294efb72578dc6747b81747d03b5bce9fa9c6d4c,0x0e31914536a751dce017585d51c8c30127cf0abf8cce302faf8ea87de1393a37696df8d999f597b256e8e19a0865817a",
+        "y": "0x0a718016d326692f10e7508c6abc624e1b37da5fd0e4391acf5a19fac36b97a9ae13a79dd2bd0b28c1db20f9d27607e9,0x01df562b2fe9e7281b63a3c136a93773184ad924d9a0a0cd01b51150f175f9dfaa8d009f77df9812636a6de4a1b0a901"
+      },
+      "msg": "",
+      "u": [
+        "0x09367e3b485dda3925e82cc458e5009051281d3e442e94f9ef9feec44ee26375d6dc904dc1aa1f831f2aebd7b437ad12,0x094376a68cdc8f64bd981d59bf762f9b2960df6b135f6e09ceada2fe8d0000bbf04023492796c09f8ef04016a2e8365f"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x16d830a4e12fddfbdaf9a667f94f21e490879fd3ccc5ee6f039cd7c2174fb47ea8027af78779a978d2a921612844587f,0x019a3b47aa956b2b548cc04d9e109dec06642d6e28814f7e35f807e1ce609e2eae3a155af406c842529776d8192f562e",
+        "y": "0x15930174c11aa9b51a5cc3ebfa1ab6377e2318c4ea2df387bdb84b28687a02c86e6401b195bbcabb6e95d6ae43669e12,0x15adde069459ab2012b44c7703119185b96b7f04ad59b39f4f6aea35fdbb9c5c7d876b5f89afb55b67e7da96ad489dc3"
+      },
+      "Q": {
+        "x": "0x0f4c4441758b65035fab9adeb84dc4fcbf48e218085111cbc9e3294dde67ba93411d747d090fbc5aa144900df054ed32,0x0bcf59db7917f351264cbc8825c04e88885b01f8228ecef238e39cd9d7e42c7a6b4aeeabacbfe43ea36f1a148c3517ae",
+        "y": "0x128fae582c1c32dc1199981981c9f2ff42343523192b82d3c010c6b06e419087449196cf4a79caa921db2ab10fc316b5,0x0cff0768048fef20c10c19679deb85fff097befdb18a47a21c2ee57eeebf046d4d9f3bdaff6f9c7d6c80e0700018b86e"
+      },
+      "msg": "abc",
+      "u": [
+        "0x17ecd5d41a860b8886cb1210874b254f59945b089f774dcc14bc1aca7d4e3c975bce0d28510c442e9a932be5880ee5b1,0x0f105595e14847cc9a41fd70deb3240337678b266304100ec261add2585b991c7268bb1a325d2f871b327e8d04fd579b"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x1498937f0ed18c49ebbcdee579b58ce235f3ab03be5dc809e1df25e2e0b4eb4c672f4eaf26df91f3755d6367df55d5be,0x0910b2d55e210122fab2d2dae81e6a440fd22e925e422aaf16a8fd28477bacb12aa888de0faeea203e372a1c1cd9578c",
+        "y": "0x033b1948575e70fed67fb4f7bd86b5452dfc0afeb74ecf5cab4a6872e33f0eade9564d3d5b9fcb9d4c498afda0bc037d,0x102631eb4e684d759312d7eab78598f487c2c10ad3d3552cb43ce6f09a11eb46e551864863077906d3ecfd921f1fe541"
+      },
+      "Q": {
+        "x": "0x110a8c50fb6b2df0146678e80de24089e0d619c45c488e0c688f136963a4190b76647e9e122c18ab7b60a88ca1281e9c,0x17f35d34544ad51d51f2ccfbda142addc678bf5551bf301dce3c3b934ecb6aa78b3814729282755a62e4680083736628",
+        "y": "0x0bd9c15e07f2a2bd5dacae74861afa19ea15d393fe7552d3ba45ef1396d37ff7967bdf67d93ea68baf849710bcd88147,0x18e9a587c3b76f53a62e8919101b6f2b25803333a53b2c8596db44929bd59376f0a170c5debea9f8a378107c2ee1d51b"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x032ae17a23a76c94745a5460cd9f1191c0ebeec7adfc4df28b0833e536b7dbabf498dc076ff16cc11c6a6ef5105df693,0x1107a6f450c6c9580c720190b577f52c633cf5f3defb528ae873d3723bccc8fa433014e9120a1da31abc27c674f37ae4"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x18af6eedb7ed3be66c5a1d998ad4d9640f557b189558baec41f6e712ff2a39f795a35494b4b12343b7a1a2b17686d793,0x021f7faa0550e5a5d08338b4c0a5d30240dec7989fc7c77b6ffba9bfd5d64ce45af5aad8da8482bf0da91af4f29d371f",
+        "y": "0x0cc46cea229960bfbe25831162c27f96cf8bb14c017938e35b636987a306521915456fbd40633c6d5a30f61bce52a3f5,0x166c1abec65af593d291dbd05e5d7d28f1a9ffb73751d65f49d76084493f3da707ee2bbf54cf6de5bbaac2ffa0028c31"
+      },
+      "Q": {
+        "x": "0x0cf7bef1339955cf2139e61d3876d22bfcc89c44492b458b2d08a6bb4fa58755739a4b216bfd7604e203f4c31cfcdc00,0x0b80a0dee7817f29f8bf3374a3c033586d695391dc95280b2143d398817bbf9b76547c54b81fd2b8ad24a6afa1dd8524",
+        "y": "0x07bba42c7be028acf9111e51cfa6d98f2949f12635847e938b0f7980705da9abd1d77bbdaf86f90512e0139ac0e57a6b,0x0266340a1aaaf26dd5ec892f33dcb6a217dcde9b8d39dff5d277d93130ee3e33e43a2cb83665fee8648d610da2967fa5"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x0cda6b874f8c41862c078099aa76d607be51d913a2e3f997539a0993bda31892292818c74aa9be035f234df2576fe49a,0x0306162d24592a18fa8de2007d7b69d04bb7a71a5a7965d15bdcbaa4ddf9b599079fbdae9f67d55ab6dba044f9daf179"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
new file mode 100644
index 0000000..d108a06
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
@@ -0,0 +1,97 @@
+{
+  "L": "0x40",
+  "Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa9,0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
+  "ciphersuite": "BLS12381G2_XMD:SHA-256_SSWU_RO_",
+  "curve": "BLS12381G2",
+  "dst": "BLS12381G2_XMD:SHA-256_SSWU_RO_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x2",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SSWU",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": true,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x0d3b02ee071b12d1e79138c3900ca3da7b8021ac462fe6ed68080dc9a5f1c5de46b7fe171e8b3e4e7537e7746757aeca,0x0d4733459fead6a1f30e5f92df08ecfd0db9bcd0f3e2f2de0f00c8f45e081420aa4392eade61eade57d7a68474672fc1",
+        "y": "0x09cc6f7b3074f0c82510e65d8fc58f6033e03ba7358005a13e2bbd7f429b080f29731ef08c3780c9e3c746578b96b05c,0x0011531b8e08900a4f6f612e1e27432961419ce6a5ee3ec904a53588982d36ec4ea37be80b6cb7d986b38faec67dbe44"
+      },
+      "Q0": {
+        "x": "0x06828063f239b9607a9668fc0a59e5391c1bf24ba42ab5b480112666e3835c45f29401bea70d6f529d07e33bc017c1a4,0x04545e6b5318ec1c10f75791bc97142722370b851b7829987ada828de5a9b6353cb2c4f8540bf0821328c983e7eb887e",
+        "y": "0x06fc755b65fd277f7e1e4a6174dc11fedddf1baaefc07d04c3d120e15ca2ec61f489711c4af949bf6a5d26a885db05e3,0x068d9e1e428ed301e425e633603ea9ce5ff02df898aca1957fe5be1faf2ff42b64485cab41370a50c1e7e9742c0a2c6d"
+      },
+      "Q1": {
+        "x": "0x16af5b519e92362ce94c0ef76051510266c5ace22d2cf9c3c1ef20856e4669523df27c30e513444b436cef2082983814,0x03cb00c0a0370bd301cd45b0c08e6feea3adf07052e83a3f2ced57665d7484f5540db310f649387701731ff185b460da",
+        "y": "0x025310a94143c55175eb4929df2d8294b0268f3011850bdf46bdfb82749233e8dbb8070d623e3fb8397b079504d6c5aa,0x087d9d2c1cd911f8cd9844e60011a1d1c02d61a831bfd33b58c436d4305935abd3207c553c0145fd3ae1bf18c82011ce"
+      },
+      "msg": "",
+      "u": [
+        "0x1921dd796efec0b5f2ad9037e73b7470e6e7c85e6b7bf6e6827729442cd01aa55ac765ae451f497873400e90a814105c,0x0838662da53724510bb7d677b7caedbf3c4e19e55b42c9872c2af096272b26cb53cc522413cf4c54c1f7691bcdabfc4d",
+        "0x12bcf2aa2ec29a9dc0b77c942869af340047a27b57f549ecdd2e93fc5e63d0364fba13941725cbbac1d1e8c6e8605d5d,0x04e892eca8729b9a2b88b4b0b33e8c8d4ed52f7d0fc860e41f09de0a05c48f605a7a9d603b60db4f9ee49f888e4f3273"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0b6d276d0bfbddde617a9ab4c175b07c9c4aecad2cdd6cc9ca541b61334a69c58680ef5692bbad03d2f572838df32b66,0x139e9d78ff6d9d163f979d14a64c5e57f82f1ef7e42ece338b571a9e92c0666f0f6bf1a5fc21e2d32bcb6432eab7037c",
+        "y": "0x022f9ee5d596d06c5f2f735c3c5f743978f79fd57bf7d4291e221227f490d3f276066de9f9edc89c57e048ef4cf0ef72,0x14dd23517516a80d1d840e34f51dfb76946c7670fca0f36ad8ec9bde4ea82dfae119a21b076519bcc1c00152989a4d45"
+      },
+      "Q0": {
+        "x": "0x198d5f5fad8e1594ed98ee3d5f5b24b58e6cb8ae37372f6028e7beffa0e7a16b0958e13f92f322f513b85eacdd88d0c2,0x09288d195828e46e7c058b22115af5c1bde20cb7462a3f9d6488188fa937e2c0bee3aa188622312f87e12b48660a66d2",
+        "y": "0x16a0916a0c42492649701f0520c075d4cc66d74cd8fb4f9c6d2631cac1bb48e357bae0b97bb7f87f1b08539ac944f46a,0x0dd21353972061024a92db26e51cd97246c89a884ecad67a1ff8dd1da73a8397f54d41533ea2ac48ee4f5817cb09dd1a"
+      },
+      "Q1": {
+        "x": "0x17a29041f55a2b23b3a601b8d4f5a3e85b75cdc52650f26470884b8b367b20ef8f7e6f0ee8969b994f4132344a68f023,0x115d814e4f7973e7a960df53b494c2a0a1cd7a42ce6650bd7f46e55a2622dbf6528392ab9c8ff45d3fd97bd7b1dcfe67",
+        "y": "0x15749a8af1d35fcb409ffc3336670a8b47a117f81670394183c316d7bcd2a49b2253ced38b7d00763a2fe4afb51f0336,0x10624b1845ccd669e5edd403d68a603fb43e382c6570953dd9b9add472e422d1098eb45380fa870e14f6927252c4e667"
+      },
+      "msg": "abc",
+      "u": [
+        "0x0b7b2d371fc970671ddf7bc9ca4a70a1bd286af4487b497e460c0b44d405d73db576f8a08d59416cc976d4b1d0100775,0x0e86d0eb2d34c34fe8b2a1f2d999fa3dabcd504fdb4beb57e79756b08fd75b0a82660abc6026ecc4ccf327a522587b38",
+        "0x10376d048c060df1c5017a363144c482892fe2ce0061094327b8bbe49a713ce795726aa23b5402a271e9f1e7b9b6c7ba,0x0117f2ea63015e192d759f11a658a002e06112147d90f00d7429722456b9a1c63fef2dbe8df13168e3bd40af2fb959f3"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0ded52c30aace28d3e9cc5c1b47861ae4dd4e9cd17622e0f5b9d584af0397cd0e3bae80d4ee2d9d4b18c390f63154dfd,0x046701a03f361a0b8392ca387585f7ee6534dcec9450a035e39dc37387d5ca079b9557447f7d9cad0bd9671cb65ada02",
+        "y": "0x07a5cf56c5ea1d69ad59c0e80cc16c0c1b27f02840b396eb0ea320f70e87f705c6fa70cfeb9719b14badbb058bec5a4c,0x0674d1f7c9e8e84d8d7a07b40231257571c43160fd566e8d24459d17ca52f6068e1b63aaae5359d8869d4abc66de66b6"
+      },
+      "Q0": {
+        "x": "0x1729bbdeef9e902ab2e2bf6f90e3800231397ecc36b0b53d33ecb173bd682ef45a51e691d7c884965fb530cc85d6476d,0x07fd016eb7f3785362f75a0150d9e73d5ae13631c491075d73eab5c3b6ceb8391d909926d0c519fb83fbe889dae667eb",
+        "y": "0x15ee2194b053071cd1d40bacbb2650b5608d22d12ddeeae9fb11921e475ffea6d1c008fc390f231aa14589365c6937c7,0x15345785b7ba1db6cf6ec9f652dede47c86b6837b2c43f3a9e6984f95feecffb84bb5963df655068a0ad6b8d8a762fc6"
+      },
+      "Q1": {
+        "x": "0x18505ec8bfa125df7ea130e702eaa33a89961dd24ad06b3b3452da15f2394d0abec06aa3b4e9433c32fa8a7c6ef874ec,0x17c0d91f4c363a7ff183deeb4308fa5e8d61c0263b9d0ddcf304b2758e2b556695fe20636b4b7a2cd4909c145a81c884",
+        "y": "0x140b4d6603a96ef9de2a71a8ceec992aa72eb8c4f08d28de11310dcfd4d13dbb68734001417d0c1587b9082b593ab9ca,0x0ac81f1093f8be742b331c1c04e9cb0fb75ac72e87ae5da9fa395b043fb83fbdabe9e54331ec3a3a754f845939b118f6"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x0022182b07cb11d26cbdab43e0d696297a7dfe1b8dd2fa8ded11f858bf25ab000adb1ec319cbfa42d1107a3ec9528b33,0x01160e11ac26a46322b4867a0d66cbb1d8b8f78e88a3771b7a832d18c65d65297692e9faa1f65719c9ea621578003c37",
+        "0x185e096fa6e05479e1f3ae4148fd4de985c73e414f9a9202d3930d59a09d90d87e545522a91a0d24c6aa3e2363a48a41,0x08e234820b6cdd9229490f5c1e05e82b8fe7b1efab9dfaabe3ea4158f0f8da855daf1e1f5382246187d317ccee520a0e"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0161130ef4aa2f60f751e6b3dd48ac6e994d2d2613897c5dd26945bc72f33cc2977e1255c3f2dc0f1440d15a71c29b40,0x06db1818f132a61f5fe86d315faa8de4653049ac9cf7fbbc6d9987e5864d82a0156259d56192109bafddd5c30b9f01f5",
+        "y": "0x00f7fab0fedc978b974a38a1755244727b8a4eb31073653fa949594645ad181880d20ff0c91c4375b7e451fe803c9847,0x0964d550ee8752b6db99555ffcd442b4185267f31e3d57435ea73896a7a9fe952bd67f90fd75f4413212ac9640a7672c"
+      },
+      "Q0": {
+        "x": "0x08420c5b8d9f73ddac45b6ce050a8876e5014cb8783bc63a24eebab5e0ca75d547b51025ecfe75f4efadbc8d71c145c5,0x1915fda1fb71039148f5d346f1c36df1630a2f908881f29de32a5c2782eb6eb3c8cbe58f8c1bf8d348319347c6ec7635",
+        "y": "0x0e557684bd3e61db3f96df904c57ee1e8e45f5aecdda654ed741587082ad91860d311cae158569c217c56bbba3d3f25f,0x0acc1f70e15591005ab8bcdc7b1b19e3c16a6ee6c7a17ce83eaa2771971254be34726b266c076abab6b9b477ef790261"
+      },
+      "Q1": {
+        "x": "0x0cabb5826e6bf948e30cbb094b72685aa1d93ea49fdd9d54828b7ffb9df582e3d9405f33b9ae3ad3b6fd51863ff68c56,0x0604d687830b1dba2cd28c644709475c7a5427aa15278df2db06f59a48bcfb52061f77b6f5b637fc345e2bc64aa7e5ba",
+        "y": "0x11e8a23425631218f3249f1870a8b1a17d82f3224602e433ff04a5525e827582ac5898e81972e21618e41e5c5edc03f5,0x18f405a27aaf3803ef88b9f4d3e5d8eed901d980ebbefb71d5816ac2f1975c513965b7556ee44db2f74202ac178c72e4"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x0034f33d3e0b2bb1e396fa3716a02682ebfefe6b99e986c356c725f4bb787714f66fca8aac0581b538ae255aa69aa8b2,0x169a32a329b295e56423a29a2fa15b259f5e27f992c1391b3d333a4a050d8264cf146b1baa641e609ec748d74d6bfcd5",
+        "0x04028afd52de566f85dec8fd409112d34f09ed3b617b31bb23b0a96d76080d1dce671a910785cf63d4efcc20112f4a67,0x06d00ecaf61b0f972b521b223aeed36d1e4e1e6308b36dea9eeeb917619499d06615c275ea39cc4d7db697e4b697d40e"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json
new file mode 100644
index 0000000..25c4da1
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_NU_.json
@@ -0,0 +1,77 @@
+{
+  "L": "0x40",
+  "Z": "0x0,0x1",
+  "ciphersuite": "BLS12381G2_XMD:SHA-256_SVDW_NU_",
+  "curve": "BLS12381G2",
+  "dst": "BLS12381G2_XMD:SHA-256_SVDW_NU_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x2",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SVDW",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": false,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x164c24901348f035811139a2ad95042bc85bb4b4481309431cd98503c951e9cb8f29d3c4ad0abeb31a3da4062f4b9027,0x0cbca2904d96a263308df43e2767c4165f0357a5f0abf3419acab6fcf2200002b0b018c574f9253716844947f2752c94",
+        "y": "0x12b642193b7beb7989fe98c06482effb8740d9e744ff317e050f758bf449d6dedfded2eb1b1b3314b8699b9ea41f9fab,0x0219ec9ba08594f6e1582fb6a6ffb795a92551b32191f146296d29497bbafba7b3aae8ab2f012a5780f72cb0d0380a78"
+      },
+      "Q": {
+        "x": "0x033aa78402bfe8ee9117ac5501b55e2d1cc133a36ff2351b0176e7f44b009260f9f984be5aff18207a751fee8347250f,0x0f6512f645a015b2917bcef9407299bc46e57344ec24877b681b2c7b3c8171bbd0efe0074fe5eaa7fc74983494f90521",
+        "y": "0x02ed21e9ce037653ba12b3996f085847db2daf80e0033013a67667c6c53983ee76af4946da08c7186164ed50d225551f,0x05f95d63b6f2d45bc79824359754d23c795f98be958384829ea72b473525f58bef08bbf1c09ad153628f2d3ca9f44bdc"
+      },
+      "msg": "",
+      "u": [
+        "0x12e76b1034fcb8958d47b2ff763642841556e09d524a6e1ac146009e7b0a60e859567d52629ea27abc86996632970e99,0x005f69bf4eb6ef49bd04d4ca394c77b9ad359646e2ed36e013dc9491a64f2d1207734d4b91b53fd71a32d9e966d46dce"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x14662fda486645b71a497576120b99cd0c8fd72c52ade4b13ce4de57ca05acba0facf6bdc1a230539a96e97fbfdef9fd,0x0646f0fb608d82ba68075d6af75c61b762c5b47de2c620822e88acd296fcfecf125113392b582c48c9c4cec645e7e817",
+        "y": "0x097b57eed2bdcc07cf6518cc582af8604d284f51447d572f3c8b3c36c13f2f5ab3448d06a5e433a0a4753163469977b4,0x0d0e9f7c5c51da1a8b3211052b0562b0f19690027d2bf0df3f662ec9743b0b39c6b9be5b5bf6d224f7eff946b3c4a149"
+      },
+      "Q": {
+        "x": "0x065cca134296b189b4587c38490d674900cac3cb7a6e14ff96f415eae6ce4ee51696910182471d2542b86bc707a40230,0x088edc31bb54b91389c1c057cc5b69e62eb06f72c3184834ce60bcdf1ee885ad8e03005230bfb15c89109209d8c7671b",
+        "y": "0x17c0ef47c0c7960baec68b33d1ce4e9a54c2c770956cc43afe93d8b4bb07d5205fca8f785d55010111367b529a13a67b,0x121a0b8aa8dc49fd8da99eb93d9d736e01e65a0e72c9144b3ba87416fdf125a355f38b5d98e98c20744cbae1c344386f"
+      },
+      "msg": "abc",
+      "u": [
+        "0x108fd37b239357d783a30c9aeea3129316f236cfa8e279bbd921ea7c642ffbb69e4f731cbee57b2df7b17e9ec19c8c91,0x110587325ae905e360ad84368fe6aed5b8636bab77eaac3921c0468154c5d72ddd3ca2e9d57d393d55929344a34215c2"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0816a09925c45e39c3c04d3fdb331613f7308a0d5dec8e5496e4aec5e5a67458532f25dd07c6a793bc4be8be17a9fd56,0x0addce3d065de3f0e1b4ccad3e503b570412818094d1639329e7f4c6ad759bdcaff01f234ec3f1ebe71209a0773e4ca9",
+        "y": "0x1214b5de271352309fd0091b72eecdb6224f58af9c76ae47a2b21512fe194d5c08278bbfbbd3468ba4ef3abbdb0ffcf0,0x105bd74edfcf83e10663800fc4aca1f2de2e3197b6ad91c246c3c9828e24c44384747b95a8d156da7063df00546a6bad"
+      },
+      "Q": {
+        "x": "0x02da0a79d42b538d42ffc67176681d80ca8d0dc26974d3a30440ee92a362c13bbf737b414fbdf2fd8ce635a396e79ff0,0x0e91dd04cd2d2e112e503efec26f84183fca55101c36fa41226c72eab8e398a189c9cf2f4eda77f7c9a38a09a563b2f1",
+        "y": "0x0d3d3ca0d4ec0aff793a69c22e2abf333e8efc5a72b1d5179c19479e191daff895c95f32669672a1d3df38b1a184f8e8,0x069ab87711da7286d7c75f8cdd4b1e2719554d7866139e948851bc14d7e9124f6f969118bdd2ae3db9d8f997b59717e2"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x183b05a0844e652153f50ef0ea7e12bd9174707faf7fa3ac3d4408e8f06b0c8bae4aa322a71614f7d0380986632f2261,0x011b40d28c312f5f62289fe083c493c84ac5c2e66f8be782c1d50493d30bab14fc88966dfe4d51f53049d1e7b221e0e7"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0eb76ebb9399768c509108314b557659a38bc8187e7ab742adf8c672da98e2a7c9714e0e885070ccb7fbbabebf7a7bbb,0x04049cf80dd5f3a2734402d6ef6ce67f35189a4ace622dae7cf02b8b9662cd58f05dde5b6920fb93c6126c5895e9a3a5",
+        "y": "0x022d29c941c40481c8496f4b1df9fb708103c3170e99ffe41942e79ce8b0e35ecdce0e9281da60a685bafe07f9a635a7,0x023c57e63304ec8997a2b35ab78a2d060ffde49ff0235058ffdbf129946672e518bb31506c53dad9c8a30b751b6181bf"
+      },
+      "Q": {
+        "x": "0x1764c36ebfdb830ad6bed870087c5969cc95e16ca57d572047f8bb17ba961d2264c86726ef69ce6122a4459a6025461c,0x0d27880f35312ee235f2dc9208cc679679261e7f909072c5b71b14e369e20dc0c52459ace34c23aa6842e9b4663073e7",
+        "y": "0x07e98c5d7eadaa88299ee4ecccf848ca9492db725c45696596c50000cdf4852cee8d4a0e3ec0ca4d7b048ab0d92a4dee,0x00b35c992495fa745f8a3b765a2e7d7ee06e7c4cdd6d26be78b06231a98cf9fd6b585d24b6f7a659c45e1acd64082af5"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x09619086497c2a6933c45e2d330c560562d87d3b2f77f1d2da51525fb630a0ba2bd03ea9ebeb65778a65b29f1092a99d,0x0c3c45a61a7938b2a8a645c48c37a2e2e957b5ef5bbe3f661e8bdcb50e962a548862335c8503d73c1d28c5dc598ea29f"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json
new file mode 100644
index 0000000..6d1955a
--- /dev/null
+++ b/src/test_utils/hash_to_curve_vectors/BLS12381G2_XMD:SHA-256_SVDW_RO_.json
@@ -0,0 +1,97 @@
+{
+  "L": "0x40",
+  "Z": "0x0,0x1",
+  "ciphersuite": "BLS12381G2_XMD:SHA-256_SVDW_RO_",
+  "curve": "BLS12381G2",
+  "dst": "BLS12381G2_XMD:SHA-256_SVDW_RO_TESTGEN",
+  "expand": "XMD",
+  "field": {
+    "m": "0x2",
+    "p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
+  },
+  "hash": "sha256",
+  "k": "0x80",
+  "map": {
+    "name": "SVDW",
+    "sgn0": "sgn0_be"
+  },
+  "randomOracle": true,
+  "vectors": [
+    {
+      "P": {
+        "x": "0x0d2b7cb4e1b0f001de23bda54652814186434637442e61bd7ae665f78e3e8429a3b0abf727b6ffc1a7d5d7f5683c2517,0x0c6519468850b1b6b34c2ac7a67166d9c2b842df09105c8644d6d9be03880c56452e26dc82ee93d0db99946acc2675f4",
+        "y": "0x063e54fd52fde42a5d4a0739ce89956deb0aa4721237b581a79af5e6e847dc047e0b0a41502975e4c15bed99cdcdf0e8,0x0a04fe752f02d57217f2eca100582f9f60fe464aaec2e94624ff22a2522d562fc251e3e962b00f2a7cb544bad462487e"
+      },
+      "Q0": {
+        "x": "0x0440b705d56079686eace2e3d2fc6c26ed4349ddb574bbb13ef5c9c25c7a757b43a1243ecfc62f9cdd169d6360c21cad,0x061b98df942271495e7259a7010ed74c6bdf0f83fe225c7e60fa91b3699d32a99afa440f1ec380aacc8d703649631246",
+        "y": "0x12964591a5a374d4ed6f1306e1889d8ab5259e88928cf0900c6f4fc64ca2cd7d1cc992166f0515c7ce53dd52efe3ded2,0x1440790373a4369524884f589eff8c3ddeb82ad6032446072e75c3b09a300bfd9303a4794f6676ff2c73c796f9110557"
+      },
+      "Q1": {
+        "x": "0x01146e5fe16047ea58369ff4e6f53ada22c23260cb46b4ac1b24a7054691835c6f45e3a8218ed67c68a2c492b35a89b6,0x196e511b97c1f3802e37478224bb5ce12082cee5dd8e5630ff194d8537c7b30ace746d39c051cf3f6a836a861f0fca71",
+        "y": "0x16860436cd82bd22c166a92a38bae79036e357ce185ddcc481cef46edf398d377b5d85f38325be63270cf09c31329583,0x067e5d9c24201fa688bb9101b96fff337625778d0a6cb00495fa5aa8840bfed134b7b1bbd03979538b9b9bb5222b8a99"
+      },
+      "msg": "",
+      "u": [
+        "0x178a86886823673336e71d5cb95ef38381506d64e1251fe3f66c2fae08f5c1b5d1f01a0f09cbb29e8d776345c7601941,0x1200915fc80bdf41b2723f5051a642fee4f548ebdd6f90da9d34d8f477fd17f84921be12497be94b9061bcc9e977a958",
+        "0x0c2b3e012f715a94fc08bd3757ba7c979d848c9719264d2a6b07f03be4f236da0f5017ee8b92fa4fac3ab88c64cce667,0x099e1f36e1dada16e9277160ba74552efaa0c939a629c16fc8ebda75421af560a7ede7cd4423f00ffc1a12c07ab05fa0"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x0c2e41838e536c79576d6b34974204b591f0127354eac121b79029886a405615b273a6e1a78476d5d824d781b885af26,0x0dca051f4d106f072564729f74969ab9e557760e14c67c55ed38fb7e2f3f4b26af1ce227c963fd06a5c5c2745f082415",
+        "y": "0x12e8f2e906c3bac97820bd1cfad278d03321ba3d650a93cea80d4eea70271aff8f145dc6d7c32e4e945b4a213a551871,0x006d694e36dc47f3761ffc22d8a3cc66a9abe8851ad7dc42630a573f569692d46de02256b9bf98f1066be5ce38d97836"
+      },
+      "Q0": {
+        "x": "0x056eff68c169148bf3cf4a1e3dcd47d05f172f54f0f0906759b98ee48897090c16127085c2f9a16dec9ef0b73e1e98ae,0x0245cec38af51ed121d2d2f9ba21469335fb2eddc2c084386477c53d2999c65182d43285464927b5f63465599955b283",
+        "y": "0x1597b2110dc452b8083728a6ed061340b27cef4b2f96c7c4c74e3f090577407f2d8e72dd12e5a642eb0e0116d50d2900,0x040a92bbe9662fa154a7706b0b208bbc5083e2909de5e0feb243c4aeb4c2abd9201d970fd586fe9fc3f7b70deeca38c0"
+      },
+      "Q1": {
+        "x": "0x0a231b6efadfd4cd9243b2d5f8d9820943f6616bd34dc48b677783f0d298211d06b9f25e7ebaf5c3d53009c99b2371bb,0x0397e8e732c84a631df79723dc4ce49aeb1a08857cfd4272ca2b41d840862588fb75ac2555f127b3852942d5be5d8f32",
+        "y": "0x0576ad544c7dff5cfb6fe52857e89f1ad5ee0f703826471a18c6e8a28f538a87de1d02cca1a4aa7c1a90f0f2e1efe9fa,0x16eae9ad925c008d00832bad8830eaf05a2e693ddcf1fbb5d2702515fbbac163f0b12369e5466bcb30153616cf1a9021"
+      },
+      "msg": "abc",
+      "u": [
+        "0x0ecb785eea491ba407b29812dd080692d7f654fa9be80e1b930f90a2764157ec6522aec0ebeca35a440b524b1efe2ade,0x02f7de24231dbff773ec0ebdf9b1b7d84713ef0eff9ff8bc356163c34bc42e373abebb437568b9b8a7a9622f52f8f64d",
+        "0x09ed2dafb8141db58cf0e3038c1b5969742a15dfd3a8de689309ad49477a8c4d45f0b3029d216bef8197a615b89ee53d,0x0da9396afba6386ea945d8881d5d1b4e892ff506940d11f1c14e11008650abf458d6423185935f13e5304ac325996fed"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x103b9ec29f230ce504d06b3d9efbebd5ef5cda2bbdbd09e66ed9979a84dd4ccbb86bdfdb4e9673b75af702cd933b9938,0x17bb4ca24579cf87c16a554bc92497a67390971ad25d60a09befa7799b01676cdb30308ec0ddae9e4a5ca485200bc01f",
+        "y": "0x161a632c2847e27715f550ea93ac9897dab5d7ad483cbf180efefaa232f2bba706bff16b1f1c3e0b9da9ff39e160e42f,0x047f0b3db455080f13114bb2bbe37d40abdc9850bdc724f27a9ffa7bbd8307739fa1b803d69c30da64586c102842a3ae"
+      },
+      "Q0": {
+        "x": "0x0ad81631edcdf51ac0df8426a5d49192326f94244df93b8f990b9d23c2fd654b8f310a8bc0b136b649271a2ed598aeb7,0x106a7d7e84ca907f28cdf2e2ab98a49d53aa70f512afc0c764fdffe778ff3538992546decf48142a790700c6eee5db70",
+        "y": "0x0d9c4f07a23d596b3735a7e275a4a8ed3ac7b6849d83adf78b2743c6cb180232d5f180f7e32422c5e81039f9d48f9cb3,0x0b4ee768a0d0525872db9e4c511da298691aa7a3360a38cfb89691da7c9a314a8d461e8cc8935d08b6fed60ef149e9d9"
+      },
+      "Q1": {
+        "x": "0x1351d14d9737ba5ded8fee48ee1e45c823eaec7b58600a5af7c3543c0b450c565db1e1d37732182dbcbbc31ea33e3e1f,0x0c5ddcd88ebee0861a91dde563a6785752fbc5f4e079665ca2c0567dac8f203ed81f609e27e223938a55534ba8693657",
+        "y": "0x146bbafa353ed101672c21e98fb2e1aa6f438c918d963b4f05e80c36cac3769ad25b49720b8566e1ea1eecff77b010cb,0x02613eb3f365b783461d0edc9b3212495ae6f4de190150b94bbecaa6d631a6ccdf09335ac6f6aba57d70ce06d1a6d615"
+      },
+      "msg": "abcdef0123456789",
+      "u": [
+        "0x15788d0f014f083f4a6bad1e3ec01905fb81328fac060d575f9220ddb7fc495f6cca48e8f46c69153ef0152caa692bbe,0x0c50eaf8096785caee1e08ff3d9d46b8e4c1a1600406d4ab8c9c96c74c4d2b6b90fb5ddb0bdf7adabe0b176f75005df7",
+        "0x0274a965f4d5b3c5e1d35e426df580885eb9aeb4d0997afcb51d2aa908b7a7a5d2b608b4b054fbf77eb2ec8f6854d192,0x07be630ece05ab3536328fc3ccbbc7b8af99542ce0a7241bcf03723f9b45cbe16d3003dd28fcaaa4558f8f8f261a654a"
+      ]
+    },
+    {
+      "P": {
+        "x": "0x125730d27604ffa5f1be4e6357f2dacf59803b6b8ce43b81eb2e42010e0765ea149ed52e5d8ad0847617bb87a3cfdbbc,0x033008748ad6e6d95b68e86d8e786609c1011729606e45ab0b5691eceb3d4c72a80e36792f74e907309f3550bd7b9a6e",
+        "y": "0x180de292e84a7ecc8361490a3f0d8bcf834e12d68529e437df782111f01c8c73c53c9a502eac6aa9dffceae1b7df55b8,0x07225c86be63f0b3eb8acf88ff4133fa9bb8c0b1d50c997ad33f57dcb9cd09cc4676da6f37fd7f4bfaa06bfca9bdb772"
+      },
+      "Q0": {
+        "x": "0x17dab789594c9400a35e44e124a04eb15a273b7ff3385aeb5767cecf3a5d6ce03bee39e9b3d9eedef8dfc1c064465f04,0x0d2b1ae115243ae13e9018e065bfb4215671e2ea86792e78858f012264b642591f4839972f58c00309cbf54a6f2809c5",
+        "y": "0x19d7a9d430474d353c6ccf18db52263cd2fa4685e0194b3ec55672dfea3645c08feb3643dc8a4e995406e3b1108e7275,0x03ac4fde5674418babfbbc6bad412d789f018ad49135ef84e6cbb1b63eb9fb61d7d12caa9ccb4e710d1badff2fe47515"
+      },
+      "Q1": {
+        "x": "0x08d580532d837ce1cd78df4e3668b123eafd519b93e359ba64e0281740742649b76c960e5390e1fd4ea4abcc84afcaca,0x12a30881e5bca0c8f3f8159b1490e215a380eb70c71f14570e886f6ba2de770e26ce6634e00c9a98e14665f61820209f",
+        "y": "0x13192225f9eea2cb2c342e39654a115e5f4b002943cea6067d429e685317be5034edcfe71897728402fc28abb725eca9,0x01c62e5d5325ec325e75e7e0a60a86d489ee543b0709ccd76807cafd1d8041486c185a89f6ca72b96cb7eb193a3d5ef5"
+      },
+      "msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa [...]
+      "u": [
+        "0x00a73d9f99c991b8a95d533111700cb468bb9dfc7ecfa8879d278efd4f62907dc735a137ed26eac6fbd4730d16c525e7,0x011de2ac3ddd0fce82f81ff1506a4da615a545f5f1a38d76493489d043dec0298423741a607fd45b57526b2dbf7c0512",
+        "0x054e5964345b7e40826826b6c0773ae205596eed3f430649873afb7ff36a0a4583d947b5e1dcaaf64b62067814724329,0x0c022493d6de52b27b95ba1097b803e2834ce69555e25bda8df9a60bbd7cb8ef2d11eea6ea85856626a1f35c2ccccb95"
+      ]
+    }
+  ]
+}
diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs
index 4c85c50..3ed8643 100644
--- a/src/test_utils/mod.rs
+++ b/src/test_utils/mod.rs
@@ -1,5 +1,13 @@
+use std::fs::File;
+use std::io::BufReader;
+use std::path::PathBuf;
+
 use crate::rand::RAND;
 
+mod test_vector_structs;
+
+pub use self::test_vector_structs::*;
+
 pub fn printbinary(array: &[u8]) {
     for i in 0..array.len() {
         print!("{:02X}", array[i])
@@ -19,3 +27,15 @@ pub fn create_rng() -> RAND {
     rng.seed(100, &raw);
     rng
 }
+
+// Reads the json test files
+pub fn json_reader(file_name: &str) -> BufReader<File> {
+    let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
+    file_path_buf.push("src/test_utils/hash_to_curve_vectors/");
+    let mut file_name = String::from(file_name);
+    file_name.push_str(".json");
+    file_path_buf.push(file_name);
+
+    let file = File::open(file_path_buf).unwrap();
+    BufReader::new(file)
+}
diff --git a/src/test_utils/test_vector_structs.rs b/src/test_utils/test_vector_structs.rs
new file mode 100644
index 0000000..5ea34fd
--- /dev/null
+++ b/src/test_utils/test_vector_structs.rs
@@ -0,0 +1,44 @@
+#[derive(Deserialize)]
+pub struct Field {
+    pub m: String,
+    pub p: String,
+}
+
+#[derive(Deserialize)]
+pub struct Map {
+    pub name: String,
+    pub sgn0: String,
+}
+
+#[derive(Deserialize)]
+pub struct Point {
+    pub x: String,
+    pub y: String,
+}
+
+#[derive(Deserialize)]
+#[allow(non_snake_case)]
+pub struct Bls12381Ro {
+    pub L: String,
+    pub Z: String,
+    pub ciphersuite: String,
+    pub curve: String,
+    pub dst: String,
+    pub expand: String,
+    pub field: Field,
+    pub hash: String,
+    pub k: String,
+    pub map: Map,
+    pub randomOracle: bool,
+    pub vectors: Vec<Bls12381RoVectors>,
+}
+
+#[derive(Deserialize)]
+#[allow(non_snake_case)]
+pub struct Bls12381RoVectors {
+    pub P: Point,
+    pub Q0: Point,
+    pub Q1: Point,
+    pub msg: String,
+    pub u: Vec<String>,
+}


[incubator-milagro-crypto-rust] 01/44: initial commit

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 3948f75f9adb2ff91578af3171b5909ae99a0e85
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Wed Jun 26 10:01:25 2019 +0100

    initial commit
---
 BenchtestALL.rs               |  957 ++++++++++++++++++++++++
 Cargo.lock                    |    6 +
 Cargo.toml                    |   46 ++
 LICENSE                       |  202 ++++++
 TestALL.rs                    | 1459 +++++++++++++++++++++++++++++++++++++
 TestBLS.rs                    |  190 +++++
 TestNHS.rs                    |   77 ++
 deploy.token                  |    1 +
 readme.md                     |   83 +++
 src/aes.rs                    |  772 ++++++++++++++++++++
 src/arch/arch32.rs            |   22 +
 src/arch/arch64.rs            |   22 +
 src/big.rs                    | 1070 +++++++++++++++++++++++++++
 src/bls.rs                    |   96 +++
 src/bls192.rs                 |   96 +++
 src/bls256.rs                 |   96 +++
 src/dbig.rs                   |  301 ++++++++
 src/ecdh.rs                   |  744 +++++++++++++++++++
 src/ecp.rs                    | 1261 ++++++++++++++++++++++++++++++++
 src/ecp2.rs                   |  784 ++++++++++++++++++++
 src/ecp4.rs                   |  866 ++++++++++++++++++++++
 src/ecp8.rs                   | 1155 +++++++++++++++++++++++++++++
 src/ff.rs                     | 1058 +++++++++++++++++++++++++++
 src/fp.rs                     |  717 ++++++++++++++++++
 src/fp12.rs                   | 1109 ++++++++++++++++++++++++++++
 src/fp16.rs                   |  602 +++++++++++++++
 src/fp2.rs                    |  407 +++++++++++
 src/fp24.rs                   | 1268 ++++++++++++++++++++++++++++++++
 src/fp4.rs                    |  697 ++++++++++++++++++
 src/fp48.rs                   | 1610 +++++++++++++++++++++++++++++++++++++++++
 src/fp8.rs                    |  701 ++++++++++++++++++
 src/gcm.rs                    |  481 ++++++++++++
 src/hash256.rs                |  216 ++++++
 src/hash384.rs                |  288 ++++++++
 src/hash512.rs                |  288 ++++++++
 src/lib.rs                    |  561 ++++++++++++++
 src/mpin.rs                   |  945 ++++++++++++++++++++++++
 src/mpin192.rs                |  960 ++++++++++++++++++++++++
 src/mpin256.rs                |  993 +++++++++++++++++++++++++
 src/nhs.rs                    |  705 ++++++++++++++++++
 src/pair.rs                   |  755 +++++++++++++++++++
 src/pair192.rs                |  606 ++++++++++++++++
 src/pair256.rs                |  722 ++++++++++++++++++
 src/rand.rs                   |  180 +++++
 src/roms/rom_anssi_32.rs      |   73 ++
 src/roms/rom_anssi_64.rs      |   91 +++
 src/roms/rom_bls24_32.rs      |  240 ++++++
 src/roms/rom_bls24_64.rs      |  288 ++++++++
 src/roms/rom_bls381_32.rs     |  209 ++++++
 src/roms/rom_bls381_64.rs     |  211 ++++++
 src/roms/rom_bls383_32.rs     |  207 ++++++
 src/roms/rom_bls383_64.rs     |  218 ++++++
 src/roms/rom_bls461_32.rs     |  209 ++++++
 src/roms/rom_bls461_64.rs     |  232 ++++++
 src/roms/rom_bls48_32.rs      |  309 ++++++++
 src/roms/rom_bls48_64.rs      |  401 ++++++++++
 src/roms/rom_bn254CX_32.rs    |  183 +++++
 src/roms/rom_bn254CX_64.rs    |  242 +++++++
 src/roms/rom_bn254_32.rs      |  171 +++++
 src/roms/rom_bn254_64.rs      |  208 ++++++
 src/roms/rom_brainpool_32.rs  |   74 ++
 src/roms/rom_brainpool_64.rs  |   92 +++
 src/roms/rom_c25519_32.rs     |   59 ++
 src/roms/rom_c25519_64.rs     |   61 ++
 src/roms/rom_c41417_32.rs     |   71 ++
 src/roms/rom_c41417_64.rs     |   78 ++
 src/roms/rom_ed25519_32.rs    |   68 ++
 src/roms/rom_ed25519_64.rs    |   79 ++
 src/roms/rom_fp256bn_32.rs    |  180 +++++
 src/roms/rom_fp256bn_64.rs    |  233 ++++++
 src/roms/rom_fp512bn_32.rs    |  249 +++++++
 src/roms/rom_fp512bn_64.rs    |  482 ++++++++++++
 src/roms/rom_goldilocks_32.rs |   73 ++
 src/roms/rom_goldilocks_64.rs |   99 +++
 src/roms/rom_hifive_32.rs     |   68 ++
 src/roms/rom_hifive_64.rs     |   77 ++
 src/roms/rom_nist256_32.rs    |   74 ++
 src/roms/rom_nist256_64.rs    |   86 +++
 src/roms/rom_nist384_32.rs    |   76 ++
 src/roms/rom_nist384_64.rs    |  104 +++
 src/roms/rom_nist521_32.rs    |   79 ++
 src/roms/rom_nist521_64.rs    |  104 +++
 src/roms/rom_nums256e_32.rs   |   71 ++
 src/roms/rom_nums256e_64.rs   |   80 ++
 src/roms/rom_nums256w_32.rs   |   66 ++
 src/roms/rom_nums256w_64.rs   |   78 ++
 src/roms/rom_nums384e_32.rs   |   74 ++
 src/roms/rom_nums384e_64.rs   |   95 +++
 src/roms/rom_nums384w_32.rs   |   74 ++
 src/roms/rom_nums384w_64.rs   |   94 +++
 src/roms/rom_nums512e_32.rs   |   79 ++
 src/roms/rom_nums512e_64.rs   |  104 +++
 src/roms/rom_nums512w_32.rs   |   77 ++
 src/roms/rom_nums512w_64.rs   |   94 +++
 src/roms/rom_rsa2048_32.rs    |    3 +
 src/roms/rom_rsa2048_64.rs    |    3 +
 src/roms/rom_rsa3072_32.rs    |    3 +
 src/roms/rom_rsa3072_64.rs    |    3 +
 src/roms/rom_rsa4096_32.rs    |    3 +
 src/roms/rom_rsa4096_64.rs    |    3 +
 src/roms/rom_secp256k1_32.rs  |   70 ++
 src/roms/rom_secp256k1_64.rs  |   81 +++
 src/rsa.rs                    |  469 ++++++++++++
 src/sha3.rs                   |  270 +++++++
 src/types.rs                  |   45 ++
 105 files changed, 34172 insertions(+)

diff --git a/BenchtestALL.rs b/BenchtestALL.rs
new file mode 100644
index 0000000..55961be
--- /dev/null
+++ b/BenchtestALL.rs
@@ -0,0 +1,957 @@
+/*
+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.
+*/
+#![allow(non_snake_case)]
+extern crate amcl;
+
+//use std::str;
+//use std::io;
+
+use amcl::arch;
+use amcl::rand::RAND;
+use amcl::types::{CurveType, CurvePairingType, ModType};
+
+use std::time::Instant;
+
+const MIN_ITERS: isize = 10;
+const MIN_TIME: isize = 10;
+
+fn ed25519(mut rng: &mut RAND) {
+	//use amcl::ed25519;
+	use amcl::ed25519::big;
+	use amcl::ed25519::ecp;
+	use amcl::ed25519::fp;
+	use amcl::ed25519::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing ed25519 ECC");
+
+	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+		println!("Weierstrass parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::EDWARDS {
+		println!("Edwards parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+		println!("Montgomery parameterization");
+	}
+
+	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+		println!("Pseudo-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+		println!("Montgomery friendly Modulus");
+	}
+	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+		println!("Generalised-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::NOT_SPECIAL {
+		println!("Not special Modulus");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let P = G.mul(&mut r);
+	if !P.is_infinity() {
+		println!("FAILURE - rG!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = G.mul(&mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("EC  mul - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn nist256(mut rng: &mut RAND) {
+	//use amcl::nist256;
+	use amcl::nist256::big;
+	use amcl::nist256::ecp;
+	use amcl::nist256::fp;
+	use amcl::nist256::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing nist256 ECC");
+
+	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+		println!("Weierstrass parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::EDWARDS {
+		println!("Edwards parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+		println!("Montgomery parameterization");
+	}
+
+	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+		println!("Pseudo-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+		println!("Montgomery friendly Modulus");
+	}
+	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+		println!("Generalised-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::NOT_SPECIAL {
+		println!("Not special Modulus");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let P = G.mul(&mut r);
+	if !P.is_infinity() {
+		println!("FAILURE - rG!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = G.mul(&mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("EC  mul - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn goldilocks(mut rng: &mut RAND) {
+	//use amcl::goldilocks;
+	use amcl::goldilocks::big;
+	use amcl::goldilocks::ecp;
+	use amcl::goldilocks::fp;
+	use amcl::goldilocks::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing goldilocks ECC");
+
+	if ecp::CURVETYPE == CurveType::WEIERSTRASS {
+		println!("Weierstrass parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::EDWARDS {
+		println!("Edwards parameterization");
+	}
+	if ecp::CURVETYPE == CurveType::MONTGOMERY {
+		println!("Montgomery parameterization");
+	}
+
+	if fp::MODTYPE == ModType::PSEUDO_MERSENNE {
+		println!("Pseudo-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::MONTGOMERY_FRIENDLY {
+		println!("Montgomery friendly Modulus");
+	}
+	if fp::MODTYPE == ModType::GENERALISED_MERSENNE {
+		println!("Generalised-Mersenne Modulus");
+	}
+	if fp::MODTYPE == ModType::NOT_SPECIAL {
+		println!("Not special Modulus");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let P = G.mul(&mut r);
+	if !P.is_infinity() {
+		println!("FAILURE - rG!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = G.mul(&mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("EC  mul - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn bn254(mut rng: &mut RAND) {
+	//use amcl::bn254;
+	use amcl::bn254::big;
+	use amcl::bn254::ecp;
+	use amcl::bn254::ecp2;
+	use amcl::bn254::fp;
+	use amcl::bn254::pair;
+	use amcl::bn254::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing BN254 Pairings");
+
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+		println!("BN Pairing-Friendly Curve");
+	}
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+		println!("BLS Pairing-Friendly Curve");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let mut G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let mut P = pair::g1mul(&mut G, &mut r);
+
+	if !P.is_infinity() {
+		println!("FAILURE - rP!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		P = pair::g1mul(&mut G, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G1  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut Q = ecp2::ECP2::generator();
+	let mut W = pair::g2mul(&mut Q, &mut r);
+
+	if !W.is_infinity() {
+		println!("FAILURE - rQ!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		W = pair::g2mul(&mut Q, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G2  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut w = pair::ate(&mut Q, &mut P);
+	w = pair::fexp(&w);
+
+	let mut g = pair::gtpow(&mut w, &mut r);
+
+	if !g.isunity() {
+		println!("FAILURE - g^r!=1");
+		return;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair::gtpow(&mut w, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = w.compow(&s, &mut r);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow (compressed) - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		w = pair::ate(&mut Q, &mut P);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing ATE          - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair::fexp(&w);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing FEXP         - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	P.copy(&G);
+	Q.copy(&W);
+
+	P = pair::g1mul(&mut P, &mut s);
+	g = pair::ate(&mut Q, &mut P);
+	g = pair::fexp(&g);
+
+	P.copy(&G);
+	Q = pair::g2mul(&mut Q, &mut s);
+	w = pair::ate(&mut Q, &mut P);
+	w = pair::fexp(&w);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,sP) ");
+		fail = true;
+	}
+
+	Q.copy(&W);
+	g = pair::ate(&mut Q, &mut P);
+	g = pair::fexp(&g);
+	g = pair::gtpow(&mut g, &mut s);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,P)^s ");
+		fail = true;
+	}
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn bls383(mut rng: &mut RAND) {
+	//use amcl::bls383;
+	use amcl::bls383::big;
+	use amcl::bls383::ecp;
+	use amcl::bls383::ecp2;
+	use amcl::bls383::fp;
+	use amcl::bls383::pair;
+	use amcl::bls383::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing BLS383 Pairings");
+
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+		println!("BN Pairing-Friendly Curve");
+	}
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+		println!("BLS Pairing-Friendly Curve");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let mut G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let mut P = pair::g1mul(&mut G, &mut r);
+
+	if !P.is_infinity() {
+		println!("FAILURE - rP!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		P = pair::g1mul(&mut G, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G1  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut Q = ecp2::ECP2::generator();
+	let mut W = pair::g2mul(&mut Q, &mut r);
+
+	if !W.is_infinity() {
+		println!("FAILURE - rQ!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		W = pair::g2mul(&mut Q, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G2  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut w = pair::ate(&mut Q, &mut P);
+	w = pair::fexp(&w);
+
+	let mut g = pair::gtpow(&mut w, &mut r);
+
+	if !g.isunity() {
+		println!("FAILURE - g^r!=1");
+		return;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair::gtpow(&mut w, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = w.compow(&s, &mut r);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow (compressed) - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		w = pair::ate(&mut Q, &mut P);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing ATE          - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair::fexp(&w);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing FEXP         - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	P.copy(&G);
+	Q.copy(&W);
+
+	P = pair::g1mul(&mut P, &mut s);
+	g = pair::ate(&mut Q, &mut P);
+	g = pair::fexp(&g);
+
+	P.copy(&G);
+	Q = pair::g2mul(&mut Q, &mut s);
+	w = pair::ate(&mut Q, &mut P);
+	w = pair::fexp(&w);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,sP) ");
+		fail = true;
+	}
+
+	Q.copy(&W);
+	g = pair::ate(&mut Q, &mut P);
+	g = pair::fexp(&g);
+	g = pair::gtpow(&mut g, &mut s);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,P)^s ");
+		fail = true;
+	}
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn bls24(mut rng: &mut RAND) {
+	//use amcl::bls24;
+	use amcl::bls24::big;
+	use amcl::bls24::ecp;
+	use amcl::bls24::ecp4;
+	use amcl::bls24::fp;
+	use amcl::bls24::pair192;
+	use amcl::bls24::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing BLS24 Pairings");
+
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+		println!("BN Pairing-Friendly Curve");
+	}
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+		println!("BLS24 Pairing-Friendly Curve");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let mut G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let mut P = pair192::g1mul(&mut G, &mut r);
+
+	if !P.is_infinity() {
+		println!("FAILURE - rP!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		P = pair192::g1mul(&mut G, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G1  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut Q = ecp4::ECP4::generator();
+	let mut W = pair192::g2mul(&mut Q, &mut r);
+
+	if !W.is_infinity() {
+		println!("FAILURE - rQ!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		W = pair192::g2mul(&mut Q, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G2  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut w = pair192::ate(&mut Q, &mut P);
+	w = pair192::fexp(&w);
+
+	let mut g = pair192::gtpow(&mut w, &mut r);
+
+	if !g.isunity() {
+		println!("FAILURE - g^r!=1");
+		return;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair192::gtpow(&mut w, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = w.compow(&s, &mut r);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow (compressed) - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		w = pair192::ate(&mut Q, &mut P);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing ATE          - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair192::fexp(&w);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing FEXP         - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	P.copy(&G);
+	Q.copy(&W);
+
+	P = pair192::g1mul(&mut P, &mut s);
+	g = pair192::ate(&mut Q, &mut P);
+	g = pair192::fexp(&g);
+
+	P.copy(&G);
+	Q = pair192::g2mul(&mut Q, &mut s);
+	w = pair192::ate(&mut Q, &mut P);
+	w = pair192::fexp(&w);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,sP) ");
+		fail = true;
+	}
+
+	Q.copy(&W);
+	g = pair192::ate(&mut Q, &mut P);
+	g = pair192::fexp(&g);
+	g = pair192::gtpow(&mut g, &mut s);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,P)^s ");
+		fail = true;
+	}
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn bls48(mut rng: &mut RAND) {
+	//use amcl::bls48;
+	use amcl::bls48::big;
+	use amcl::bls48::ecp;
+	use amcl::bls48::ecp8;
+	use amcl::bls48::fp;
+	use amcl::bls48::pair256;
+	use amcl::bls48::rom;
+	let mut fail = false;
+	println!("\nTesting/Timing BLS48 Pairings");
+
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+		println!("BN Pairing-Friendly Curve");
+	}
+	if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+		println!("BLS48 Pairing-Friendly Curve");
+	}
+
+	println!("Modulus size {:} bits", fp::MODBITS);
+	println!("{:} bit build", arch::CHUNK);
+
+	let mut G = ecp::ECP::generator();
+
+	let mut r = big::BIG::new_ints(&rom::CURVE_ORDER);
+	let mut s = big::BIG::randomnum(&r, &mut rng);
+
+	let mut P = pair256::g1mul(&mut G, &mut r);
+
+	if !P.is_infinity() {
+		println!("FAILURE - rP!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		P = pair256::g1mul(&mut G, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G1  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut Q = ecp8::ECP8::generator();
+	let mut W = pair256::g2mul(&mut Q, &mut r);
+
+	if !W.is_infinity() {
+		println!("FAILURE - rQ!=O");
+		fail = true;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		W = pair256::g2mul(&mut Q, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("G2  mul              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut w = pair256::ate(&mut Q, &mut P);
+	w = pair256::fexp(&w);
+
+	let mut g = pair256::gtpow(&mut w, &mut r);
+
+	if !g.isunity() {
+		println!("FAILURE - g^r!=1");
+		return;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair256::gtpow(&mut w, &mut s);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow              - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = w.compow(&s, &mut r);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("GT  pow (compressed) - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		w = pair256::ate(&mut Q, &mut P);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing ATE          - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		let _ = pair256::fexp(&w);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("PAIRing FEXP         - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	P.copy(&G);
+	Q.copy(&W);
+
+	P = pair256::g1mul(&mut P, &mut s);
+	g = pair256::ate(&mut Q, &mut P);
+	g = pair256::fexp(&g);
+
+	P.copy(&G);
+	Q = pair256::g2mul(&mut Q, &mut s);
+	w = pair256::ate(&mut Q, &mut P);
+	w = pair256::fexp(&w);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,sP) ");
+		fail = true;
+	}
+
+	Q.copy(&W);
+	g = pair256::ate(&mut Q, &mut P);
+	g = pair256::fexp(&g);
+	g = pair256::gtpow(&mut g, &mut s);
+
+	if !g.equals(&mut w) {
+		println!("FAILURE - e(sQ,p)!=e(Q,P)^s ");
+		fail = true;
+	}
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+fn rsa2048(mut rng: &mut RAND) {
+	use amcl::rsa2048::ff;
+	use amcl::rsa2048::rsa;
+	let mut pbc = rsa::new_public_key(ff::FFLEN);
+	let mut prv = rsa::new_private_key(ff::HFLEN);
+	let mut c: [u8; rsa::RFS] = [0; rsa::RFS];
+	let mut m: [u8; rsa::RFS] = [0; rsa::RFS];
+	let mut p: [u8; rsa::RFS] = [0; rsa::RFS];
+
+	let mut fail = false;
+	println!("\nTesting/Timing 2048-bit RSA");
+	println!("Generating 2048 -bit RSA public/private key pair");
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("RSA gen - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	for i in 0..rsa::RFS {
+		m[i] = (i % 128) as u8;
+	}
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		rsa::encrypt(&pbc, &m, &mut c);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("RSA enc - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let start = Instant::now();
+	let mut iterations = 0;
+	let mut dur = 0 as u64;
+	while dur < (MIN_TIME as u64) * 1000 || iterations < MIN_ITERS {
+		rsa::decrypt(&prv, &c, &mut p);
+		iterations += 1;
+		let elapsed = start.elapsed();
+		dur = (elapsed.as_secs() * 1_000) + (elapsed.subsec_nanos() / 1_000_000) as u64;
+	}
+	let duration = (dur as f64) / (iterations as f64);
+	print!("RSA dec - {:} iterations  ", iterations);
+	println!(" {:0.2} ms per iteration", duration);
+
+	let mut cmp = true;
+	for i in 0..rsa::RFS {
+		if p[i] != m[i] {
+			cmp = false;
+		}
+	}
+
+	if !cmp {
+		println!("FAILURE - RSA decryption");
+		fail = true;
+	}
+
+	if !fail {
+		println!("All tests pass");
+	}
+}
+
+#[allow(non_snake_case)]
+//#[test]
+fn main() {
+	let mut raw: [u8; 100] = [0; 100];
+
+	let mut rng = RAND::new();
+	rng.clean();
+	for i in 0..100 {
+		raw[i] = i as u8
+	}
+
+	rng.seed(100, &raw);
+
+	ed25519(&mut rng);
+	nist256(&mut rng);
+	goldilocks(&mut rng);
+	bn254(&mut rng);
+	bls383(&mut rng);
+	bls24(&mut rng);
+	bls48(&mut rng);
+	rsa2048(&mut rng);
+}
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..ccba62a
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,6 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "amcl"
+version = "0.2.0"
+
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..b3a8fa8
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,46 @@
+[package]
+name = "amcl"
+version = "0.2.0"
+authors = ["Nikita Khateev <ni...@dsr-corporation.com>"]
+
+description = "The Apache Milagro Cryptographic Library (version 3)"
+license = "Apache-2.0"
+repository = "https://github.com/milagro-crypto/amcl"
+
+[dependencies]
+
+[lib]
+name = "amcl"
+path = "src/lib.rs"
+
+[features]
+default = ["bn254"]
+bn254 = []
+bn254cx = []
+ansii = []
+bls24 = []
+bls48 = []
+bls381 = []
+bls383 = []
+bls461 = []
+brainpool = []
+c25519 = []
+c41417 = []
+ed25519 = []
+fp256Bn = []
+fp512BN = []
+goldilocks = []
+hifive = []
+nist256 = []
+nist384 = []
+nist521 = []
+nums256e = []
+nums256w = []
+nums384e = []
+nums384w = []
+nums512e = []
+nums512w = []
+secp256k1 = []
+rsa2048 = []
+rsa3072 = []
+rsa4096 = []
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
\ No newline at end of file
diff --git a/TestALL.rs b/TestALL.rs
new file mode 100644
index 0000000..2dbf276
--- /dev/null
+++ b/TestALL.rs
@@ -0,0 +1,1459 @@
+/*
+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.
+*/
+
+extern crate amcl;
+
+use std::io;
+use std::str;
+
+use amcl::rand::RAND;
+use amcl::types::CurveType;
+
+pub fn printbinary(array: &[u8]) {
+    for i in 0..array.len() {
+        print!("{:02X}", array[i])
+    }
+    println!("")
+}
+
+fn ecdh_ed25519(mut rng: &mut RAND) {
+    //use amcl::ed25519;
+    use amcl::ed25519::ecdh;
+    use amcl::ed25519::ecp;
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+fn ecdh_nist256(mut rng: &mut RAND) {
+    //use amcl::nist256;
+    use amcl::nist256::ecdh;
+    use amcl::nist256::ecp;
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+fn ecdh_goldilocks(mut rng: &mut RAND) {
+    //use amcl::goldilocks;
+    use amcl::goldilocks::ecdh;
+    use amcl::goldilocks::ecp;
+
+    let pw = "M0ng00se";
+    let pp: &[u8] = b"M0ng00se";
+    const EFS: usize = ecdh::EFS;
+    const EGS: usize = ecdh::EGS;
+    const EAS: usize = ecp::AESKEY;
+
+    let sha = ecp::HASH_TYPE;
+    let mut salt: [u8; 8] = [0; 8];
+    let mut s1: [u8; EGS] = [0; EGS];
+    let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut z0: [u8; EFS] = [0; EFS];
+    let mut z1: [u8; EFS] = [0; EFS];
+    let mut key: [u8; EAS] = [0; EAS];
+    let mut cs: [u8; EGS] = [0; EGS];
+    let mut ds: [u8; EGS] = [0; EGS];
+    let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap.
+    let mut p1: [u8; 3] = [0; 3];
+    let mut p2: [u8; 4] = [0; 4];
+    let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1];
+    let mut t: [u8; 12] = [0; 12];
+
+    for i in 0..8 {
+        salt[i] = (i + 1) as u8
+    } // set Salt
+
+    println!("\nTesting ECDH/ECDSA/ECIES");
+    println!("Alice's Passphrase= {}", pw);
+
+    let mut s0: [u8; EFS] = [0; EGS];
+    ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0);
+
+    print!("Alice's private key= 0x");
+    printbinary(&s0);
+
+    /* Generate Key pair S/W */
+    ecdh::key_pair_generate(None, &mut s0, &mut w0);
+
+    print!("Alice's public key= 0x");
+    printbinary(&w0);
+
+    let mut res = ecdh::public_key_validate(&w0);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+
+    /* Random private key for other party */
+    ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1);
+
+    print!("Servers private key= 0x");
+    printbinary(&s1);
+
+    print!("Servers public key= 0x");
+    printbinary(&w1);
+
+    res = ecdh::public_key_validate(&w1);
+    if res != 0 {
+        println!("ECP Public Key is invalid!");
+        return;
+    }
+    /* Calculate common key using DH - IEEE 1363 method */
+
+    ecdh::ecpsvdp_dh(&s0, &w1, &mut z0);
+    ecdh::ecpsvdp_dh(&s1, &w0, &mut z1);
+
+    let mut same = true;
+    for i in 0..EFS {
+        if z0[i] != z1[i] {
+            same = false
+        }
+    }
+
+    if !same {
+        println!("*** ECPSVDP-DH Failed");
+        return;
+    }
+
+    ecdh::kdf2(sha, &z0, None, EAS, &mut key);
+
+    print!("Alice's DH Key=  0x");
+    printbinary(&key);
+    print!("Servers DH Key=  0x");
+    printbinary(&key);
+
+    if ecp::CURVETYPE != CurveType::MONTGOMERY {
+        for i in 0..17 {
+            m[i] = i as u8
+        }
+
+        println!("Testing ECIES");
+
+        p1[0] = 0x0;
+        p1[1] = 0x1;
+        p1[2] = 0x2;
+        p2[0] = 0x0;
+        p2[1] = 0x1;
+        p2[2] = 0x2;
+        p2[3] = 0x3;
+
+        let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t);
+
+        if let Some(mut c) = cc {
+            println!("Ciphertext= ");
+            print!("V= 0x");
+            printbinary(&v);
+            print!("C= 0x");
+            printbinary(&c);
+            print!("T= 0x");
+            printbinary(&t);
+
+            let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1);
+            if let Some(rm) = mm {
+                println!("Decryption succeeded");
+                print!("Message is 0x");
+                printbinary(&rm);
+            } else {
+                println!("*** ECIES Decryption Failed");
+                return;
+            }
+        } else {
+            println!("*** ECIES Encryption Failed");
+            return;
+        }
+
+        println!("Testing ECDSA");
+
+        if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 {
+            println!("***ECDSA Signature Failed");
+            return;
+        }
+        println!("Signature= ");
+        print!("C= 0x");
+        printbinary(&cs);
+        print!("D= 0x");
+        printbinary(&ds);
+
+        if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 {
+            println!("***ECDSA Verification Failed");
+            return;
+        } else {
+            println!("ECDSA Signature/Verification succeeded ")
+        }
+    }
+}
+
+fn mpin_bn254(mut rng: &mut RAND) {
+    //use amcl::bn254;
+    use amcl::bn254::ecp;
+    use amcl::bn254::mpin;
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin::EFS;
+    const EGS: usize = mpin::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hcid);
+        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hsid);
+        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+fn mpin_bls383(mut rng: &mut RAND) {
+    //use amcl::bls383;
+    use amcl::bls383::ecp;
+    use amcl::bls383::mpin;
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin::EFS;
+    const EGS: usize = mpin::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut g2: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut f: [u8; 12 * EFS] = [0; 12 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hcid);
+        mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin::hash_id(sha, &client_id, &mut hsid);
+        mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+fn mpin_bls24(mut rng: &mut RAND) {
+    //use amcl::bls24;
+    use amcl::bls24::ecp;
+    use amcl::bls24::mpin192;
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin192::EFS;
+    const EGS: usize = mpin192::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 8 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut g2: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut f: [u8; 24 * EFS] = [0; 24 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin192::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin192::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin192::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin192::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin192::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin192::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin192::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin192::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin192::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin192::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin192::hash_id(sha, &client_id, &mut hcid);
+        mpin192::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin192::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin192::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin192::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin192::hash_id(sha, &client_id, &mut hsid);
+        mpin192::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin192::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin192::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin192::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin192::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin192::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin192::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin192::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin192::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin192::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+fn mpin_bls48(mut rng: &mut RAND) {
+    //use amcl::bls48;
+    use amcl::bls48::ecp;
+    use amcl::bls48::mpin256;
+
+    pub const PERMITS: bool = true;
+    pub const PINERROR: bool = true;
+    pub const FULL: bool = true;
+    //pub const SINGLE_PASS:bool=false;
+
+    const EFS: usize = mpin256::EFS;
+    const EGS: usize = mpin256::EGS;
+
+    let mut s: [u8; EGS] = [0; EGS];
+    const RM: usize = EFS as usize;
+    let mut hcid: [u8; RM] = [0; RM];
+    let mut hsid: [u8; RM] = [0; RM];
+
+    const G1S: usize = 2 * EFS + 1; /* Group 1 Size */
+    const G2S: usize = 16 * EFS; /* Group 2 Size */
+    const EAS: usize = ecp::AESKEY;
+
+    let mut sst: [u8; G2S] = [0; G2S];
+    let mut token: [u8; G1S] = [0; G1S];
+    let mut permit: [u8; G1S] = [0; G1S];
+    let mut g1: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut g2: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut xid: [u8; G1S] = [0; G1S];
+    let mut xcid: [u8; G1S] = [0; G1S];
+    let mut x: [u8; EGS] = [0; EGS];
+    let mut y: [u8; EGS] = [0; EGS];
+    let mut sec: [u8; G1S] = [0; G1S];
+    let mut r: [u8; EGS] = [0; EGS];
+    let mut z: [u8; G1S] = [0; G1S];
+    let mut hid: [u8; G1S] = [0; G1S];
+    let mut htid: [u8; G1S] = [0; G1S];
+    let mut rhid: [u8; G1S] = [0; G1S];
+    let mut w: [u8; EGS] = [0; EGS];
+    let mut t: [u8; G1S] = [0; G1S];
+    let mut e: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut f: [u8; 48 * EFS] = [0; 48 * EFS];
+    let mut h: [u8; RM] = [0; RM];
+    let mut ck: [u8; EAS] = [0; EAS];
+    let mut sk: [u8; EAS] = [0; EAS];
+
+    let sha = ecp::HASH_TYPE;
+
+    println!("\nTesting MPIN - PIN is 1234");
+    /* Trusted Authority set-up */
+
+    mpin256::random_generate(&mut rng, &mut s);
+    print!("Master Secret s: 0x");
+    printbinary(&s);
+
+    /* Create Client Identity */
+    let name = "testUser@miracl.com";
+    let client_id = name.as_bytes();
+
+    print!("Client ID= ");
+    printbinary(&client_id);
+
+    mpin256::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+    /* Client and Server are issued secrets by DTA */
+    mpin256::get_server_secret(&s, &mut sst);
+    print!("Server Secret SS: 0x");
+    printbinary(&sst);
+
+    mpin256::get_client_secret(&mut s, &hcid, &mut token);
+    print!("Client Secret CS: 0x");
+    printbinary(&token);
+
+    /* Client extracts PIN from secret to create Token */
+    let pin: i32 = 1234;
+    println!("Client extracts PIN= {}", pin);
+    let mut rtn = mpin256::extract_pin(sha, &client_id, pin, &mut token);
+    if rtn != 0 {
+        println!("FAILURE: EXTRACT_PIN rtn: {}", rtn);
+    }
+
+    print!("Client Token TK: 0x");
+    printbinary(&token);
+
+    if FULL {
+        mpin256::precompute(&token, &hcid, &mut g1, &mut g2);
+    }
+
+    let mut date = 0;
+    if PERMITS {
+        date = mpin256::today();
+        /* Client gets "Time Token" permit from DTA */
+
+        mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit);
+        print!("Time Permit TP: 0x");
+        printbinary(&permit);
+
+        /* This encoding makes Time permit look random - Elligator squared */
+        mpin256::encoding(&mut rng, &mut permit);
+        print!("Encoded Time Permit TP: 0x");
+        printbinary(&permit);
+        mpin256::decoding(&mut permit);
+        print!("Decoded Time Permit TP: 0x");
+        printbinary(&permit);
+    }
+
+    print!("\nPIN= ");
+    let _ = io::Write::flush(&mut io::stdout());
+    let mut input_text = String::new();
+    let _ = io::stdin().read_line(&mut input_text);
+
+    let pin = input_text.trim().parse::<usize>().unwrap();
+
+    println!("MPIN Multi Pass");
+    /* Send U=x.ID to server, and recreate secret from token and pin */
+    rtn = mpin256::client_1(
+        sha,
+        date,
+        &client_id,
+        Some(&mut rng),
+        &mut x,
+        pin,
+        &token,
+        &mut sec,
+        Some(&mut xid[..]),
+        Some(&mut xcid[..]),
+        Some(&permit[..]),
+    );
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_1 rtn: {}", rtn);
+    }
+
+    if FULL {
+        mpin256::hash_id(sha, &client_id, &mut hcid);
+        mpin256::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */
+    }
+
+    /* Server calculates H(ID) and H(T|H(ID)) (if time mpin256::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */
+
+    mpin256::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..]));
+
+    if date != 0 {
+        rhid.clone_from_slice(&htid[..]);
+    } else {
+        rhid.clone_from_slice(&hid[..]);
+    }
+
+    /* Server generates Random number Y and sends it to Client */
+    mpin256::random_generate(&mut rng, &mut y);
+
+    if FULL {
+        mpin256::hash_id(sha, &client_id, &mut hsid);
+        mpin256::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w  */
+    }
+
+    /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+    rtn = mpin256::client_2(&x, &y, &mut sec);
+    if rtn != 0 {
+        println!("FAILURE: CLIENT_2 rtn: {}", rtn);
+    }
+
+    /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+    /* If PIN error not required, set E and F = null */
+
+    if !PINERROR {
+        rtn = mpin256::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            None,
+            None,
+        );
+    } else {
+        rtn = mpin256::server_2(
+            date,
+            &hid,
+            Some(&htid[..]),
+            &y,
+            &sst,
+            Some(&xid[..]),
+            Some(&xcid[..]),
+            &sec,
+            Some(&mut e),
+            Some(&mut f),
+        );
+    }
+
+    if rtn == mpin256::BAD_PIN {
+        println!("Server says - Bad Pin. I don't know you. Feck off.");
+        if PINERROR {
+            let err = mpin256::kangaroo(&e, &f);
+            if err != 0 {
+                println!("(Client PIN is out by {})", err)
+            }
+        }
+        return;
+    } else {
+        println!("Server says - PIN is good! You really are {}", name);
+    }
+
+    if FULL {
+        let mut pxcid = None;
+        if PERMITS {
+            pxcid = Some(&xcid[..])
+        };
+
+        mpin256::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin256::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck);
+        print!("Client Key =  0x");
+        printbinary(&ck);
+
+        mpin256::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h);
+        mpin256::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk);
+        print!("Server Key =  0x");
+        printbinary(&sk);
+    }
+}
+
+fn rsa_2048(mut rng: &mut RAND) {
+    //use amcl::rsa2048;
+    use amcl::rsa2048::ff;
+    use amcl::rsa2048::rsa;
+
+    let sha = rsa::HASH_TYPE;
+    let message: &[u8] = b"Hello World\n";
+    const RFS: usize = rsa::RFS;
+
+    let mut pbc = rsa::new_public_key(ff::FFLEN);
+    let mut prv = rsa::new_private_key(ff::HFLEN);
+
+    let mut ml: [u8; RFS] = [0; RFS];
+    let mut ms: [u8; RFS] = [0; RFS];
+    let mut c: [u8; RFS] = [0; RFS];
+    let mut s: [u8; RFS] = [0; RFS];
+    let mut e: [u8; RFS] = [0; RFS];
+
+    println!("\nTesting RSA");
+    println!("Generating public/private key pair");
+    rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc);
+
+    println!("Encrypting test string\n");
+    rsa::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E  */
+
+    rsa::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */
+    print!("Ciphertext= 0x");
+    printbinary(&c);
+
+    println!("Decrypting test string");
+    rsa::decrypt(&prv, &c, &mut ml);
+    let mlen = rsa::oaep_decode(sha, None, &mut ml); /* OAEP decode message  */
+
+    let mess = str::from_utf8(&ml[0..mlen]).unwrap();
+    print!("{}", &mess);
+
+    println!("Signing message");
+    rsa::pkcs15(sha, message, &mut c);
+
+    rsa::decrypt(&prv, &c, &mut s); /* create signature in S */
+
+    print!("Signature= 0x");
+    printbinary(&s);
+
+    rsa::encrypt(&pbc, &s, &mut ms);
+
+    let mut cmp = true;
+    if c.len() != ms.len() {
+        cmp = false;
+    } else {
+        for j in 0..c.len() {
+            if c[j] != ms[j] {
+                cmp = false
+            }
+        }
+    }
+    if cmp {
+        println!("Signature is valid");
+    } else {
+        println!("Signature is INVALID");
+    }
+
+    rsa::private_key_kill(&mut prv);
+}
+
+//#[test]
+fn main() {
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut rng = RAND::new();
+    rng.clean();
+    for i in 0..100 {
+        raw[i] = i as u8
+    }
+
+    rng.seed(100, &raw);
+
+    ecdh_ed25519(&mut rng);
+    ecdh_nist256(&mut rng);
+    ecdh_goldilocks(&mut rng);
+    mpin_bn254(&mut rng);
+    mpin_bls383(&mut rng);
+    mpin_bls24(&mut rng);
+    mpin_bls48(&mut rng);
+    rsa_2048(&mut rng);
+}
diff --git a/TestBLS.rs b/TestBLS.rs
new file mode 100644
index 0000000..1a54ee4
--- /dev/null
+++ b/TestBLS.rs
@@ -0,0 +1,190 @@
+/*
+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.
+*/
+
+extern crate amcl;
+
+use amcl::rand::RAND;
+
+pub fn printbinary(array: &[u8]) {
+    for i in 0..array.len() {
+        print!("{:02X}", array[i])
+    }
+    println!("")
+}
+
+fn bls_bn254(mut rng: &mut RAND) {
+    use amcl::bn254::bls;
+
+    const BFS: usize = bls::BFS;
+    const BGS: usize = bls::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+fn bls_bls383(mut rng: &mut RAND) {
+    use amcl::bls383::bls;
+
+    const BFS: usize = bls::BFS;
+    const BGS: usize = bls::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 4 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+fn bls_bls24(mut rng: &mut RAND) {
+    use amcl::bls24::bls192;
+
+    const BFS: usize = bls192::BFS;
+    const BGS: usize = bls192::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 8 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls192::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls192::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls192::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+fn bls_bls48(mut rng: &mut RAND) {
+    use amcl::bls48::bls256;
+
+    const BFS: usize = bls256::BFS;
+    const BGS: usize = bls256::BGS;
+
+    let mut s: [u8; BGS] = [0; BGS];
+
+    const G1S: usize = BFS + 1; /* Group 1 Size */
+    const G2S: usize = 16 * BFS; /* Group 2 Size */
+
+    let mut w: [u8; G2S] = [0; G2S];
+    let mut sig: [u8; G1S] = [0; G1S];
+
+    let m = String::from("This is a test message");
+
+    bls256::key_pair_generate(&mut rng, &mut s, &mut w);
+    print!("Private key : 0x");
+    printbinary(&s);
+    print!("Public  key : 0x");
+    printbinary(&w);
+
+    bls256::sign(&mut sig, &m, &s);
+    print!("Signature : 0x");
+    printbinary(&sig);
+
+    let res = bls256::verify(&sig, &m, &w);
+    if res == 0 {
+        println!("Signature is OK");
+    } else {
+        println!("Signature is *NOT* OK");
+    }
+}
+
+fn main() {
+    use amcl::arch;
+
+    let mut raw: [u8; 100] = [0; 100];
+
+    let mut rng = RAND::new();
+    rng.clean();
+    for i in 0..100 {
+        raw[i] = i as u8
+    }
+
+    rng.seed(100, &raw);
+
+    println!("{} bit build", arch::CHUNK);
+
+    println!("Testing BLS signature for curve BN254");
+    bls_bn254(&mut rng);
+    println!("\nTesting BLS signature for curve BLS383");
+    bls_bls383(&mut rng);
+    println!("\nTesting BLS signature for curve BLS24");
+    bls_bls24(&mut rng);
+    println!("\nTesting BLS signature for curve BLS48");
+    bls_bls48(&mut rng);
+}
diff --git a/TestNHS.rs b/TestNHS.rs
new file mode 100644
index 0000000..4e7ed02
--- /dev/null
+++ b/TestNHS.rs
@@ -0,0 +1,77 @@
+/*
+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.
+*/
+
+//  TestNHS.rs - Tests NewHope Simple API
+
+// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe)
+
+// rustc TestNHS.rs --extern amcl=libamcl.rlib
+
+extern crate amcl;
+
+//use std::str;
+//use std::io;
+
+use amcl::rand::RAND;
+//use amcl::aes;
+use amcl::nhs;
+
+//#[test]
+fn main()
+{
+	let mut raw:[u8;100]=[0;100];	
+
+	let mut srng=RAND::new();
+	srng.clean();
+	for i in 0..100 {raw[i]=(i+1) as u8}
+
+	srng.seed(100,&raw);	
+
+
+									let mut crng=RAND::new();
+									crng.clean();
+									for i in 0..100 {raw[i]=(i+2) as u8}
+
+									crng.seed(100,&raw);	
+
+
+	let mut ss:[u8;1792]=[0;1792];
+					let mut sb:[u8;1824]=[0;1824];
+					let mut uc:[u8;2176]=[0;2176];
+
+	let mut keya:[u8;32]=[0;32];
+									let mut keyb:[u8;32]=[0;32];
+
+	nhs::server_1(&mut srng,&mut sb,&mut ss);
+
+									nhs::client(&mut crng,&sb,&mut uc,&mut keyb);
+
+	nhs::server_2(&ss,&uc,&mut keya);
+
+	for i in 0..keya.len() {
+		print!("{:02X}", keya[i]);
+	}
+	println!("");	
+
+									for i in 0..keyb.len() {
+										print!("{:02X}", keyb[i]);
+									}
+									println!("");		
+
+}
\ No newline at end of file
diff --git a/deploy.token b/deploy.token
new file mode 100644
index 0000000..32b7050
--- /dev/null
+++ b/deploy.token
@@ -0,0 +1 @@
+1YhwbnDDEE2ZdX8P7g4U9WY3uzKTZHvIk5qKEivXYQbQwtLsugOlh8plPhFuL9M6lQeiHX7GeuQkevsymgXHrXVV5QFB7JtsJmh4tJcIiJ8z+9YWchHmCLRkXWoWgoXxwEGIne48KT3At43gCKJGNFGmYAl00XtgiQ1SAfop0LmImrWWHyDIAxeou6GBSg+S2Gz5+AePf3HDnXCfgX2f+tw/SGlEi6LDAtyoU7+yF584g9d5PK6Ctm7GMCdS4M65mqhcqUkrqy4jGomAkf57/j4zauj2ISmyHcmfkKNFvK2qFlf/vy65hacFV3+nIUYvcAv8aasT5Qx895LsQ3xXmCIJnorqd1c7xeafjQudLwpDlyJs5j82NZUIQn+mMkCuSj5g686gpfuKMNs0Gthl2Z7IzmQWiP5PgDZd/QEx/4Q4jUoy8CtrZu6BCxAK7muLLWaI91gWpducaJKZ6dVHZ5tBz7XHG7NFpqRssCUfIMhg [...]
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..da805e0
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,83 @@
+NOTE: Updated to Rust 2018
+
+NOTE: This version of the library requires Version 1.31+ of Rust for 64-bit 
+integer support and for Rust 2018. 
+
+Now AMCL version 3 is distributed as a cargo crate.
+
+Namespaces are used to separate different curves.
+
+To build the library and see it in action, copy all of the files in this 
+directory and its subdirectories to a fresh root directory. 
+
+Then for example execute
+
+cargo rustc  --release --features "bn254 bls383 bls24 bls48 ed25519 nist256 goldilocks rsa2048"
+
+This will create a build of the library for the current default target (be it 32 or 64 bits). 
+
+(To test a 32-bit environment you can follow the Web Assembly (wasm) readme instructions for rust)
+
+Next copy the library from target/release/libamcl.rlib into the root 
+directory and execute
+
+rustc TestALL.rs --extern amcl=libamcl.rlib
+
+rustc TestBLS.rs --extern amcl=libamcl.rlib
+
+rustc BenchtestALL.rs --extern amcl=libamcl.rlib
+
+rustc TestNHS.rs --extern amcl=libamcl.rlib
+
+Finally execute these programs.
+
+To add amcl functionality to your own programs, add a dependency to your 
+Cargo.toml file. For example to use the curve bls48, add this dependency
+
+[dependencies]
+
+amcl = { version = "0.2.0",  optional = true, default-features = false, features = ["bls48"]}
+
+if published to crates.io, or 
+
+amcl = { version = "0.2.0",  optional = true, default-features = false, features = ["bls48"], path="your_amcl_location" }
+
+And to use primitives of the needed curve in your source code:
+
+use amcl::bls48::{ECP, ECP8}; //any primitive you need
+
+Full list of features:
+
+* Elliptic Curves
+  * ed25519
+  * c25519
+  * nist256
+  * brainpool
+  * anssi
+  * hifive
+  * goldilocks
+  * nist384
+  * c41417
+  * nist521
+  * nums256w
+  * nums256e
+  * nums384w
+  * nums384e
+  * nums512w
+  * nums512e
+  * secp256k1
+* Pairing-Friendly Elliptic Curves
+  * bn254
+  * bn254CX
+  * bls383
+  * bls381
+  * fp256BN
+  * fp512BN
+  * bls461
+  * bls24
+  * bls48
+  
+* RSA
+  * rsa2048
+  * rsa3072
+  * rsa4096
diff --git a/src/aes.rs b/src/aes.rs
new file mode 100644
index 0000000..eedea79
--- /dev/null
+++ b/src/aes.rs
@@ -0,0 +1,772 @@
+/*
+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.
+*/
+
+pub const ECB: usize = 0;
+pub const CBC: usize = 1;
+pub const CFB1: usize = 2;
+pub const CFB2: usize = 3;
+pub const CFB4: usize = 5;
+pub const OFB1: usize = 14;
+pub const OFB2: usize = 15;
+pub const OFB4: usize = 17;
+pub const OFB8: usize = 21;
+pub const OFB16: usize = 29;
+pub const CTR1: usize = 30;
+pub const CTR2: usize = 31;
+pub const CTR4: usize = 33;
+pub const CTR8: usize = 37;
+pub const CTR16: usize = 45;
+
+const INCO: [u8; 4] = [0xB, 0xD, 0x9, 0xE]; /* Inverse Coefficients */
+
+const PTAB: [u8; 256] = [
+    1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, 95, 225, 56, 72, 216, 115,
+    149, 164, 247, 2, 6, 10, 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217,
+    112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+    76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, 131, 158, 185, 208,
+    107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, 181, 196, 87, 249, 16, 48, 80, 240,
+    11, 29, 39, 105, 187, 214, 97, 163, 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174,
+    233, 32, 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, 195,
+    94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172,
+    239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35, 101, 175,
+    234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176,
+    203, 70, 202, 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, 18, 54,
+    90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, 57, 75, 221, 124, 132, 151,
+    162, 253, 28, 36, 108, 180, 199, 82, 246, 1,
+];
+
+const LTAB: [u8; 256] = [
+    0, 255, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3, 100, 4, 224, 14, 52, 141,
+    129, 239, 76, 113, 8, 200, 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
+    166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218,
+    142, 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56, 102, 221, 253,
+    48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16, 126, 110, 72, 195, 163, 182, 30, 66,
+    58, 107, 40, 84, 250, 133, 61, 186, 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243,
+    115, 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232, 44,
+    215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23,
+    196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96, 177, 134, 59, 82,
+    161, 108, 170, 85, 41, 157, 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63,
+    91, 209, 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171, 68, 17, 146,
+    217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165, 103, 74, 237, 222, 197, 49, 254,
+    24, 13, 99, 140, 128, 192, 247, 112, 7,
+];
+
+const FBSUB: [u8; 256] = [
+    99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125,
+    250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
+    52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235,
+    39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0,
+    237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133,
+    69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16,
+    255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129,
+    79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92,
+    194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234,
+    101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
+    112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105,
+    217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65,
+    153, 45, 15, 176, 84, 187, 22,
+];
+
+const RBSUB: [u8; 256] = [
+    82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251, 124, 227, 57, 130,
+    155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61,
+    238, 76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109,
+    139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146, 108,
+    112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140,
+    188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175,
+    189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230,
+    115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26,
+    113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32,
+    154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39,
+    128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,
+    224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119,
+    214, 38, 225, 105, 20, 99, 85, 33, 12, 125,
+];
+
+const RCO: [u8; 16] = [
+    1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154, 47,
+];
+
+const FTABLE: [u32; 256] = [
+    0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0xdf2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
+    0x50303060, 0x3010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
+    0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0xbf0f0fb,
+    0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
+    0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x2f7f7f5, 0x4fcccc83,
+    0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x8f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
+    0xc040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0xf05050a, 0xb59a9a2f,
+    0x907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
+    0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
+    0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+    0xf55353a6, 0x68d1d1b9, 0x0, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
+    0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
+    0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
+    0xcf45458a, 0x10f9f9e9, 0x6020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
+    0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x4f5f5f1,
+    0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0xef3f3fd, 0x6dd2d2bf,
+    0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
+    0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
+    0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
+    0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+    0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0xa06060c, 0x6c242448, 0xe45c5cb8,
+    0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
+    0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
+    0xb46c6cd8, 0xfa5656ac, 0x7f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
+    0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+    0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
+    0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x5030306, 0x1f6f6f7, 0x120e0e1c,
+    0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
+    0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
+    0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+    0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
+    0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
+];
+
+const RTABLE: [u32; 256] = [
+    0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
+    0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
+    0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x2752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
+    0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
+    0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+    0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
+    0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
+    0x728ebb2, 0x3c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
+    0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
+    0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x69f715e, 0x51106ebd,
+    0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x55dc471, 0x6fd40604, 0xff155060,
+    0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
+    0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x0, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
+    0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
+    0xb1670a0c, 0xfe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+    0xaba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0xb0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
+    0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
+    0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
+    0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
+    0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+    0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
+    0xe49d3a2c, 0xd927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
+    0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
+    0x97826cd, 0xf418596e, 0x1b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x8cfbc21, 0xe6e815ef,
+    0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+    0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0xe50cd7f, 0x2ff69117,
+    0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
+    0x4ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
+    0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
+    0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+    0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0xc25e2bc, 0x8b493c28, 0x41950dff,
+    0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0,
+];
+
+pub struct AES {
+    nk: usize,
+    nr: usize,
+    mode: usize,
+    fkey: [u32; 60],
+    rkey: [u32; 60],
+    pub f: [u8; 16],
+}
+
+impl AES {
+    fn rotl8(x: u32) -> u32 {
+        return ((x) << 8) | ((x) >> 24);
+    }
+
+    fn rotl16(x: u32) -> u32 {
+        return ((x) << 16) | ((x) >> 16);
+    }
+
+    fn rotl24(x: u32) -> u32 {
+        return ((x) << 24) | ((x) >> 8);
+    }
+
+    fn pack(b: [u8; 4]) -> u32 {
+        /* pack bytes into a 32-bit Word */
+        return ((((b[3]) & 0xff) as u32) << 24)
+            | ((((b[2]) & 0xff) as u32) << 16)
+            | ((((b[1]) & 0xff) as u32) << 8)
+            | (((b[0]) & 0xff) as u32);
+    }
+
+    fn unpack(a: u32) -> [u8; 4] {
+        /* unpack bytes from a word */
+        let b: [u8; 4] = [
+            (a & 0xff) as u8,
+            ((a >> 8) & 0xff) as u8,
+            ((a >> 16) & 0xff) as u8,
+            ((a >> 24) & 0xff) as u8,
+        ];
+        return b;
+    }
+
+    fn bmul(x: u8, y: u8) -> u8 {
+        /* x.y= AntiLog(Log(x) + Log(y)) */
+        let ix = (x as usize) & 0xff;
+        let iy = (y as usize) & 0xff;
+        let lx = (LTAB[ix] as usize) & 0xff;
+        let ly = (LTAB[iy] as usize) & 0xff;
+
+        if x != 0 && y != 0 {
+            return PTAB[(lx + ly) % 255];
+        } else {
+            return 0;
+        }
+    }
+
+    fn subbyte(a: u32) -> u32 {
+        let mut b = AES::unpack(a);
+        b[0] = FBSUB[b[0] as usize];
+        b[1] = FBSUB[b[1] as usize];
+        b[2] = FBSUB[b[2] as usize];
+        b[3] = FBSUB[b[3] as usize];
+        return AES::pack(b);
+    }
+
+    fn product(x: u32, y: u32) -> u8 {
+        /* dot product of two 4-byte arrays */
+        let xb = AES::unpack(x);
+        let yb = AES::unpack(y);
+
+        return AES::bmul(xb[0], yb[0])
+            ^ AES::bmul(xb[1], yb[1])
+            ^ AES::bmul(xb[2], yb[2])
+            ^ AES::bmul(xb[3], yb[3]);
+    }
+
+    fn invmixcol(x: u32) -> u32 {
+        /* matrix Multiplication */
+        let mut b: [u8; 4] = [0; 4];
+        let mut m = AES::pack(INCO);
+        b[3] = AES::product(m, x);
+        m = AES::rotl24(m);
+        b[2] = AES::product(m, x);
+        m = AES::rotl24(m);
+        b[1] = AES::product(m, x);
+        m = AES::rotl24(m);
+        b[0] = AES::product(m, x);
+        let y = AES::pack(b);
+        return y;
+    }
+
+    fn increment(f: &mut [u8; 16]) {
+        for i in 0..16 {
+            f[i] += 1;
+            if f[i] != 0 {
+                break;
+            }
+        }
+    }
+
+    pub fn new() -> AES {
+        AES {
+            nk: 0,
+            nr: 0,
+            mode: 0,
+            fkey: [0; 60],
+            rkey: [0; 60],
+            f: [0; 16],
+        }
+    }
+
+    /* reset cipher */
+    pub fn reset(&mut self, m: usize, iv: Option<[u8; 16]>) {
+        /* reset mode, or reset iv */
+        self.mode = m;
+        for i in 0..16 {
+            self.f[i] = 0
+        }
+        if self.mode != ECB {
+            if let Some(x) = iv {
+                for i in 0..16 {
+                    self.f[i] = x[i]
+                }
+            }
+        }
+    }
+
+    pub fn init(&mut self, m: usize, nkey: usize, key: &[u8], iv: Option<[u8; 16]>) -> bool {
+        /* Key Scheduler. Create expanded encryption key */
+        let mut cipherkey: [u32; 8] = [0; 8];
+        let mut b: [u8; 4] = [0; 4];
+        let nk = nkey / 4;
+        if nk != 4 && nk != 6 && nk != 8 {
+            return false;
+        }
+        let nr = 6 + nk;
+        self.nk = nk;
+        self.nr = nr;
+        self.reset(m, iv);
+        let n = 4 * (nr + 1);
+
+        let mut j = 0;
+        for i in 0..nk {
+            for k in 0..4 {
+                b[k] = key[j + k]
+            }
+            cipherkey[i] = AES::pack(b);
+            j += 4;
+        }
+
+        for i in 0..nk {
+            self.fkey[i] = cipherkey[i]
+        }
+
+        j = nk;
+        let mut k = 0;
+        while j < n {
+            self.fkey[j] =
+                self.fkey[j - nk] ^ AES::subbyte(AES::rotl24(self.fkey[j - 1])) ^ (RCO[k] as u32);
+            if nk<=6 { 
+		for i in 1..nk {
+			if (i + j) >= n {
+				break;
+			}
+			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+		}
+	    } else {
+		for i in 1..4  {
+			if (i + j) >= n {
+				break;
+			}
+			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+		}
+		
+		if (j + 4) < n {
+			self.fkey[j + 4] = self.fkey[j + 4 - nk] ^ AES::subbyte(self.fkey[j + 3]);
+		}
+		for i in 5..nk {
+			if (i + j) >= n {
+				break;
+			}
+			self.fkey[i + j] = self.fkey[i + j - nk] ^ self.fkey[i + j - 1];
+		}	        
+	    }
+            j += nk;
+            k += 1;
+        }
+
+        /* now for the expanded decrypt key in reverse order */
+
+        for j in 0..4 {
+            self.rkey[j + n - 4] = self.fkey[j]
+        }
+        let mut i = 4;
+        while i < n - 4 {
+            let k = n - 4 - i;
+            for j in 0..4 {
+                self.rkey[k + j] = AES::invmixcol(self.fkey[i + j])
+            }
+            i += 4;
+        }
+        for j in n - 4..n {
+            self.rkey[j + 4 - n] = self.fkey[j]
+        }
+        return true;
+    }
+
+    pub fn getreg(&mut self) -> [u8; 16] {
+        let mut ir: [u8; 16] = [0; 16];
+        for i in 0..16 {
+            ir[i] = self.f[i]
+        }
+        return ir;
+    }
+
+    /* Encrypt a single block */
+    pub fn ecb_encrypt(&mut self, buff: &mut [u8; 16]) {
+        let mut b: [u8; 4] = [0; 4];
+        let mut p: [u32; 4] = [0; 4];
+        let mut q: [u32; 4] = [0; 4];
+
+        let mut j = 0;
+        for i in 0..4 {
+            for k in 0..4 {
+                b[k] = buff[j + k]
+            }
+            p[i] = AES::pack(b);
+            p[i] ^= self.fkey[i];
+            j += 4;
+        }
+
+        let mut k = 4;
+
+        /* State alternates between p and q */
+        for _ in 1..self.nr {
+            q[0] = self.fkey[k]
+                ^ FTABLE[(p[0] & 0xff) as usize]
+                ^ AES::rotl8(FTABLE[((p[1] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(FTABLE[((p[2] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(FTABLE[((p[3] >> 24) & 0xff) as usize]);
+
+            q[1] = self.fkey[k + 1]
+                ^ FTABLE[(p[1] & 0xff) as usize]
+                ^ AES::rotl8(FTABLE[((p[2] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(FTABLE[((p[3] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(FTABLE[((p[0] >> 24) & 0xff) as usize]);
+
+            q[2] = self.fkey[k + 2]
+                ^ FTABLE[(p[2] & 0xff) as usize]
+                ^ AES::rotl8(FTABLE[((p[3] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(FTABLE[((p[0] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(FTABLE[((p[1] >> 24) & 0xff) as usize]);
+
+            q[3] = self.fkey[k + 3]
+                ^ FTABLE[(p[3] & 0xff) as usize]
+                ^ AES::rotl8(FTABLE[((p[0] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(FTABLE[((p[1] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(FTABLE[((p[2] >> 24) & 0xff) as usize]);
+
+            k += 4;
+            for j in 0..4 {
+                let t = p[j];
+                p[j] = q[j];
+                q[j] = t;
+            }
+        }
+
+        /* Last Round */
+
+        q[0] = self.fkey[k]
+            ^ (FBSUB[(p[0] & 0xff) as usize] as u32)
+            ^ AES::rotl8((FBSUB[((p[1] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((FBSUB[((p[2] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((FBSUB[((p[3] >> 24) & 0xff) as usize]) as u32);
+
+        q[1] = self.fkey[k + 1]
+            ^ (FBSUB[(p[1] & 0xff) as usize] as u32)
+            ^ AES::rotl8((FBSUB[((p[2] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((FBSUB[((p[3] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((FBSUB[((p[0] >> 24) & 0xff) as usize]) as u32);
+
+        q[2] = self.fkey[k + 2]
+            ^ (FBSUB[(p[2] & 0xff) as usize] as u32)
+            ^ AES::rotl8((FBSUB[((p[3] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((FBSUB[((p[0] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((FBSUB[((p[1] >> 24) & 0xff) as usize]) as u32);
+
+        q[3] = self.fkey[k + 3]
+            ^ (FBSUB[(p[3] & 0xff) as usize] as u32)
+            ^ AES::rotl8((FBSUB[((p[0] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((FBSUB[((p[1] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((FBSUB[((p[2] >> 24) & 0xff) as usize]) as u32);
+
+        j = 0;
+        for i in 0..4 {
+            b = AES::unpack(q[i]);
+            for k in 0..4 {
+                buff[j + k] = b[k]
+            }
+            j += 4;
+        }
+    }
+
+    /* Decrypt a single block */
+    pub fn ecb_decrypt(&mut self, buff: &mut [u8; 16]) {
+        let mut b: [u8; 4] = [0; 4];
+        let mut p: [u32; 4] = [0; 4];
+        let mut q: [u32; 4] = [0; 4];
+
+        let mut j = 0;
+        for i in 0..4 {
+            for k in 0..4 {
+                b[k] = buff[j + k]
+            }
+            p[i] = AES::pack(b);
+            p[i] ^= self.rkey[i];
+            j += 4;
+        }
+
+        let mut k = 4;
+
+        /* State alternates between p and q */
+        for _ in 1..self.nr {
+            q[0] = self.rkey[k]
+                ^ RTABLE[(p[0] & 0xff) as usize]
+                ^ AES::rotl8(RTABLE[((p[3] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(RTABLE[((p[2] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(RTABLE[((p[1] >> 24) & 0xff) as usize]);
+
+            q[1] = self.rkey[k + 1]
+                ^ RTABLE[(p[1] & 0xff) as usize]
+                ^ AES::rotl8(RTABLE[((p[0] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(RTABLE[((p[3] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(RTABLE[((p[2] >> 24) & 0xff) as usize]);
+
+            q[2] = self.rkey[k + 2]
+                ^ RTABLE[(p[2] & 0xff) as usize]
+                ^ AES::rotl8(RTABLE[((p[1] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(RTABLE[((p[0] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(RTABLE[((p[3] >> 24) & 0xff) as usize]);
+
+            q[3] = self.rkey[k + 3]
+                ^ RTABLE[(p[3] & 0xff) as usize]
+                ^ AES::rotl8(RTABLE[((p[2] >> 8) & 0xff) as usize])
+                ^ AES::rotl16(RTABLE[((p[1] >> 16) & 0xff) as usize])
+                ^ AES::rotl24(RTABLE[((p[0] >> 24) & 0xff) as usize]);
+
+            k += 4;
+            for j in 0..4 {
+                let t = p[j];
+                p[j] = q[j];
+                q[j] = t;
+            }
+        }
+
+        /* Last Round */
+
+        q[0] = self.rkey[k]
+            ^ (RBSUB[(p[0] & 0xff) as usize] as u32)
+            ^ AES::rotl8((RBSUB[((p[3] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((RBSUB[((p[2] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((RBSUB[((p[1] >> 24) & 0xff) as usize]) as u32);
+
+        q[1] = self.rkey[k + 1]
+            ^ (RBSUB[(p[1] & 0xff) as usize] as u32)
+            ^ AES::rotl8((RBSUB[((p[0] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((RBSUB[((p[3] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((RBSUB[((p[2] >> 24) & 0xff) as usize]) as u32);
+
+        q[2] = self.rkey[k + 2]
+            ^ (RBSUB[(p[2] & 0xff) as usize] as u32)
+            ^ AES::rotl8((RBSUB[((p[1] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((RBSUB[((p[0] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((RBSUB[((p[3] >> 24) & 0xff) as usize]) as u32);
+
+        q[3] = self.rkey[k + 3]
+            ^ (RBSUB[((p[3]) & 0xff) as usize] as u32)
+            ^ AES::rotl8((RBSUB[((p[2] >> 8) & 0xff) as usize]) as u32)
+            ^ AES::rotl16((RBSUB[((p[1] >> 16) & 0xff) as usize]) as u32)
+            ^ AES::rotl24((RBSUB[((p[0] >> 24) & 0xff) as usize]) as u32);
+
+        j = 0;
+        for i in 0..4 {
+            b = AES::unpack(q[i]);
+            for k in 0..4 {
+                buff[j + k] = b[k]
+            }
+            j += 4;
+        }
+    }
+
+    /* Encrypt using selected mode of operation */
+    pub fn encrypt(&mut self, buff: &mut [u8; 16]) -> u32 {
+        let mut st: [u8; 16] = [0; 16];
+
+        // Supported Modes of Operation
+
+        let mut fell_off: u32 = 0;
+
+        match self.mode {
+            ECB => {
+                self.ecb_encrypt(buff);
+                return 0;
+            }
+            CBC => {
+                for j in 0..16 {
+                    buff[j] ^= self.f[j]
+                }
+                self.ecb_encrypt(buff);
+                for j in 0..16 {
+                    self.f[j] = buff[j]
+                }
+                return 0;
+            }
+
+            CFB1 | CFB2 | CFB4 => {
+                let bytes = self.mode - CFB1 + 1;
+                for j in 0..bytes {
+                    fell_off = (fell_off << 8) | (self.f[j] as u32)
+                }
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                for j in bytes..16 {
+                    self.f[j - bytes] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    buff[j] ^= st[j];
+                    self.f[16 - bytes + j] = buff[j];
+                }
+                return fell_off;
+            }
+
+            OFB1 | OFB2 | OFB4 | OFB8 | OFB16 => {
+                let bytes = self.mode - OFB1 + 1;
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    buff[j] ^= st[j]
+                }
+                for j in 0..16 {
+                    self.f[j] = st[j]
+                }
+
+                //self.ecb_encrypt(&mut (self.f));
+                //for j in 0..bytes {buff[j]^=self.f[j]}
+                return 0;
+            }
+
+            CTR1 | CTR2 | CTR4 | CTR8 | CTR16 => {
+                let bytes = self.mode - CTR1 + 1;
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    buff[j] ^= st[j]
+                }
+                AES::increment(&mut (self.f));
+                return 0;
+            }
+
+            _ => {
+                return 0;
+            }
+        }
+    }
+
+    /* Decrypt using selected mode of operation */
+    pub fn decrypt(&mut self, buff: &mut [u8; 16]) -> u32 {
+        let mut st: [u8; 16] = [0; 16];
+
+        // Supported Modes of Operation
+
+        let mut fell_off: u32 = 0;
+
+        match self.mode {
+            ECB => {
+                self.ecb_decrypt(buff);
+                return 0;
+            }
+            CBC => {
+                for j in 0..16 {
+                    st[j] = self.f[j];
+                    self.f[j] = buff[j];
+                }
+                self.ecb_decrypt(buff);
+                for j in 0..16 {
+                    buff[j] ^= st[j];
+                    st[j] = 0;
+                }
+                return 0;
+            }
+            CFB1 | CFB2 | CFB4 => {
+                let bytes = self.mode - CFB1 + 1;
+                for j in 0..bytes {
+                    fell_off = (fell_off << 8) | (self.f[j] as u32)
+                }
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                for j in bytes..16 {
+                    self.f[j - bytes] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    self.f[16 - bytes + j] = buff[j];
+                    buff[j] ^= st[j];
+                }
+                return fell_off;
+            }
+            OFB1 | OFB2 | OFB4 | OFB8 | OFB16 => {
+                let bytes = self.mode - OFB1 + 1;
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    buff[j] ^= st[j]
+                }
+                for j in 0..16 {
+                    self.f[j] = st[j]
+                }
+                //  self.ecb_encrypt(A.f[:]);
+                //  for j in 0..bytes {buff[j]^=self.f[j]}
+                return 0;
+            }
+
+            CTR1 | CTR2 | CTR4 | CTR8 | CTR16 => {
+                let bytes = self.mode - CTR1 + 1;
+                for j in 0..16 {
+                    st[j] = self.f[j]
+                }
+                self.ecb_encrypt(&mut st);
+                for j in 0..bytes {
+                    buff[j] ^= st[j]
+                }
+                AES::increment(&mut (self.f));
+                return 0;
+            }
+
+            _ => {
+                return 0;
+            }
+        }
+    }
+
+    /* Clean up and delete left-overs */
+    pub fn end(&mut self) {
+        // clean up
+        for i in 0..4 * (self.nr + 1) {
+            self.fkey[i] = 0;
+            self.rkey[i] = 0
+        }
+        for i in 0..16 {
+            self.f[i] = 0
+        }
+    }
+}
+
+/*
+fn main()
+{
+    let mut key:[u8;32]=[0;32];
+    let mut block:[u8;16]=[0;16];
+    let mut iv: [u8;16] = [0;16];
+
+    for i in 0..32 {key[i]=0}
+    key[0]=1;
+    for i in 0..16 {iv[i]=i as u8}
+    for i in 0..16 {block[i]=i as u8}
+
+    let mut aes=AES::new();
+    aes.init(CTR16,32,&key,Some(iv));
+
+    println!("Plain= ");
+    for i in 0..16 {print!("{:02x} ",block[i])}
+    println!("");
+
+    aes.encrypt(&mut block);
+
+    println!("Encrypt= ");
+    for i in 0..16 {print!("{:02x} ",block[i])}
+    println!("");
+
+    aes.reset(CTR16,Some(iv));
+    aes.decrypt(&mut block);
+
+    println!("Decrypt= ");
+    for i in 0..16 {print!("{:02x} ",block[i])}
+    println!("");
+
+    aes.end();
+}
+*/
diff --git a/src/arch/arch32.rs b/src/arch/arch32.rs
new file mode 100644
index 0000000..2df2c97
--- /dev/null
+++ b/src/arch/arch32.rs
@@ -0,0 +1,22 @@
+/*
+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.
+*/
+
+pub type Chunk = i32;
+pub type DChunk = i64;
+pub const CHUNK: usize = 32;
diff --git a/src/arch/arch64.rs b/src/arch/arch64.rs
new file mode 100644
index 0000000..76b95d9
--- /dev/null
+++ b/src/arch/arch64.rs
@@ -0,0 +1,22 @@
+/*
+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.
+*/
+
+pub type Chunk = i64;
+pub type DChunk = i128;
+pub const CHUNK: usize = 64;
diff --git a/src/big.rs b/src/big.rs
new file mode 100644
index 0000000..7267ad4
--- /dev/null
+++ b/src/big.rs
@@ -0,0 +1,1070 @@
+/*
+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 super::super::arch;
+use super::super::arch::Chunk;
+
+use super::super::arch::DChunk;
+
+use super::dbig::DBIG;
+use rand::RAND;
+
+pub use super::rom::MODBYTES;
+pub use super::rom::BASEBITS;
+use std::cmp::Ordering;
+use std::fmt;
+
+pub const NLEN: usize = (1 + ((8 * MODBYTES - 1) / BASEBITS));
+pub const DNLEN: usize = 2 * NLEN;
+pub const BMASK: Chunk = ((1 << BASEBITS) - 1);
+pub const HBITS: usize = (BASEBITS / 2);
+pub const HMASK: Chunk = ((1 << HBITS) - 1);
+pub const NEXCESS: isize = (1 << ((arch::CHUNK) - BASEBITS - 1));
+pub const BIGBITS: usize = (MODBYTES * 8);
+
+#[derive(Copy)]
+pub struct BIG {
+    pub w: [Chunk; NLEN],
+}
+
+impl Clone for BIG {
+    fn clone(&self) -> BIG { *self }
+}
+
+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 {
+        if BIG::comp(self,other)==0 {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+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; 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..NLEN {
+            s.w[i] = a[i]
+        }
+        return s;
+    }
+
+    pub fn new_copy(y: &BIG) -> BIG {
+        let mut s = BIG::new();
+        for i in 0..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..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..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[NLEN - 1] ^= x;
+    }
+
+    pub fn ortop(&mut self, x: Chunk) {
+        self.w[NLEN - 1] |= x;
+    }
+
+    /* test for zero */
+    pub fn iszilch(&self) -> bool {
+        for i in 0..NLEN {
+            if self.w[i] != 0 {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* set to zero */
+    pub fn zero(&mut self) {
+        for i in 0..NLEN {
+            self.w[i] = 0
+        }
+    }
+
+    /* Test for equal to one */
+    pub fn isunity(&self) -> bool {
+        for i in 1..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..NLEN {
+            self.w[i] = 0;
+        }
+    }
+
+    /* Copy from another BIG */
+    pub fn copy(&mut self, x: &BIG) {
+        for i in 0..NLEN {
+            self.w[i] = x.w[i]
+        }
+    }
+
+    pub fn dcopy(&mut self, x: &DBIG) {
+        for i in 0..NLEN {
+            self.w[i] = x.w[i]
+        }
+    }
+
+    /* Get top and bottom half of =x*y+c+r */
+    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 & (BMASK as DChunk)) as Chunk;
+        let top = (prod >> BASEBITS) as Chunk;
+        return (top, bot);
+    }
+
+    /* normalise BIG - force all digits < 2^BASEBITS */
+    pub fn norm(&mut self) -> Chunk {
+        let mut carry = 0 as Chunk;
+        for i in 0..NLEN - 1 {
+            let d = self.w[i] + carry;
+            self.w[i] = d & BMASK;
+            carry = d >> BASEBITS;
+        }
+        self.w[NLEN - 1] += carry;
+        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % 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..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..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..NLEN - 1 {
+            self.w[i] = (self.w[i] >> k) | ((self.w[i + 1] << (BASEBITS - n)) & BMASK);
+        }
+        self.w[NLEN - 1] = self.w[NLEN - 1] >> k;
+        return w as isize;
+    }
+
+    /* general shift right */
+    pub fn shr(&mut self, k: usize) {
+        let n = k % BASEBITS;
+        let m = k / BASEBITS;
+        for i in 0..NLEN - m - 1 {
+            self.w[i] = (self.w[m + i] >> n) | ((self.w[m + i + 1] << (BASEBITS - n)) & BMASK)
+        }
+        self.w[NLEN - m - 1] = self.w[NLEN - 1] >> n;
+        for i in NLEN - m..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[NLEN - 1] = (self.w[NLEN - 1] << n) | (self.w[NLEN - 2] >> (BASEBITS - n));
+        for i in (1..NLEN - 1).rev() {
+            self.w[i] = ((self.w[i] << k) & BMASK) | (self.w[i - 1] >> (BASEBITS - n));
+        }
+        self.w[0] = (self.w[0] << n) & BMASK;
+        return (self.w[NLEN - 1] >> ((8 * MODBYTES) % BASEBITS)) as isize; /* return excess - only used in ff.c */
+    }
+
+    /* general shift left */
+    pub fn shl(&mut self, k: usize) {
+        let n = k % BASEBITS;
+        let m = k / BASEBITS;
+
+        self.w[NLEN - 1] = self.w[NLEN - 1 - m] << n;
+        if NLEN >= m + 2 {
+            self.w[NLEN - 1] |= self.w[NLEN - m - 2] >> (BASEBITS - n)
+        }
+        for i in (m + 1..NLEN - 1).rev() {
+            self.w[i] = ((self.w[i - m] << n) & BMASK) | (self.w[i - m - 1] >> (BASEBITS - n));
+        }
+        self.w[m] = (self.w[0] << n) & BMASK;
+        for i in 0..m {
+            self.w[i] = 0
+        }
+    }
+
+    /* return number of bits */
+    pub fn nbits(&self) -> usize {
+        let mut k = NLEN - 1;
+        let mut s = BIG::new_copy(&self);
+        s.norm();
+        while (k as isize) >= 0 && s.w[k] == 0 {
+            k = k.wrapping_sub(1)
+        }
+        if (k as isize) < 0 {
+            return 0;
+        }
+        let mut bts = BASEBITS * k;
+        let mut c = s.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 = (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 fromstring(val: String) -> BIG {
+        let mut res = BIG::new();
+        let len = val.len();
+        let op = &val[0..1];
+        let n = u8::from_str_radix(op, 16).unwrap();
+        res.w[0] += n as Chunk;
+        for i in 1..len {
+            res.shl(4);
+            let op = &val[i..i+1];
+            let n = u8::from_str_radix(op, 16).unwrap();
+            res.w[0] += n as Chunk;
+        }
+        return res;
+    }
+
+    pub fn from_hex(val: String) -> BIG {
+        BIG::fromstring(val)
+    }
+    
+    pub fn to_hex(&mut self) -> String {
+        self.tostring()
+    }
+
+    pub fn add(&mut self, r: &BIG) {
+        for i in 0..NLEN {
+            self.w[i] += r.w[i]
+        }
+    }
+
+    pub fn or(&mut self, r: &BIG) {
+        for i in 0..NLEN {
+            self.w[i] |= r.w[i]
+        }
+    }
+
+    pub fn dbl(&mut self) {
+        for i in 0..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..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;
+    }
+
+    /* return self-x */
+    pub fn minus(&self, x: &BIG) -> BIG {
+        let mut d = BIG::new();
+        for i in 0..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..NLEN {
+            self.w[i] -= x.w[i];
+        }
+    }
+
+    /* reverse subtract this=x-this */
+
+    pub fn rsub(&mut self, x: &BIG) {
+        for i in 0..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..NLEN {
+            self.w[i] *= c as Chunk;
+        }
+    }
+
+    /* convert this BIG to byte array */
+    pub fn tobytearray(&mut self, b: &mut [u8], n: usize) {
+        let mut c = BIG::new_copy(self);
+        c.norm();
+
+        for i in (0..(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..(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);
+    }
+
+    /* self*=x, where x is >NEXCESS */
+    pub fn pmul(&mut self, c: isize) -> Chunk {
+        let mut carry = 0 as Chunk;
+        for i in 0..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..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[NLEN] = carry;
+        return m;
+    }
+
+    /* divide by 3 */
+    pub fn div3(&mut self) -> Chunk {
+        let mut carry = 0 as Chunk;
+        self.norm();
+        let base = 1 << BASEBITS;
+        for i in (0..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..NLEN {
+            let mut carry = 0 as Chunk;
+            for j in 0..NLEN {
+                if i + j < 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..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 / BASEBITS;
+        let bt = m % BASEBITS;
+        let msk = (1 << bt) - 1;
+        self.w[wd] &= msk;
+        for i in wd + 1..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 / (BASEBITS as usize)] & (1 << (n % 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 < BIGBITS {
+            u.norm();
+            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);
+            t1.norm();
+            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(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[NLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize,
+            );
+            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[NLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
+            b.cmove(&r, d);
+            r.copy(self);
+            r.add(&e);
+            r.norm();
+            self.cmove(&r, d);
+            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 * (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;
+            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;
+        let t = BIG::new_copy(q);
+        for _ in 0..2 * t.nbits() {
+            if j == 0 {
+                r = rng.getbyte();
+            } else {
+                r >>= 1
+            }
+
+            let b = (r as Chunk) & 1;
+            d.shl(1);
+            d.w[0] += 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.fshr(1);
+                if x1.parity() != 0 {
+                    x1.add(p);
+                    x1.norm();
+                }
+                x1.fshr(1);
+            }
+            while v.parity() == 0 {
+                v.fshr(1);
+                if x2.parity() != 0 {
+                    x2.add(p);
+                    x2.norm();
+                }
+                x2.fshr(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 */
+
+    pub fn mul(a: &BIG, b: &BIG) -> DBIG {
+        let mut c = DBIG::new();
+        let rm = BMASK as DChunk;
+        let rb = BASEBITS;
+
+        let mut d: [DChunk; DNLEN] = [0; DNLEN];
+        for i in 0..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..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 NLEN..2 * NLEN - 1 {
+            s -= d[k - NLEN];
+            t = co + s;
+            let mut i = 1 + k / 2;
+            while i < 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 * NLEN - 1] = co as Chunk;
+        return c;
+    }
+
+    /* return a^2 as DBIG */
+    pub fn sqr(a: &BIG) -> DBIG {
+        let mut c = DBIG::new();
+        let rm = BMASK as DChunk;
+        let rb = BASEBITS;
+
+        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;
+
+        let mut j = 1;
+        while j < NLEN - 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;
+            c.w[j] = (t & rm) as Chunk;
+            co = t >> rb;
+            j += 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;
+        }
+
+        j = NLEN + (NLEN % 2) - 1;
+        while j < DNLEN - 3 {
+            t = (a.w[NLEN - 1] as DChunk) * (a.w[j + 1 - NLEN] as DChunk);
+            for i in j + 2 - NLEN..(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;
+            t = (a.w[NLEN - 1] as DChunk) * (a.w[j + 1 - NLEN] as DChunk);
+            for i in j + 2 - NLEN..(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[NLEN - 2] as DChunk) * (a.w[NLEN - 1] as DChunk);
+        t += t;
+        t += co;
+        c.w[DNLEN - 3] = (t & rm) as Chunk;
+        co = t >> rb;
+
+        t = (a.w[NLEN - 1] as DChunk) * (a.w[NLEN - 1] as DChunk) + co;
+        c.w[DNLEN - 2] = (t & rm) as Chunk;
+        co = t >> rb;
+        c.w[DNLEN - 1] = co as Chunk;
+
+        return c;
+    }
+
+    pub fn monty(md: &BIG, mc: Chunk, d: &mut DBIG) -> BIG {
+        let mut b = BIG::new();
+        let rm = BMASK as DChunk;
+        let rb = BASEBITS;
+
+        let mut dd: [DChunk; NLEN] = [0; NLEN];
+        let mut v: [Chunk; NLEN] = [0; NLEN];
+
+        b.zero();
+
+        let mut t = d.w[0] as DChunk;
+        v[0] = (((t & rm) as Chunk).wrapping_mul(mc)) & 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..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(mc)) & 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 NLEN..2 * NLEN - 1 {
+            t = c + s;
+            let mut i = 1 + k / 2;
+            while i < NLEN {
+                t += ((v[k - i] - v[i]) as DChunk) * ((md.w[i] - md.w[k - i]) as DChunk);
+                i += 1;
+            }
+            b.w[k - NLEN] = (t & rm) as Chunk;
+            c = (d.w[k + 1] as DChunk) + (t >> rb);
+            s -= dd[k + 1 - NLEN];
+        }
+        b.w[NLEN - 1] = (c & rm) as Chunk;
+        return b;
+    }
+
+    pub fn ssn(r: &mut BIG, a: &BIG, m: &mut BIG) -> isize {
+        let n = NLEN - 1;
+        m.w[0] = (m.w[0] >> 1) | ((m.w[1] << (BASEBITS - 1)) & BMASK);
+        r.w[0] = a.w[0] - m.w[0];
+        let mut carry = r.w[0] >> BASEBITS;
+        r.w[0] &= BMASK;
+        for i in 1..n {
+            m.w[i] = (m.w[i] >> 1) | ((m.w[i + 1] << (BASEBITS - 1)) & BMASK);
+            r.w[i] = a.w[i] - m.w[i] + carry;
+            carry = r.w[i] >> BASEBITS;
+            r.w[i] &= BMASK;
+        }
+        m.w[n] >>= 1;
+        r.w[n] = a.w[n] - m.w[n] + carry;
+        return ((r.w[n] >> (arch::CHUNK - 1)) & 1) as isize;
+    }
+
+    /* return a*b mod m */
+    pub fn modmul(a1: &BIG, b1: &BIG, m: &BIG) -> BIG {
+        let mut a = BIG::new_copy(a1);
+        let mut b = BIG::new_copy(b1);
+        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(a1: &BIG, m: &BIG) -> BIG {
+        let mut a = BIG::new_copy(a1);
+        a.rmod(m);
+        let mut d = BIG::sqr(&a);
+        return d.dmod(m);
+    }
+
+    /* return -a mod m */
+    pub fn modneg(a1: &BIG, m: &BIG) -> BIG {
+        let mut a = BIG::new_copy(a1);
+        a.rmod(m);
+        return m.minus(&a);
+    }
+
+    /* return this^e mod m */
+    pub fn powmod(&mut self, e1: &BIG, m: &BIG) -> BIG {
+        self.norm();
+        let mut e = BIG::new_copy(e1);
+        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(&a, &s, m)
+            }
+            if z.iszilch() {
+                break;
+            }
+            s = BIG::modsqr(&mut s, m);
+        }
+        return a;
+    }
+}
diff --git a/src/bls.rs b/src/bls.rs
new file mode 100644
index 0000000..7e7fd7a
--- /dev/null
+++ b/src/bls.rs
@@ -0,0 +1,96 @@
+/*
+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::str;
+use super::ecp::ECP;
+use super::ecp2::ECP2;
+//use super::fp12::FP12;
+use super::big::BIG;
+use super::pair;
+use super::big;
+use super::rom;
+
+use rand::RAND;
+use sha3::SHA3;
+use sha3::SHAKE256;
+
+/* BLS API Functions */
+
+pub const BFS: usize = big::MODBYTES as usize;
+pub const BGS: usize = big::MODBYTES as usize;
+pub const BLS_OK: isize = 0;
+pub const BLS_FAIL: isize = -1;
+
+/* hash a message to an ECP point, using SHA3 */
+
+#[allow(non_snake_case)]
+fn bls_hashit(m: &str) -> ECP {
+    let mut sh = SHA3::new(SHAKE256);
+    let mut hm: [u8; BFS] = [0; BFS];
+    let t = m.as_bytes();
+    for i in 0..m.len() {
+        sh.process(t[i]);
+    }
+    sh.shake(&mut hm, BFS);
+    let P = ECP::mapit(&hm);
+    return P;
+}
+
+/* generate key pair, private key s, public key w */
+pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
+    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let g = ECP2::generator();
+    let mut sc = BIG::randomnum(&q, &mut rng);
+    sc.tobytes(s);
+    pair::g2mul(&g, &mut sc).tobytes(w);
+    return BLS_OK;
+}
+
+/* Sign message m using private key s to produce signature sig */
+
+pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
+    let d = bls_hashit(m);
+    let mut sc = BIG::frombytes(&s);
+    pair::g1mul(&d, &mut sc).tobytes(sig, true);
+    return BLS_OK;
+}
+
+/* Verify signature given message m, the signature sig, and the public key w */
+
+pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
+    let hm = bls_hashit(m);
+    let mut d = ECP::frombytes(&sig);
+    let g = ECP2::generator();
+    let pk = ECP2::frombytes(&w);
+    d.neg();
+
+// Use new multi-pairing mechanism 
+    let mut r=pair::initmp();
+    pair::another(&mut r,&g,&d);
+    pair::another(&mut r,&pk,&hm);
+    let mut v=pair::miller(&r);
+
+//.. or alternatively
+//    let mut v = pair::ate2(&g, &d, &pk, &hm);
+
+    v = pair::fexp(&v);
+    if v.isunity() {
+        return BLS_OK;
+    }
+    return BLS_FAIL;
+}
diff --git a/src/bls192.rs b/src/bls192.rs
new file mode 100644
index 0000000..20ee92e
--- /dev/null
+++ b/src/bls192.rs
@@ -0,0 +1,96 @@
+/*
+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::str;
+use super::ecp::ECP;
+use super::ecp4::ECP4;
+//use super::fp24::FP24;
+use super::big::BIG;
+use super::pair192;
+use super::big;
+use super::rom;
+
+use rand::RAND;
+use sha3::SHA3;
+use sha3::SHAKE256;
+
+/* BLS API Functions */
+
+pub const BFS: usize = big::MODBYTES as usize;
+pub const BGS: usize = big::MODBYTES as usize;
+pub const BLS_OK: isize = 0;
+pub const BLS_FAIL: isize = -1;
+
+/* hash a message to an ECP point, using SHA3 */
+
+#[allow(non_snake_case)]
+fn bls_hashit(m: &str) -> ECP {
+    let mut sh = SHA3::new(SHAKE256);
+    let mut hm: [u8; BFS] = [0; BFS];
+    let t = m.as_bytes();
+    for i in 0..m.len() {
+        sh.process(t[i]);
+    }
+    sh.shake(&mut hm, BFS);
+    let P = ECP::mapit(&hm);
+    return P;
+}
+
+/* generate key pair, private key s, public key w */
+pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
+    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let g = ECP4::generator();
+    let mut sc = BIG::randomnum(&q, &mut rng);
+    sc.tobytes(s);
+    pair192::g2mul(&g, &mut sc).tobytes(w);
+    return BLS_OK;
+}
+
+/* Sign message m using private key s to produce signature sig */
+
+pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
+    let d = bls_hashit(m);
+    let mut sc = BIG::frombytes(&s);
+    pair192::g1mul(&d, &mut sc).tobytes(sig, true);
+    return BLS_OK;
+}
+
+/* Verify signature given message m, the signature sig, and the public key w */
+
+pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
+    let hm = bls_hashit(m);
+    let mut d = ECP::frombytes(&sig);
+    let g = ECP4::generator();
+    let pk = ECP4::frombytes(&w);
+    d.neg();
+
+// Use new multi-pairing mechanism 
+    let mut r=pair192::initmp();
+    pair192::another(&mut r,&g,&d);
+    pair192::another(&mut r,&pk,&hm);
+    let mut v=pair192::miller(&r);
+
+//.. or alternatively
+//    let mut v = pair192::ate2(&g, &d, &pk, &hm);
+    
+    v = pair192::fexp(&v);
+    if v.isunity() {
+        return BLS_OK;
+    }
+    return BLS_FAIL;
+}
diff --git a/src/bls256.rs b/src/bls256.rs
new file mode 100644
index 0000000..cdb553d
--- /dev/null
+++ b/src/bls256.rs
@@ -0,0 +1,96 @@
+/*
+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::str;
+use super::ecp::ECP;
+use super::ecp8::ECP8;
+//use super::fp48::FP48;
+use super::big::BIG;
+use super::pair256;
+use super::big;
+use super::rom;
+
+use rand::RAND;
+use sha3::SHA3;
+use sha3::SHAKE256;
+
+/* BLS API Functions */
+
+pub const BFS: usize = big::MODBYTES as usize;
+pub const BGS: usize = big::MODBYTES as usize;
+pub const BLS_OK: isize = 0;
+pub const BLS_FAIL: isize = -1;
+
+/* hash a message to an ECP point, using SHA3 */
+
+#[allow(non_snake_case)]
+fn bls_hashit(m: &str) -> ECP {
+    let mut sh = SHA3::new(SHAKE256);
+    let mut hm: [u8; BFS] = [0; BFS];
+    let t = m.as_bytes();
+    for i in 0..m.len() {
+        sh.process(t[i]);
+    }
+    sh.shake(&mut hm, BFS);
+    let P = ECP::mapit(&hm);
+    return P;
+}
+
+/* generate key pair, private key s, public key w */
+pub fn key_pair_generate(mut rng: &mut RAND, s: &mut [u8], w: &mut [u8]) -> isize {
+    let q = BIG::new_ints(&rom::CURVE_ORDER);
+    let g = ECP8::generator();
+    let mut sc = BIG::randomnum(&q, &mut rng);
+    sc.tobytes(s);
+    pair256::g2mul(&g, &mut sc).tobytes(w);
+    return BLS_OK;
+}
+
+/* Sign message m using private key s to produce signature sig */
+
+pub fn sign(sig: &mut [u8], m: &str, s: &[u8]) -> isize {
+    let d = bls_hashit(m);
+    let mut sc = BIG::frombytes(&s);
+    pair256::g1mul(&d, &mut sc).tobytes(sig, true);
+    return BLS_OK;
+}
+
+/* Verify signature given message m, the signature sig, and the public key w */
+
+pub fn verify(sig: &[u8], m: &str, w: &[u8]) -> isize {
+    let hm = bls_hashit(m);
+    let mut d = ECP::frombytes(&sig);
+    let g = ECP8::generator();
+    let pk = ECP8::frombytes(&w);
+    d.neg();
+
+// Use new multi-pairing mechanism 
+    let mut r=pair256::initmp();
+    pair256::another(&mut r,&g,&d);
+    pair256::another(&mut r,&pk,&hm);
+    let mut v=pair256::miller(&r);
+
+//.. or alternatively
+//    let mut v = pair256::ate2(&g, &d, &pk, &hm);
+
+    v = pair256::fexp(&v);
+    if v.isunity() {
+        return BLS_OK;
+    }
+    return BLS_FAIL;
+}
diff --git a/src/dbig.rs b/src/dbig.rs
new file mode 100644
index 0000000..353443a
--- /dev/null
+++ b/src/dbig.rs
@@ -0,0 +1,301 @@
+/*
+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 super::super::arch;
+use super::big;
+use super::big::BIG;
+use super::super::arch::Chunk;
+
+#[derive(Copy)]
+pub struct DBIG {
+    pub w: [Chunk; big::DNLEN],
+}
+
+impl Clone for DBIG {
+    fn clone(&self) -> DBIG { *self }
+}
+
+impl DBIG {
+    pub fn new() -> DBIG {
+        DBIG {
+            w: [0; big::DNLEN as usize],
+        }
+    }
+
+    pub fn new_copy(y: &DBIG) -> DBIG {
+        let mut s = DBIG::new();
+        for i in 0..big::DNLEN {
+            s.w[i] = y.w[i]
+        }
+        return s;
+    }
+
+    pub fn new_scopy(x: &BIG) -> DBIG {
+        let mut b = DBIG::new();
+        for i in 0..big::NLEN {
+            b.w[i] = x.w[i];
+        }
+        b.w[big::NLEN - 1] = x.get(big::NLEN - 1) & big::BMASK; /* top word normalized */
+        b.w[big::NLEN] = x.get(big::NLEN - 1) >> big::BASEBITS;
+
+        for i in big::NLEN + 1..big::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 % big::BASEBITS;
+        let mut carry = self.w[big::DNLEN - 1] << (big::BASEBITS - m);
+
+        for i in (big::NLEN - 1..big::DNLEN - 1).rev() {
+            let nw = (self.w[i] >> m) | carry;
+            carry = (self.w[i] << (big::BASEBITS - m)) & big::BMASK;
+            t.set(i + 1 - big::NLEN, nw);
+        }
+        self.w[big::NLEN - 1] &= ((1 as Chunk) << m) - 1;
+        return t;
+    }
+
+    /* general shift left */
+    pub fn shl(&mut self, k: usize) {
+        let n = k % big::BASEBITS;
+        let m = k / big::BASEBITS;
+        self.w[big::DNLEN - 1] =
+            (self.w[big::DNLEN - 1 - m] << n) | (self.w[big::DNLEN - m - 2] >> (big::BASEBITS - n));
+        for i in (m + 1..big::DNLEN - 1).rev() {
+            self.w[i] =
+                ((self.w[i - m] << n) & big::BMASK) | (self.w[i - m - 1] >> (big::BASEBITS - n));
+        }
+
+        self.w[m] = (self.w[0] << n) & big::BMASK;
+        for i in 0..m {
+            self.w[i] = 0
+        }
+    }
+
+    /* general shift right */
+    pub fn shr(&mut self, k: usize) {
+        let n = k % big::BASEBITS;
+        let m = k / big::BASEBITS;
+        for i in 0..big::DNLEN - m - 1 {
+            self.w[i] =
+                (self.w[m + i] >> n) | ((self.w[m + i + 1] << (big::BASEBITS - n)) & big::BMASK);
+        }
+        self.w[big::DNLEN - m - 1] = self.w[big::DNLEN - 1] >> n;
+        for i in big::DNLEN - m..big::DNLEN {
+            self.w[i] = 0
+        }
+    }
+
+    /* Copy from another DBIG */
+    pub fn copy(&mut self, x: &DBIG) {
+        for i in 0..big::DNLEN {
+            self.w[i] = x.w[i];
+        }
+    }
+
+    pub fn ucopy(&mut self, x: &BIG) {
+        for i in 0..big::NLEN {
+            self.w[i] = 0;
+        }
+        for i in big::NLEN..big::DNLEN {
+            self.w[i] = x.w[i - big::NLEN];
+        }
+    }
+
+    pub fn cmove(&mut self, g: &DBIG, d: isize) {
+        let b = -d as Chunk;
+        for i in 0..big::DNLEN {
+            self.w[i] ^= (self.w[i] ^ g.w[i]) & b;
+        }
+    }
+
+    /* self+=x */
+    pub fn add(&mut self, x: &DBIG) {
+        for i in 0..big::DNLEN {
+            self.w[i] += x.w[i];
+        }
+    }
+
+    /* self-=x */
+    pub fn sub(&mut self, x: &DBIG) {
+        for i in 0..big::DNLEN {
+            self.w[i] -= x.w[i];
+        }
+    }
+
+    /* self=x-self */
+    pub fn rsub(&mut self, x: &DBIG) {
+        for i in 0..big::DNLEN {
+            self.w[i] = x.w[i] - self.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..big::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^big::BASEBITS */
+    pub fn norm(&mut self) {
+        let mut carry = 0 as Chunk;
+        for i in 0..big::DNLEN - 1 {
+            let d = self.w[i] + carry;
+            self.w[i] = d & big::BMASK;
+            carry = d >> big::BASEBITS;
+        }
+        self.w[big::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[big::DNLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize,
+            );
+
+            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[big::DNLEN - 1] >> (arch::CHUNK - 1)) & 1)) as isize;
+            self.cmove(&dr, d);
+            r.copy(&a);
+            r.add(&e);
+            r.norm();
+            a.cmove(&r, d);
+
+            k -= 1;
+        }
+        return a;
+    }
+
+    /* set x = x mod 2^m */
+    pub fn mod2m(&mut self, m: usize) {
+        let wd = m / big::BASEBITS;
+        let bt = m % big::BASEBITS;
+        let msk = (1 << bt) - 1;
+        self.w[wd] &= msk;
+        for i in wd + 1..big::DNLEN {
+            self.w[i] = 0
+        }
+    }
+
+    /* return number of bits */
+    pub fn nbits(&mut self) -> usize {
+        let mut k = big::DNLEN - 1;
+        let mut s = DBIG::new_copy(&self);
+        s.norm();
+        while (k as isize) >= 0 && s.w[k] == 0 {
+            k = k.wrapping_sub(1)
+        }
+        if (k as isize) < 0 {
+            return 0;
+        }
+        let mut bts = (big::BASEBITS as usize) * k;
+        let mut c = s.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;
+    }
+}
diff --git a/src/ecdh.rs b/src/ecdh.rs
new file mode 100644
index 0000000..9b49e18
--- /dev/null
+++ b/src/ecdh.rs
@@ -0,0 +1,744 @@
+/*
+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 super::ecp;
+use super::ecp::ECP;
+use super::big::BIG;
+use super::rom;
+use super::big;
+
+use rand::RAND;
+use hash256::HASH256;
+use hash384::HASH384;
+use hash512::HASH512;
+use aes;
+use aes::AES;
+
+
+pub const INVALID_PUBLIC_KEY: isize = -2;
+pub const ERROR: isize = -3;
+pub const INVALID: isize = -4;
+pub const EFS: usize = big::MODBYTES as usize;
+pub const EGS: usize = big::MODBYTES as usize;
+pub const SHA256: usize = 32;
+pub const SHA384: usize = 48;
+pub const SHA512: usize = 64;
+
+#[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 + pad - sha] = r[i]
+            }
+            for i in 0..(pad - sha) {
+                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];
+
+    if olen < 4 {
+        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 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]);
+        }
+    }
+
+    /* 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]);
+    }
+    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 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]);
+        }
+    }
+
+    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 i in 0..16 - padlen {
+            m.push(buff[i]);
+        }
+    }
+
+    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 G = ECP::generator();
+
+    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);
+    }
+
+    sc.tobytes(s);
+
+    let WP = G.mul(&mut sc);
+
+    WP.tobytes(w, false); // To use point compression on public keys, change to true
+
+    return res;
+}
+
+/* validate public key */
+#[allow(non_snake_case)]
+pub fn public_key_validate(w: &[u8]) -> isize {
+    let mut WP = ECP::frombytes(w);
+    let mut res = 0;
+
+    let r = BIG::new_ints(&rom::CURVE_ORDER);
+
+    if WP.is_infinity() {
+        res = INVALID_PUBLIC_KEY
+    }
+    if res == 0 {
+        let q = BIG::new_ints(&rom::MODULUS);
+        let nb = q.nbits();
+        let mut k = BIG::new();
+        k.one();
+        k.shl((nb + 4) / 2);
+        k.add(&q);
+        k.div(&r);
+
+        while k.parity() == 0 {
+            k.shr(1);
+            WP.dbl();
+        }
+
+        if !k.isunity() {
+            WP = WP.mul(&mut k)
+        }
+        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; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+
+    hashit(sha, f, 0, None, big::MODBYTES as usize, &mut b);
+
+    let G = ECP::generator();
+
+    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); /* side channel masking */
+
+        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; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+
+    hashit(sha, f, 0, None, big::MODBYTES as usize, &mut b);
+
+    let mut G = ECP::generator();
+
+    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 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; ecp::AESKEY] = [0; ecp::AESKEY];
+    let mut k2: [u8; ecp::AESKEY] = [0; ecp::AESKEY];
+    let mut u: [u8; EGS] = [0; EGS];
+    let mut vz: [u8; 3 * EFS + 1] = [0; 3 * EFS + 1];
+    let mut k: [u8; 2 * ecp::AESKEY] = [0; 2 * ecp::AESKEY];
+
+    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), 2 * ecp::AESKEY, &mut k);
+
+    for i in 0..ecp::AESKEY {
+        k1[i] = k[i];
+        k2[i] = k[ecp::AESKEY + 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);
+}
+
+/* constant time n-byte compare */
+fn ncomp(t1: &[u8], t2: &[u8], n: usize) -> bool {
+    let mut res = 0;
+    for i in 0..n {
+        res |= (t1[i] ^ t2[i]) as isize;
+    }
+    if res == 0 {
+        return true;
+    }
+    return false;
+}
+
+/* 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; ecp::AESKEY] = [0; ecp::AESKEY];
+    let mut k2: [u8; ecp::AESKEY] = [0; ecp::AESKEY];
+    let mut vz: [u8; 3 * EFS + 1] = [0; 3 * EFS + 1];
+    let mut k: [u8; 2 * ecp::AESKEY] = [0; 2 * ecp::AESKEY];
+
+    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), 2 * ecp::AESKEY, &mut k);
+
+    for i in 0..ecp::AESKEY {
+        k1[i] = k[i];
+        k2[i] = k[ecp::AESKEY + 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();
+    }
+
+    if !ncomp(&t, &tag, t.len()) {
+        return None;
+    }
+
+    return m;
+}
diff --git a/src/ecp.rs b/src/ecp.rs
new file mode 100644
index 0000000..9e7b29c
--- /dev/null
+++ b/src/ecp.rs
@@ -0,0 +1,1261 @@
+/*
+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 super::fp::FP;
+use super::big::BIG;
+use super::big;
+use super::rom;
+
+pub use super::rom::{CURVETYPE, CURVE_PAIRING_TYPE, SEXTIC_TWIST, SIGN_OF_X, HASH_TYPE, AESKEY};
+pub use types::CurveType;
+use std::str::SplitWhitespace;
+use std::fmt;
+
+#[derive(Copy, Clone)]
+pub struct ECP {
+    x: FP,
+    y: FP,
+    z: FP,
+}
+
+impl PartialEq for ECP {
+    fn eq(&self, other: &ECP) -> bool {
+        self.equals(other)
+    }
+}
+
+impl fmt::Display for ECP {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+	}
+}
+
+impl fmt::Debug for ECP {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "ECP: [ {}, {}, {} ]", self.x, self.y, self.z)
+	}
+}
+
+#[allow(non_snake_case)]
+impl ECP {
+    pub fn pnew() -> ECP {
+        ECP {
+            x: FP::new(),
+            y: FP::new_int(1),
+            z: FP::new(),
+        }
+    }
+
+    pub fn new() -> ECP {
+        let mut E = ECP::pnew();
+        if CURVETYPE == CurveType::EDWARDS {
+            E.z.one();
+        }
+        return E;
+    }
+
+    /* 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();
+        E.x.norm();
+        let mut rhs = ECP::rhs(&E.x);
+        if CURVETYPE == CurveType::MONTGOMERY {
+            if rhs.jacobi() != 1 {
+                E.inf();
+            }
+        } else {
+            let mut y2 = FP::new_copy(&E.y);
+            y2.sqr();
+            if !y2.equals(&mut rhs) {
+                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.x.norm();
+        E.z.one();
+
+        let mut rhs = ECP::rhs(&E.x);
+
+        if rhs.jacobi() == 1 {
+            let mut ny = rhs.sqrt();
+            if ny.redc().parity() != s {
+                ny.neg()
+            }
+            E.y.copy(&ny);
+        } 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.x.norm();
+        E.z.one();
+        let mut rhs = ECP::rhs(&E.x);
+        if rhs.jacobi() == 1 {
+            if CURVETYPE != CurveType::MONTGOMERY {
+                E.y.copy(&rhs.sqrt())
+            }
+        } else {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* set this=O */
+    pub fn inf(&mut self) {
+        self.x.zero();
+        if CURVETYPE != CurveType::MONTGOMERY {
+            self.y.one();
+        }
+        if CURVETYPE != CurveType::EDWARDS {
+            self.z.zero();
+        } else {
+            self.z.one()
+        }
+    }
+
+    /* Calculate RHS of curve equation */
+    fn rhs(x: &FP) -> FP {
+        let mut r = FP::new_copy(x);
+        r.sqr();
+
+        if CURVETYPE == CurveType::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 CURVETYPE == CurveType::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(&r);
+            b.sub(&one);
+            b.norm();
+            if rom::CURVE_A == -1 {
+                r.neg()
+            }
+            r.sub(&one);
+            r.norm();
+            b.inverse();
+            r.mul(&b);
+        }
+        if CURVETYPE == CurveType::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(&self) -> bool {
+        match CURVETYPE {
+            CurveType::EDWARDS=> self.x.iszilch() && self.y.equals(&self.z),
+            CurveType::WEIERSTRASS => self.x.iszilch() && self.z.iszilch(),
+            CurveType::MONTGOMERY => self.z.iszilch(),
+        }
+    }
+
+    /* 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 CURVETYPE != CurveType::MONTGOMERY {
+            self.y.cswap(&mut Q.y, d)
+        }
+        self.z.cswap(&mut Q.z, d);
+    }
+
+    /* 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 CURVETYPE != CurveType::MONTGOMERY {
+            self.y.cmove(&Q.y, d)
+        }
+        self.z.cmove(&Q.z, d);
+    }
+
+    /* 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 CURVETYPE != CurveType::MONTGOMERY {
+            self.y.copy(&P.y)
+        }
+        self.z.copy(&P.z);
+    }
+
+    /* this=-this */
+    pub fn neg(&mut self) {
+        if CURVETYPE == CurveType::WEIERSTRASS {
+            self.y.neg();
+            self.y.norm();
+        }
+        if CURVETYPE == CurveType::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(&self, Q: &ECP) -> bool {
+        let mut a = FP::new();
+        let mut b = FP::new();
+        a.copy(&self.x);
+        a.mul(&Q.z);
+        b.copy(&Q.x);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+        if CURVETYPE != CurveType::MONTGOMERY {
+            a.copy(&self.y);
+            a.mul(&Q.z);
+            b.copy(&Q.y);
+            b.mul(&self.z);
+            if !a.equals(&mut b) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* set to affine - 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();
+
+        self.x.mul(&self.z);
+        self.x.reduce();
+        if CURVETYPE != CurveType::MONTGOMERY {
+            self.y.mul(&self.z);
+            self.y.reduce();
+        }
+        self.z.copy(&one);
+    }
+
+    /* extract x as a BIG */
+    pub fn getx(&self) -> BIG {
+        let mut W = ECP::new();
+        W.copy(self);
+        W.affine();
+        return W.x.redc();
+    }
+
+    /* extract y as a BIG */
+    pub fn gety(&self) -> BIG {
+        let mut W = ECP::new();
+        W.copy(self);
+        W.affine();
+        return W.y.redc();
+    }
+
+    /* get sign of Y */
+    pub fn gets(&self) -> isize {
+        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(&self, b: &mut [u8], compress: bool) {
+        let mb = big::MODBYTES as usize;
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mut W = ECP::new();
+        W.copy(self);
+
+        W.affine();
+        W.x.redc().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 1] = t[i]
+        }
+
+        if CURVETYPE == CurveType::MONTGOMERY {
+            b[0] = 0x06;
+            return;
+        }
+
+        if compress {
+            b[0] = 0x02;
+            if W.y.redc().parity() == 1 {
+                b[0] = 0x03
+            }
+            return;
+        }
+
+        b[0] = 0x04;
+
+        W.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; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::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 CURVETYPE == CurveType::MONTGOMERY {
+            return ECP::new_big(&px);
+        }
+
+        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);
+        }
+
+        if b[0] == 0x02 || b[0] == 0x03 {
+            return ECP::new_bigint(&px, (b[0] & 1) as isize);
+        }
+
+        return ECP::new();
+    }
+
+    /* convert to hex string */
+    pub fn tostring(&self) -> String {
+        let mut W = ECP::new();
+        W.copy(self);
+        if W.is_infinity() {
+            return String::from("infinity");
+        }
+        if CURVETYPE == CurveType::MONTGOMERY {
+            return format!("({})", W.x.redc().tostring());
+        } else {
+            return format!("({},{})", W.x.redc().tostring(), W.y.redc().tostring());
+        };
+    }
+
+    pub fn to_hex(&self) -> String {
+        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+    }
+
+    pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP {
+        ECP {
+            x: FP::from_hex_iter(iter),
+            y: FP::from_hex_iter(iter),
+            z: FP::from_hex_iter(iter),
+        }
+    }
+
+    pub fn from_hex(val: String) -> ECP {
+        let mut iter = val.split_whitespace();
+        return ECP::from_hex_iter(&mut iter);
+    }
+
+    /* this*=2 */
+    pub fn dbl(&mut self) {
+        if CURVETYPE == CurveType::WEIERSTRASS {
+            if rom::CURVE_A == 0 {
+                let mut t0 = FP::new_copy(&self.y);
+                t0.sqr();
+                let mut t1 = FP::new_copy(&self.y);
+                t1.mul(&self.z);
+                let mut t2 = FP::new_copy(&self.z);
+                t2.sqr();
+
+                self.z.copy(&t0);
+                self.z.add(&t0);
+                self.z.norm();
+                self.z.dbl();
+                self.z.dbl();
+                self.z.norm();
+                t2.imul(3 * rom::CURVE_B_I);
+
+                let mut x3 = FP::new_copy(&t2);
+                x3.mul(&self.z);
+
+                let mut y3 = FP::new_copy(&t0);
+                y3.add(&t2);
+                y3.norm();
+                self.z.mul(&t1);
+                t1.copy(&t2);
+                t1.add(&t2);
+                t2.add(&t1);
+                t0.sub(&t2);
+                t0.norm();
+                y3.mul(&t0);
+                y3.add(&x3);
+                t1.copy(&self.x);
+                t1.mul(&self.y);
+                self.x.copy(&t0);
+                self.x.norm();
+                self.x.mul(&t1);
+                self.x.dbl();
+                self.x.norm();
+                self.y.copy(&y3);
+                self.y.norm();
+            } else {
+                let mut t0 = FP::new_copy(&self.x);
+                let mut t1 = FP::new_copy(&self.y);
+                let mut t2 = FP::new_copy(&self.z);
+                let mut t3 = FP::new_copy(&self.x);
+                let mut z3 = FP::new_copy(&self.z);
+                let mut y3 = FP::new();
+                let mut x3 = FP::new();
+                let mut b = FP::new();
+
+                if rom::CURVE_B_I == 0 {
+                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
+                }
+
+                t0.sqr(); //1    x^2
+                t1.sqr(); //2    y^2
+                t2.sqr(); //3
+
+                t3.mul(&self.y); //4
+                t3.dbl();
+                t3.norm(); //5
+                z3.mul(&self.x); //6
+                z3.dbl();
+                z3.norm(); //7
+                y3.copy(&t2);
+
+                if rom::CURVE_B_I == 0 {
+                    y3.mul(&b); //8
+                } else {
+                    y3.imul(rom::CURVE_B_I);
+                }
+
+                y3.sub(&z3); //9  ***
+                x3.copy(&y3);
+                x3.add(&y3);
+                x3.norm(); //10
+
+                y3.add(&x3); //11
+                x3.copy(&t1);
+                x3.sub(&y3);
+                x3.norm(); //12
+                y3.add(&t1);
+                y3.norm(); //13
+                y3.mul(&x3); //14
+                x3.mul(&t3); //15
+                t3.copy(&t2);
+                t3.add(&t2); //16
+                t2.add(&t3); //17
+
+                if rom::CURVE_B_I == 0 {
+                    z3.mul(&b); //18
+                } else {
+                    z3.imul(rom::CURVE_B_I);
+                }
+
+                z3.sub(&t2); //19
+                z3.sub(&t0);
+                z3.norm(); //20  ***
+                t3.copy(&z3);
+                t3.add(&z3); //21
+
+                z3.add(&t3);
+                z3.norm(); //22
+                t3.copy(&t0);
+                t3.add(&t0); //23
+                t0.add(&t3); //24
+                t0.sub(&t2);
+                t0.norm(); //25
+
+                t0.mul(&z3); //26
+                y3.add(&t0); //27
+                t0.copy(&self.y);
+                t0.mul(&self.z); //28
+                t0.dbl();
+                t0.norm(); //29
+                z3.mul(&t0); //30
+                x3.sub(&z3); //31
+                t0.dbl();
+                t0.norm(); //32
+                t1.dbl();
+                t1.norm(); //33
+                z3.copy(&t0);
+                z3.mul(&t1); //34
+
+                self.x.copy(&x3);
+                self.x.norm();
+                self.y.copy(&y3);
+                self.y.norm();
+                self.z.copy(&z3);
+                self.z.norm();
+            }
+        }
+        if CURVETYPE == CurveType::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(&self.y);
+            self.x.dbl();
+            self.x.norm();
+            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);
+            j.norm();
+            self.x.mul(&j);
+            c.sub(&d);
+            c.norm();
+            self.y.mul(&c);
+            self.z.mul(&j);
+        }
+        if CURVETYPE == CurveType::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();
+
+            a.add(&self.z);
+            a.norm();
+            aa.copy(&a);
+            aa.sqr();
+            b.sub(&self.z);
+            b.norm();
+            bb.copy(&b);
+            bb.sqr();
+            c.copy(&aa);
+            c.sub(&bb);
+            c.norm();
+
+            self.x.copy(&aa);
+            self.x.mul(&bb);
+
+            a.copy(&c);
+            a.imul((rom::CURVE_A + 2) / 4);
+
+            bb.add(&a);
+            bb.norm();
+            self.z.copy(&bb);
+            self.z.mul(&c);
+        }
+        return;
+    }
+
+    /* self+=Q */
+    pub fn add(&mut self, Q: &ECP) {
+        if CURVETYPE == CurveType::WEIERSTRASS {
+            if rom::CURVE_A == 0 {
+                let b = 3 * rom::CURVE_B_I;
+                let mut t0 = FP::new_copy(&self.x);
+                t0.mul(&Q.x);
+                let mut t1 = FP::new_copy(&self.y);
+                t1.mul(&Q.y);
+                let mut t2 = FP::new_copy(&self.z);
+                t2.mul(&Q.z);
+                let mut t3 = FP::new_copy(&self.x);
+                t3.add(&self.y);
+                t3.norm();
+                let mut t4 = FP::new_copy(&Q.x);
+                t4.add(&Q.y);
+                t4.norm();
+                t3.mul(&t4);
+                t4.copy(&t0);
+                t4.add(&t1);
+
+                t3.sub(&t4);
+                t3.norm();
+                t4.copy(&self.y);
+                t4.add(&self.z);
+                t4.norm();
+                let mut x3 = FP::new_copy(&Q.y);
+                x3.add(&Q.z);
+                x3.norm();
+
+                t4.mul(&x3);
+                x3.copy(&t1);
+                x3.add(&t2);
+
+                t4.sub(&x3);
+                t4.norm();
+                x3.copy(&self.x);
+                x3.add(&self.z);
+                x3.norm();
+                let mut y3 = FP::new_copy(&Q.x);
+                y3.add(&Q.z);
+                y3.norm();
+                x3.mul(&y3);
+                y3.copy(&t0);
+                y3.add(&t2);
+                y3.rsub(&x3);
+                y3.norm();
+                x3.copy(&t0);
+                x3.add(&t0);
+                t0.add(&x3);
+                t0.norm();
+                t2.imul(b);
+
+                let mut z3 = FP::new_copy(&t1);
+                z3.add(&t2);
+                z3.norm();
+                t1.sub(&t2);
+                t1.norm();
+                y3.imul(b);
+
+                x3.copy(&y3);
+                x3.mul(&t4);
+                t2.copy(&t3);
+                t2.mul(&t1);
+                x3.rsub(&t2);
+                y3.mul(&t0);
+                t1.mul(&z3);
+                y3.add(&t1);
+                t0.mul(&t3);
+                z3.mul(&t4);
+                z3.add(&t0);
+
+                self.x.copy(&x3);
+                self.x.norm();
+                self.y.copy(&y3);
+                self.y.norm();
+                self.z.copy(&z3);
+                self.z.norm();
+            } else {
+                let mut t0 = FP::new_copy(&self.x);
+                let mut t1 = FP::new_copy(&self.y);
+                let mut t2 = FP::new_copy(&self.z);
+                let mut t3 = FP::new_copy(&self.x);
+                let mut t4 = FP::new_copy(&Q.x);
+                let mut z3 = FP::new();
+                let mut y3 = FP::new_copy(&Q.x);
+                let mut x3 = FP::new_copy(&Q.y);
+                let mut b = FP::new();
+
+                if rom::CURVE_B_I == 0 {
+                    b.copy(&FP::new_big(&BIG::new_ints(&rom::CURVE_B)));
+                }
+
+                t0.mul(&Q.x); //1
+                t1.mul(&Q.y); //2
+                t2.mul(&Q.z); //3
+
+                t3.add(&self.y);
+                t3.norm(); //4
+                t4.add(&Q.y);
+                t4.norm(); //5
+                t3.mul(&t4); //6
+                t4.copy(&t0);
+                t4.add(&t1); //7
+                t3.sub(&t4);
+                t3.norm(); //8
+                t4.copy(&self.y);
+                t4.add(&self.z);
+                t4.norm(); //9
+                x3.add(&Q.z);
+                x3.norm(); //10
+                t4.mul(&x3); //11
+                x3.copy(&t1);
+                x3.add(&t2); //12
+
+                t4.sub(&x3);
+                t4.norm(); //13
+                x3.copy(&self.x);
+                x3.add(&self.z);
+                x3.norm(); //14
+                y3.add(&Q.z);
+                y3.norm(); //15
+
+                x3.mul(&y3); //16
+                y3.copy(&t0);
+                y3.add(&t2); //17
+
+                y3.rsub(&x3);
+                y3.norm(); //18
+                z3.copy(&t2);
+
+                if rom::CURVE_B_I == 0 {
+                    z3.mul(&b); //18
+                } else {
+                    z3.imul(rom::CURVE_B_I);
+                }
+
+                x3.copy(&y3);
+                x3.sub(&z3);
+                x3.norm(); //20
+                z3.copy(&x3);
+                z3.add(&x3); //21
+
+                x3.add(&z3); //22
+                z3.copy(&t1);
+                z3.sub(&x3);
+                z3.norm(); //23
+                x3.add(&t1);
+                x3.norm(); //24
+
+                if rom::CURVE_B_I == 0 {
+                    y3.mul(&b); //18
+                } else {
+                    y3.imul(rom::CURVE_B_I);
+                }
+
+                t1.copy(&t2);
+                t1.add(&t2); //t1.norm();//26
+                t2.add(&t1); //27
+
+                y3.sub(&t2); //28
+
+                y3.sub(&t0);
+                y3.norm(); //29
+                t1.copy(&y3);
+                t1.add(&y3); //30
+                y3.add(&t1);
+                y3.norm(); //31
+
+                t1.copy(&t0);
+                t1.add(&t0); //32
+                t0.add(&t1); //33
+                t0.sub(&t2);
+                t0.norm(); //34
+                t1.copy(&t4);
+                t1.mul(&y3); //35
+                t2.copy(&t0);
+                t2.mul(&y3); //36
+                y3.copy(&x3);
+                y3.mul(&z3); //37
+                y3.add(&t2); //y3.norm();//38
+                x3.mul(&t3); //39
+                x3.sub(&t1); //40
+                z3.mul(&t4); //41
+                t1.copy(&t3);
+                t1.mul(&t0); //42
+                z3.add(&t1);
+                self.x.copy(&x3);
+                self.x.norm();
+                self.y.copy(&y3);
+                self.y.norm();
+                self.z.copy(&z3);
+                self.z.norm();
+            }
+        }
+        if CURVETYPE == CurveType::EDWARDS {
+            let 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(&Q.z);
+            b.copy(&a);
+            b.sqr();
+            c.mul(&Q.x);
+            d.mul(&Q.y);
+
+            e.copy(&c);
+            e.mul(&d);
+            e.mul(&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.norm();
+            d.norm();
+            b.mul(&d);
+            b.sub(&c);
+            b.norm();
+            f.norm();
+            b.mul(&f);
+            self.x.copy(&a);
+            self.x.mul(&b);
+            g.norm();
+            if rom::CURVE_A == 1 {
+                e.norm();
+                c.copy(&e);
+                c.mul(&g);
+            }
+            if rom::CURVE_A == -1 {
+                c.norm();
+                c.mul(&g);
+            }
+            self.y.copy(&a);
+            self.y.mul(&c);
+            self.z.copy(&f);
+            self.z.mul(&g);
+        }
+        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);
+
+        a.norm();
+        d.norm();
+
+        da.copy(&d);
+        da.mul(&a);
+
+        c.norm();
+        b.norm();
+
+        cb.copy(&c);
+        cb.mul(&b);
+
+        a.copy(&da);
+        a.add(&cb);
+        a.norm();
+        a.sqr();
+        b.copy(&da);
+        b.sub(&cb);
+        b.norm();
+        b.sqr();
+
+        self.x.copy(&a);
+        self.z.copy(&W.x);
+        self.z.mul(&b);
+    }
+
+    /* self-=Q */
+    pub fn sub(&mut self, Q: &ECP) {
+        let mut NQ = ECP::new();
+        NQ.copy(Q);
+        NQ.neg();
+        self.add(&NQ);
+    }
+
+    /* constant time multiply by small integer of length bts - use ladder */
+    pub fn pinmul(&self, e: i32, bts: i32) -> ECP {
+        if CURVETYPE == CurveType::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(&self, e: &BIG) -> ECP {
+        if e.iszilch() || self.is_infinity() {
+            return ECP::new();
+        }
+        let mut P = ECP::new();
+        if CURVETYPE == CurveType::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 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
+            let mut w: [i8; CT] = [0; CT];
+
+            Q.copy(&self);
+            Q.dbl();
+
+            W[0].copy(&self);
+
+            for i in 1..8 {
+                C.copy(&W[i - 1]);
+                W[i].copy(&C);
+                W[i].add(&mut Q);
+            }
+
+            // make exponent odd - add 2P if even, P if odd
+            t.copy(&e);
+            let s = t.parity();
+            t.inc(1);
+            t.norm();
+            let ns = t.parity();
+            mt.copy(&t);
+            mt.inc(1);
+            mt.norm();
+            t.cmove(&mt, s);
+            Q.cmove(&self, ns);
+            C.copy(&Q);
+
+            let nb = 1 + (t.nbits() + 3) / 4;
+
+            // convert exponent to signed 4-bit window
+            for i in 0..nb {
+                w[i] = (t.lastbits(5) - 16) as i8;
+                t.dec(w[i] as isize);
+                t.norm();
+                t.fshr(4);
+            }
+            w[nb] = t.lastbits(5) as i8;
+
+            P.copy(&W[((w[nb] as usize) - 1) / 2]);
+            for i in (0..nb).rev() {
+                Q.selector(&W, w[i] as i32);
+                P.dbl();
+                P.dbl();
+                P.dbl();
+                P.dbl();
+                P.add(&mut Q);
+            }
+            P.sub(&mut C); /* apply correction */
+        }
+        P.affine();
+        return P;
+    }
+
+    /* Return e.this+f.Q */
+
+    pub fn mul2(&self, e: &BIG, Q: &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 + (big::NLEN * (big::BASEBITS as usize) + 1) / 2;
+        let mut w: [i8; CT] = [0; CT];
+
+        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);
+
+        // 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;
+    }
+
+    // Multiply itself by cofactor of the curve
+    pub fn cfp(&mut self) {
+        let cf = rom::CURVE_COF_I;
+        if cf == 1 {
+            return;
+        }
+        if cf == 4 {
+            self.dbl();
+            self.dbl();
+            return;
+        }
+        if cf == 8 {
+            self.dbl();
+            self.dbl();
+            self.dbl();
+            return;
+        }
+        let c = BIG::new_ints(&rom::CURVE_COF);
+        let P = self.mul(&c);
+        self.copy(&P);
+    }
+
+    // Map a given byte slice to a point on the curve. The byte slice should be atleast the size of the modulus
+    #[allow(non_snake_case)]
+    pub fn mapit(h: &[u8]) -> ECP {
+        let mut q = BIG::new_ints(&rom::MODULUS);
+        let mut x = BIG::frombytes(h);
+        x.rmod(&mut q);
+        let mut P: ECP;
+
+        loop {
+            loop {
+                if CURVETYPE != CurveType::MONTGOMERY {
+                    P = ECP::new_bigint(&x, 0);
+                } else {
+                    P = ECP::new_big(&x);
+                }
+                x.inc(1);
+                x.norm();
+                if !P.is_infinity() {
+                    break;
+                }
+            }
+            P.cfp();
+            if !P.is_infinity() {
+                break;
+            }
+        }
+
+        return P;
+    }
+
+    pub fn generator() -> ECP {
+        let G: ECP;
+
+        let gx = BIG::new_ints(&rom::CURVE_GX);
+
+        if CURVETYPE != CurveType::MONTGOMERY {
+            let gy = BIG::new_ints(&rom::CURVE_GY);
+            G = ECP::new_bigs(&gx, &gy);
+        } else {
+            G = ECP::new_big(&gx);
+        }
+        return G;
+    }
+}
diff --git a/src/ecp2.rs b/src/ecp2.rs
new file mode 100644
index 0000000..afd9376
--- /dev/null
+++ b/src/ecp2.rs
@@ -0,0 +1,784 @@
+/*
+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 super::rom;
+use super::big;
+use super::ecp;
+use super::fp2::FP2;
+use super::big::BIG;
+use types::{SexticTwist, CurvePairingType, SignOfX};
+use std::str::SplitWhitespace;
+use std::fmt;
+
+#[derive(Copy, Clone)]
+pub struct ECP2 {
+    x: FP2,
+    y: FP2,
+    z: FP2,
+}
+
+impl PartialEq for ECP2 {
+	fn eq(&self, other: &ECP2) -> bool {
+		self.equals(other)
+	}
+}
+
+impl fmt::Display for ECP2 {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+	}
+}
+
+impl fmt::Debug for ECP2 {
+	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+		write!(f, "ECP2: [ {}, {}, {} ]", self.x, self.y, self.z)
+	}
+}
+
+#[allow(non_snake_case)]
+impl ECP2 {
+    pub fn new() -> ECP2 {
+        ECP2 {
+            x: FP2::new(),
+            y: FP2::new_int(1),
+            z: FP2::new(),
+        }
+    }
+    #[allow(non_snake_case)]
+    /* construct this from (x,y) - but set to O if not on curve */
+    pub fn new_fp2s(ix: &FP2, iy: &FP2) -> ECP2 {
+        let mut E = ECP2::new();
+        E.x.copy(&ix);
+        E.y.copy(&iy);
+        E.z.one();
+        E.x.norm();
+
+        let mut rhs = ECP2::rhs(&E.x);
+        let mut y2 = FP2::new_copy(&E.y);
+        y2.sqr();
+        if !y2.equals(&mut rhs) {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* construct this from x - but set to O if not on curve */
+    pub fn new_fp2(ix: &FP2) -> ECP2 {
+        let mut E = ECP2::new();
+        E.x.copy(&ix);
+        E.y.one();
+        E.z.one();
+        E.x.norm();
+        let mut rhs = ECP2::rhs(&E.x);
+        if rhs.sqrt() {
+            E.y.copy(&rhs);
+        } else {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* Test this=O? */
+    pub fn is_infinity(&self) -> bool {
+        self.x.iszilch() && self.z.iszilch()
+    }
+
+    /* copy self=P */
+    pub fn copy(&mut self, P: &ECP2) {
+        self.x.copy(&P.x);
+        self.y.copy(&P.y);
+        self.z.copy(&P.z);
+    }
+
+    /* set self=O */
+    pub fn inf(&mut self) {
+        self.x.zero();
+        self.y.one();
+        self.z.zero();
+    }
+
+    /* set self=-self */
+    pub fn neg(&mut self) {
+        self.y.norm();
+        self.y.neg();
+        self.y.norm();
+    }
+
+    /* Conditional move of Q to self dependant on d */
+    pub fn cmove(&mut self, Q: &ECP2, d: isize) {
+        self.x.cmove(&Q.x, d);
+        self.y.cmove(&Q.y, d);
+        self.z.cmove(&Q.z, d);
+    }
+
+    /* 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(&self, Q: &ECP2) -> bool {
+        let mut a = FP2::new_copy(&self.x);
+        let mut b = FP2::new_copy(&Q.x);
+
+        a.mul(&Q.z);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+        a.copy(&self.y);
+        a.mul(&Q.z);
+        b.copy(&Q.y);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /* set to Affine - (x,y,z) to (x,y) */
+    pub fn affine(&mut self) {
+        if self.is_infinity() {
+            return;
+        }
+        let mut one = FP2::new_int(1);
+        if self.z.equals(&mut one) {
+            return;
+        }
+        self.z.inverse();
+
+        self.x.mul(&self.z);
+        self.x.reduce();
+        self.y.mul(&self.z);
+        self.y.reduce();
+        self.z.copy(&one);
+    }
+
+    /* extract affine x as FP2 */
+    pub fn getx(&self) -> FP2 {
+        let mut W = ECP2::new();
+        W.copy(self);
+        W.affine();
+        return FP2::new_copy(&W.x);
+    }
+
+    /* extract affine y as FP2 */
+    pub fn gety(&self) -> FP2 {
+        let mut W = ECP2::new();
+        W.copy(self);
+        W.affine();
+        return FP2::new_copy(&W.y);
+    }
+
+    /* extract projective x */
+    pub fn getpx(&self) -> FP2 {
+        return FP2::new_copy(&self.x);
+    }
+    /* extract projective y */
+    pub fn getpy(&self) -> FP2 {
+        return FP2::new_copy(&self.y);
+    }
+    /* extract projective z */
+    pub fn getpz(&self) -> FP2 {
+        return FP2::new_copy(&self.z);
+    }
+
+    /* convert to byte array */
+    pub fn tobytes(&self, b: &mut [u8]) {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+        let mut W = ECP2::new();
+        W.copy(self);
+
+        W.affine();
+        W.x.geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i] = t[i]
+        }
+        W.x.getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + mb] = t[i]
+        }
+
+        W.y.geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 2 * mb] = t[i]
+        }
+        W.y.getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 3 * mb] = t[i]
+        }
+    }
+
+    /* convert from byte array to point */
+    pub fn frombytes(b: &[u8]) -> ECP2 {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+
+        for i in 0..mb {
+            t[i] = b[i]
+        }
+        let mut ra = BIG::frombytes(&t);
+        for i in 0..mb {
+            t[i] = b[i + mb]
+        }
+        let mut rb = BIG::frombytes(&t);
+        let rx = FP2::new_bigs(&ra, &rb);
+
+        for i in 0..mb {
+            t[i] = b[i + 2 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 3 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+        let ry = FP2::new_bigs(&ra, &rb);
+
+        return ECP2::new_fp2s(&rx, &ry);
+    }
+
+    /* convert this to hex string */
+    pub fn tostring(&self) -> String {
+        let mut W = ECP2::new();
+        W.copy(self);
+        W.affine();
+        if W.is_infinity() {
+            return String::from("infinity");
+        }
+        return format!("({},{})", W.x.tostring(), W.y.tostring());
+    }
+
+    pub fn to_hex(&self) -> String {
+        format!("{} {} {}", self.x.to_hex(), self.y.to_hex(), self.z.to_hex())
+    }
+
+    pub fn from_hex_iter(iter: &mut SplitWhitespace) -> ECP2 {
+        ECP2 {
+            x: FP2::from_hex_iter(iter),
+            y: FP2::from_hex_iter(iter),
+            z: FP2::from_hex_iter(iter)
+        }
+    }
+
+    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: &FP2) -> FP2 {
+        let mut r = FP2::new_copy(x);
+        r.sqr();
+        let mut b = FP2::new_big(&BIG::new_ints(&rom::CURVE_B));
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            b.div_ip();
+        }
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            b.norm();
+            b.mul_ip();
+            b.norm();
+        }
+
+        r.mul(x);
+        r.add(&b);
+
+        r.reduce();
+        return r;
+    }
+
+    /* self+=self */
+    pub fn dbl(&mut self) -> isize {
+        let mut iy = FP2::new_copy(&self.y);
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            iy.mul_ip();
+            iy.norm();
+        }
+
+        let mut t0 = FP2::new_copy(&self.y); //***** Change
+        t0.sqr();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.mul_ip();
+        }
+        let mut t1 = FP2::new_copy(&iy);
+        t1.mul(&self.z);
+        let mut t2 = FP2::new_copy(&self.z);
+        t2.sqr();
+
+        self.z.copy(&t0);
+        self.z.add(&t0);
+        self.z.norm();
+        self.z.dbl();
+        self.z.dbl();
+        self.z.norm();
+
+        t2.imul(3 * rom::CURVE_B_I);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.mul_ip();
+            t2.norm();
+        }
+        let mut x3 = FP2::new_copy(&t2);
+        x3.mul(&self.z);
+
+        let mut y3 = FP2::new_copy(&t0);
+
+        y3.add(&t2);
+        y3.norm();
+        self.z.mul(&t1);
+        t1.copy(&t2);
+        t1.add(&t2);
+        t2.add(&t1);
+        t2.norm();
+        t0.sub(&t2);
+        t0.norm(); //y^2-9bz^2
+        y3.mul(&t0);
+        y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+        t1.copy(&self.x);
+        t1.mul(&iy); //
+        self.x.copy(&t0);
+        self.x.norm();
+        self.x.mul(&t1);
+        self.x.dbl(); //(y^2-9bz^2)xy2
+
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+
+        return 1;
+    }
+
+    /* self+=Q - return 0 for add, 1 for double, -1 for O */
+    pub fn add(&mut self, Q: &ECP2) -> isize {
+        let b = 3 * rom::CURVE_B_I;
+        let mut t0 = FP2::new_copy(&self.x);
+        t0.mul(&Q.x); // x.Q.x
+        let mut t1 = FP2::new_copy(&self.y);
+        t1.mul(&Q.y); // y.Q.y
+
+        let mut t2 = FP2::new_copy(&self.z);
+        t2.mul(&Q.z);
+        let mut t3 = FP2::new_copy(&self.x);
+        t3.add(&self.y);
+        t3.norm(); //t3=X1+Y1
+        let mut t4 = FP2::new_copy(&Q.x);
+        t4.add(&Q.y);
+        t4.norm(); //t4=X2+Y2
+        t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
+        t4.copy(&t0);
+        t4.add(&t1); //t4=X1.X2+Y1.Y2
+
+        t3.sub(&t4);
+        t3.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t3.mul_ip();
+            t3.norm(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+        }
+        t4.copy(&self.y);
+        t4.add(&self.z);
+        t4.norm(); //t4=Y1+Z1
+        let mut x3 = FP2::new_copy(&Q.y);
+        x3.add(&Q.z);
+        x3.norm(); //x3=Y2+Z2
+
+        t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
+        x3.copy(&t1); //
+        x3.add(&t2); //X3=Y1.Y2+Z1.Z2
+
+        t4.sub(&x3);
+        t4.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t4.mul_ip();
+            t4.norm(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+        }
+        x3.copy(&self.x);
+        x3.add(&self.z);
+        x3.norm(); // x3=X1+Z1
+        let mut y3 = FP2::new_copy(&Q.x);
+        y3.add(&Q.z);
+        y3.norm(); // y3=X2+Z2
+        x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
+        y3.copy(&t0);
+        y3.add(&t2); // y3=X1.X2+Z1+Z2
+        y3.rsub(&x3);
+        y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.mul_ip();
+            t0.norm(); // x.Q.x
+            t1.mul_ip();
+            t1.norm(); // y.Q.y
+        }
+        x3.copy(&t0);
+        x3.add(&t0);
+        t0.add(&x3);
+        t0.norm();
+        t2.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.mul_ip();
+            t2.norm();
+        }
+        let mut z3 = FP2::new_copy(&t1);
+        z3.add(&t2);
+        z3.norm();
+        t1.sub(&t2);
+        t1.norm();
+        y3.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            y3.mul_ip();
+            y3.norm();
+        }
+        x3.copy(&y3);
+        x3.mul(&t4);
+        t2.copy(&t3);
+        t2.mul(&t1);
+        x3.rsub(&t2);
+        y3.mul(&t0);
+        t1.mul(&z3);
+        y3.add(&t1);
+        t0.mul(&t3);
+        z3.mul(&t4);
+        z3.add(&t0);
+
+        self.x.copy(&x3);
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+        self.z.copy(&z3);
+        self.z.norm();
+
+        return 0;
+    }
+
+    /* set this-=Q */
+    pub fn sub(&mut self, Q: &ECP2) -> isize {
+        let mut NQ = ECP2::new();
+        NQ.copy(Q);
+        NQ.neg();
+        let d = self.add(&NQ);
+        return d;
+    }
+
+    /* set this*=q, where q is Modulus, using Frobenius */
+    pub fn frob(&mut self, x: &FP2) {
+        let mut x2 = FP2::new_copy(x);
+        x2.sqr();
+        self.x.conj();
+        self.y.conj();
+        self.z.conj();
+        self.z.reduce();
+        self.x.mul(&x2);
+        self.y.mul(&x2);
+        self.y.mul(x);
+    }
+
+    /* self*=e */
+    pub fn mul(&self, e: &BIG) -> ECP2 {
+        /* fixed size windows */
+        let mut mt = BIG::new();
+        let mut t = BIG::new();
+        let mut P = ECP2::new();
+        let mut Q = ECP2::new();
+        let mut C = ECP2::new();
+
+        if self.is_infinity() {
+            return P;
+        }
+
+        let mut W: [ECP2; 8] = [
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+        ];
+
+        const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
+        let mut w: [i8; CT] = [0; CT];
+
+        /* precompute table */
+        Q.copy(&self);
+        Q.dbl();
+
+        W[0].copy(&self);
+
+        for i in 1..8 {
+            C.copy(&W[i - 1]);
+            W[i].copy(&C);
+            W[i].add(&mut Q);
+        }
+
+        /* make exponent odd - add 2P if even, P if odd */
+        t.copy(&e);
+        let s = t.parity();
+        t.inc(1);
+        t.norm();
+        let ns = t.parity();
+        mt.copy(&t);
+        mt.inc(1);
+        mt.norm();
+        t.cmove(&mt, s);
+        Q.cmove(&self, ns);
+        C.copy(&Q);
+
+        let nb = 1 + (t.nbits() + 3) / 4;
+
+        /* convert exponent to signed 4-bit window */
+        for i in 0..nb {
+            w[i] = (t.lastbits(5) - 16) as i8;
+            t.dec(w[i] as isize);
+            t.norm();
+            t.fshr(4);
+        }
+        w[nb] = (t.lastbits(5)) as i8;
+
+        P.copy(&W[((w[nb] as usize) - 1) / 2]);
+        for i in (0..nb).rev() {
+            Q.selector(&W, w[i] as i32);
+            P.dbl();
+            P.dbl();
+            P.dbl();
+            P.dbl();
+            P.add(&mut Q);
+        }
+        P.sub(&mut C);
+        P.affine();
+        return P;
+    }
+
+    /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+    // Bos & Costello https://eprint.iacr.org/2013/458.pdf
+    // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+    // Side channel attack secure
+
+    pub fn mul4(Q: &mut [ECP2], u: &[BIG]) -> ECP2 {
+        let mut W = ECP2::new();
+        let mut P = ECP2::new();
+
+        let mut T: [ECP2; 8] = [
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+            ECP2::new(),
+        ];
+
+        let mut mt = BIG::new();
+
+        let mut t: [BIG; 4] = [
+            BIG::new_copy(&u[0]),
+            BIG::new_copy(&u[1]),
+            BIG::new_copy(&u[2]),
+            BIG::new_copy(&u[3]),
+        ];
+
+        const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
+        let mut w: [i8; CT] = [0; CT];
+        let mut s: [i8; CT] = [0; CT];
+
+        for i in 0..4 {
+            t[i].norm();
+        }
+
+        T[0].copy(&Q[0]);
+        W.copy(&T[0]);
+        T[1].copy(&W);
+        T[1].add(&mut Q[1]); // Q[0]+Q[1]
+        T[2].copy(&W);
+        T[2].add(&mut Q[2]);
+        W.copy(&T[1]); // Q[0]+Q[2]
+        T[3].copy(&W);
+        T[3].add(&mut Q[2]);
+        W.copy(&T[0]); // Q[0]+Q[1]+Q[2]
+        T[4].copy(&W);
+        T[4].add(&mut Q[3]);
+        W.copy(&T[1]); // Q[0]+Q[3]
+        T[5].copy(&W);
+        T[5].add(&mut Q[3]);
+        W.copy(&T[2]); // Q[0]+Q[1]+Q[3]
+        T[6].copy(&W);
+        T[6].add(&mut Q[3]);
+        W.copy(&T[3]); // Q[0]+Q[2]+Q[3]
+        T[7].copy(&W);
+        T[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
+
+        // Make it odd
+        let pb = 1 - t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+        // Number of bits
+        mt.zero();
+        for i in 0..4 {
+            mt.or(&t[i]);
+        }
+
+        let nb = 1 + mt.nbits();
+
+        // Sign pivot
+
+        s[nb - 1] = 1;
+        for i in 0..nb - 1 {
+            t[0].fshr(1);
+            s[i] = (2 * t[0].parity() - 1) as i8;
+        }
+
+        // Recoded exponent
+        for i in 0..nb {
+            w[i] = 0;
+            let mut k = 1;
+            for j in 1..4 {
+                let bt = s[i] * (t[j].parity() as i8);
+                t[j].fshr(1);
+                t[j].dec((bt >> 1) as isize);
+                t[j].norm();
+                w[i] += bt * (k as i8);
+                k = 2 * k;
+            }
+        }
+
+        // Main loop
+        P.selector(&T, (2 * w[nb - 1] + 1) as i32);
+        for i in (0..nb - 1).rev() {
+            P.dbl();
+            W.selector(&T, (2 * w[i] + s[i]) as i32);
+            P.add(&mut W);
+        }
+
+        // apply correction
+        W.copy(&P);
+        W.sub(&mut Q[0]);
+        P.cmove(&W, pb);
+        P.affine();
+
+        return P;
+    }
+
+    #[allow(non_snake_case)]
+    pub fn mapit(h: &[u8]) -> ECP2 {
+        let mut q = BIG::new_ints(&rom::MODULUS);
+        let mut x = BIG::frombytes(h);
+        x.rmod(&mut q);
+        let mut Q: ECP2;
+        let one = BIG::new_int(1);
+
+        loop {
+            let X = FP2::new_bigs(&one, &x);
+            Q = ECP2::new_fp2(&X);
+            if !Q.is_infinity() {
+                break;
+            }
+            x.inc(1);
+            x.norm();
+        }
+        let mut X = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            X.inverse();
+            X.norm();
+        }
+        x = BIG::new_ints(&rom::CURVE_BNX);
+
+        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
+            let mut T = Q.mul(&mut x);
+            if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+                T.neg();
+            }
+            let mut K = ECP2::new();
+            K.copy(&T);
+            K.dbl();
+            K.add(&T);
+
+            K.frob(&X);
+            Q.frob(&X);
+            Q.frob(&X);
+            Q.frob(&X);
+            Q.add(&T);
+            Q.add(&K);
+            T.frob(&X);
+            T.frob(&X);
+            Q.add(&T);
+        }
+        if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BLS {
+            let mut xQ = Q.mul(&mut x);
+            let mut x2Q = xQ.mul(&mut x);
+
+            if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+                xQ.neg();
+            }
+            x2Q.sub(&xQ);
+            x2Q.sub(&Q);
+
+            xQ.sub(&Q);
+            xQ.frob(&X);
+
+            Q.dbl();
+            Q.frob(&X);
+            Q.frob(&X);
+
+            Q.add(&x2Q);
+            Q.add(&xQ);
+        }
+
+        Q.affine();
+        return Q;
+    }
+
+    pub fn generator() -> ECP2 {
+        return ECP2::new_fp2s(
+            &FP2::new_bigs(
+                &BIG::new_ints(&rom::CURVE_PXA),
+                &BIG::new_ints(&rom::CURVE_PXB),
+            ),
+            &FP2::new_bigs(
+                &BIG::new_ints(&rom::CURVE_PYA),
+                &BIG::new_ints(&rom::CURVE_PYB),
+            ),
+        );
+    }
+}
diff --git a/src/ecp4.rs b/src/ecp4.rs
new file mode 100644
index 0000000..d34b0fd
--- /dev/null
+++ b/src/ecp4.rs
@@ -0,0 +1,866 @@
+/*
+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 super::rom;
+use super::big;
+use super::ecp;
+use super::fp2::FP2;
+use super::fp4::FP4;
+use super::big::BIG;
+use types::{SexticTwist, SignOfX};
+//use std::str::SplitWhitespace;
+
+pub struct ECP4 {
+    x: FP4,
+    y: FP4,
+    z: FP4,
+}
+
+#[allow(non_snake_case)]
+impl ECP4 {
+    pub fn new() -> ECP4 {
+        ECP4 {
+            x: FP4::new(),
+            y: FP4::new_int(1),
+            z: FP4::new(),
+        }
+    }
+    #[allow(non_snake_case)]
+    /* construct this from (x,y) - but set to O if not on curve */
+    pub fn new_fp4s(ix: &FP4, iy: &FP4) -> ECP4 {
+        let mut E = ECP4::new();
+        E.x.copy(&ix);
+        E.y.copy(&iy);
+        E.z.one();
+        E.x.norm();
+
+        let mut rhs = ECP4::rhs(&E.x);
+        let mut y2 = FP4::new_copy(&E.y);
+        y2.sqr();
+        if !y2.equals(&mut rhs) {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* construct this from x - but set to O if not on curve */
+    pub fn new_fp4(ix: &FP4) -> ECP4 {
+        let mut E = ECP4::new();
+        E.x.copy(&ix);
+        E.y.one();
+        E.z.one();
+        E.x.norm();
+
+        let mut rhs = ECP4::rhs(&E.x);
+        if rhs.sqrt() {
+            E.y.copy(&rhs);
+        } else {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* Test this=O? */
+    pub fn is_infinity(&self) -> bool {
+        let xx = FP4::new_copy(&self.x);
+        let zz = FP4::new_copy(&self.z);
+        return xx.iszilch() && zz.iszilch();
+    }
+
+    /* copy self=P */
+    pub fn copy(&mut self, P: &ECP4) {
+        self.x.copy(&P.x);
+        self.y.copy(&P.y);
+        self.z.copy(&P.z);
+    }
+
+    /* set self=O */
+    pub fn inf(&mut self) {
+        self.x.zero();
+        self.y.one();
+        self.z.zero();
+    }
+
+    /* set self=-self */
+    pub fn neg(&mut self) {
+        self.y.norm();
+        self.y.neg();
+        self.y.norm();
+    }
+
+    /* Conditional move of Q to self dependant on d */
+    pub fn cmove(&mut self, Q: &ECP4, d: isize) {
+        self.x.cmove(&Q.x, d);
+        self.y.cmove(&Q.y, d);
+        self.z.cmove(&Q.z, d);
+    }
+
+    /* 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: &[ECP4], b: i32) {
+        let mut MP = ECP4::new();
+        let m = b >> 31;
+        let mut babs = (b ^ m) - m;
+
+        babs = (babs - 1) / 2;
+
+        self.cmove(&W[0], ECP4::teq(babs, 0)); // conditional move
+        self.cmove(&W[1], ECP4::teq(babs, 1));
+        self.cmove(&W[2], ECP4::teq(babs, 2));
+        self.cmove(&W[3], ECP4::teq(babs, 3));
+        self.cmove(&W[4], ECP4::teq(babs, 4));
+        self.cmove(&W[5], ECP4::teq(babs, 5));
+        self.cmove(&W[6], ECP4::teq(babs, 6));
+        self.cmove(&W[7], ECP4::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 ECP4) -> bool {
+        let mut a = FP4::new_copy(&self.x);
+        let mut b = FP4::new_copy(&Q.x);
+
+        a.mul(&Q.z);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+        a.copy(&self.y);
+        a.mul(&Q.z);
+        b.copy(&Q.y);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /* set to Affine - (x,y,z) to (x,y) */
+    pub fn affine(&mut self) {
+        if self.is_infinity() {
+            return;
+        }
+        let mut one = FP4::new_int(1);
+        if self.z.equals(&mut one) {
+            return;
+        }
+        self.z.inverse();
+
+        self.x.mul(&self.z);
+        self.x.reduce();
+        self.y.mul(&self.z);
+        self.y.reduce();
+        self.z.copy(&one);
+    }
+
+    /* extract affine x as FP4 */
+    pub fn getx(&self) -> FP4 {
+        let mut W = ECP4::new();
+        W.copy(self);
+        W.affine();
+        return FP4::new_copy(&self.x);
+    }
+
+    /* extract affine y as FP4 */
+    pub fn gety(&self) -> FP4 {
+        let mut W = ECP4::new();
+        W.copy(self);
+        W.affine();
+        return FP4::new_copy(&W.y);
+    }
+
+    /* extract projective x */
+    pub fn getpx(&self) -> FP4 {
+        return FP4::new_copy(&self.x);
+    }
+    /* extract projective y */
+    pub fn getpy(&self) -> FP4 {
+        return FP4::new_copy(&self.y);
+    }
+    /* extract projective z */
+    pub fn getpz(&self) -> FP4 {
+        return FP4::new_copy(&self.z);
+    }
+
+    /* convert to byte array */
+    pub fn tobytes(&self, b: &mut [u8]) {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+
+        let mut W = ECP4::new();
+        W.copy(self);
+
+        W.affine();
+
+        W.x.geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i] = t[i]
+        }
+        W.x.geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + mb] = t[i]
+        }
+
+        W.x.getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 2 * mb] = t[i]
+        }
+        W.x.getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 3 * mb] = t[i]
+        }
+
+        W.y.geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 4 * mb] = t[i]
+        }
+        W.y.geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 5 * mb] = t[i]
+        }
+
+        W.y.getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 6 * mb] = t[i]
+        }
+        W.y.getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 7 * mb] = t[i]
+        }
+    }
+
+    /* convert from byte array to point */
+    pub fn frombytes(b: &[u8]) -> ECP4 {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+
+        for i in 0..mb {
+            t[i] = b[i]
+        }
+        let mut ra = BIG::frombytes(&t);
+        for i in 0..mb {
+            t[i] = b[i + mb]
+        }
+        let mut rb = BIG::frombytes(&t);
+
+        let mut ra4 = 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 mut rb4 = FP2::new_bigs(&ra, &rb);
+
+        let rx = FP4::new_fp2s(&ra4, &rb4);
+
+        for i in 0..mb {
+            t[i] = b[i + 4 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 5 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        ra4.copy(&FP2::new_bigs(&ra, &rb));
+
+        for i in 0..mb {
+            t[i] = b[i + 6 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 7 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        rb4.copy(&FP2::new_bigs(&ra, &rb));
+
+        let ry = FP4::new_fp2s(&ra4, &rb4);
+
+        return ECP4::new_fp4s(&rx, &ry);
+    }
+
+    /* convert this to hex string */
+    pub fn tostring(&self) -> String {
+        let mut W = ECP4::new();
+        W.copy(self);
+        W.affine();
+        if W.is_infinity() {
+            return String::from("infinity");
+        }
+        return format!("({},{})", W.x.tostring(), W.y.tostring());
+    }
+
+    /* Calculate RHS of twisted curve equation x^3+B/i */
+    pub fn rhs(x: &FP4) -> FP4 {
+        //x.norm();
+        let mut r = FP4::new_copy(x);
+        r.sqr();
+        let mut b = FP4::new_fp2(&FP2::new_big(&BIG::new_ints(&rom::CURVE_B)));
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            b.div_i();
+        }
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            b.times_i();
+        }
+
+        r.mul(x);
+        r.add(&b);
+
+        r.reduce();
+        return r;
+    }
+
+    /* self+=self */
+    pub fn dbl(&mut self) -> isize {
+        let mut iy = FP4::new_copy(&self.y);
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            iy.times_i(); //iy.norm();
+        }
+
+        let mut t0 = FP4::new_copy(&self.y);
+        t0.sqr();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.times_i();
+        }
+        let mut t1 = FP4::new_copy(&iy);
+        t1.mul(&self.z);
+        let mut t2 = FP4::new_copy(&self.z);
+        t2.sqr();
+
+        self.z.copy(&t0);
+        self.z.add(&t0);
+        self.z.norm();
+        self.z.dbl();
+        self.z.dbl();
+        self.z.norm();
+
+        t2.imul(3 * rom::CURVE_B_I);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.times_i();
+        }
+        let mut x3 = FP4::new_copy(&t2);
+        x3.mul(&self.z);
+
+        let mut y3 = FP4::new_copy(&t0);
+
+        y3.add(&t2);
+        y3.norm();
+        self.z.mul(&t1);
+        t1.copy(&t2);
+        t1.add(&t2);
+        t2.add(&t1);
+        t2.norm();
+        t0.sub(&t2);
+        t0.norm(); //y^2-9bz^2
+        y3.mul(&t0);
+        y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+        t1.copy(&self.x);
+        t1.mul(&iy); //
+        self.x.copy(&t0);
+        self.x.norm();
+        self.x.mul(&t1);
+        self.x.dbl(); //(y^2-9bz^2)xy2
+
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+
+        return 1;
+    }
+
+    /* self+=Q - return 0 for add, 1 for double, -1 for O */
+    pub fn add(&mut self, Q: &ECP4) -> isize {
+        let b = 3 * rom::CURVE_B_I;
+        let mut t0 = FP4::new_copy(&self.x);
+        t0.mul(&Q.x); // x.Q.x
+        let mut t1 = FP4::new_copy(&self.y);
+        t1.mul(&Q.y); // y.Q.y
+
+        let mut t2 = FP4::new_copy(&self.z);
+        t2.mul(&Q.z);
+        let mut t3 = FP4::new_copy(&self.x);
+        t3.add(&self.y);
+        t3.norm(); //t3=X1+Y1
+        let mut t4 = FP4::new_copy(&Q.x);
+        t4.add(&Q.y);
+        t4.norm(); //t4=X2+Y2
+        t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
+        t4.copy(&t0);
+        t4.add(&t1); //t4=X1.X2+Y1.Y2
+
+        t3.sub(&t4);
+        t3.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+        }
+        t4.copy(&self.y);
+        t4.add(&self.z);
+        t4.norm(); //t4=Y1+Z1
+        let mut x3 = FP4::new_copy(&Q.y);
+        x3.add(&Q.z);
+        x3.norm(); //x3=Y2+Z2
+
+        t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
+        x3.copy(&t1); //
+        x3.add(&t2); //X3=Y1.Y2+Z1.Z2
+
+        t4.sub(&x3);
+        t4.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+        }
+        x3.copy(&self.x);
+        x3.add(&self.z);
+        x3.norm(); // x3=X1+Z1
+        let mut y3 = FP4::new_copy(&Q.x);
+        y3.add(&Q.z);
+        y3.norm(); // y3=X2+Z2
+        x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
+        y3.copy(&t0);
+        y3.add(&t2); // y3=X1.X2+Z1+Z2
+        y3.rsub(&x3);
+        y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.times_i(); // x.Q.x
+            t1.times_i(); // y.Q.y
+        }
+        x3.copy(&t0);
+        x3.add(&t0);
+        t0.add(&x3);
+        t0.norm();
+        t2.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.times_i();
+        }
+        let mut z3 = FP4::new_copy(&t1);
+        z3.add(&t2);
+        z3.norm();
+        t1.sub(&t2);
+        t1.norm();
+        y3.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            y3.times_i();
+        }
+        x3.copy(&y3);
+        x3.mul(&t4);
+        t2.copy(&t3);
+        t2.mul(&t1);
+        x3.rsub(&t2);
+        y3.mul(&t0);
+        t1.mul(&z3);
+        y3.add(&t1);
+        t0.mul(&t3);
+        z3.mul(&t4);
+        z3.add(&t0);
+
+        self.x.copy(&x3);
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+        self.z.copy(&z3);
+        self.z.norm();
+
+        return 0;
+    }
+
+    /* set this-=Q */
+    pub fn sub(&mut self, Q: &ECP4) -> isize {
+        let mut NQ = ECP4::new();
+        NQ.copy(Q);
+        NQ.neg();
+        let d = self.add(&NQ);
+        return d;
+    }
+
+    pub fn frob_constants() -> [FP2; 3] {
+        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+
+        let mut f0 = FP2::new_copy(&f);
+        f0.sqr();
+        let mut f2 = FP2::new_copy(&f0);
+        f2.mul_ip();
+        f2.norm();
+        let mut f1 = FP2::new_copy(&f2);
+        f1.sqr();
+        f2.mul(&f1);
+        f1.copy(&f);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            f1.mul_ip();
+            f1.inverse();
+            f0.copy(&f1);
+            f0.sqr();
+        }
+        f0.mul_ip();
+        f0.norm();
+        f1.mul(&f0);
+
+        let F: [FP2; 3] = [f0, f1, f2];
+        return F;
+    }
+
+    /* set this*=q, where q is Modulus, using Frobenius */
+    pub fn frob(&mut self, f: &[FP2; 3], n: isize) {
+        for _i in 0..n {
+            self.x.frob(&f[2]);
+            self.x.pmul(&f[0]);
+
+            self.y.frob(&f[2]);
+            self.y.pmul(&f[1]);
+            self.y.times_i();
+
+            self.z.frob(&f[2]);
+        }
+    }
+
+    /* self*=e */
+    pub fn mul(&self, e: &BIG) -> ECP4 {
+        /* fixed size windows */
+        let mut mt = BIG::new();
+        let mut t = BIG::new();
+        let mut P = ECP4::new();
+        let mut Q = ECP4::new();
+        let mut C = ECP4::new();
+
+        if self.is_infinity() {
+            return P;
+        }
+
+        let mut W: [ECP4; 8] = [
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+        ];
+
+        const CT: usize = 1 + (big::NLEN * (big::BASEBITS as usize) + 3) / 4;
+        let mut w: [i8; CT] = [0; CT];
+
+        /* precompute table */
+        Q.copy(&self);
+        Q.dbl();
+
+        W[0].copy(&self);
+
+        for i in 1..8 {
+            C.copy(&W[i - 1]);
+            W[i].copy(&C);
+            W[i].add(&mut Q);
+        }
+
+        /* make exponent odd - add 2P if even, P if odd */
+        t.copy(&e);
+        let s = t.parity();
+        t.inc(1);
+        t.norm();
+        let ns = t.parity();
+        mt.copy(&t);
+        mt.inc(1);
+        mt.norm();
+        t.cmove(&mt, s);
+        Q.cmove(&self, ns);
+        C.copy(&Q);
+
+        let nb = 1 + (t.nbits() + 3) / 4;
+
+        /* convert exponent to signed 4-bit window */
+        for i in 0..nb {
+            w[i] = (t.lastbits(5) - 16) as i8;
+            t.dec(w[i] as isize);
+            t.norm();
+            t.fshr(4);
+        }
+        w[nb] = (t.lastbits(5)) as i8;
+
+        P.copy(&W[((w[nb] as usize) - 1) / 2]);
+        for i in (0..nb).rev() {
+            Q.selector(&W, w[i] as i32);
+            P.dbl();
+            P.dbl();
+            P.dbl();
+            P.dbl();
+            P.add(&mut Q);
+        }
+        P.sub(&mut C);
+        P.affine();
+        return P;
+    }
+
+    /* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3.. */
+    // Bos & Costello https://eprint.iacr.org/2013/458.pdf
+    // Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+    // Side channel attack secure
+
+    pub fn mul8(Q: &mut [ECP4], u: &[BIG]) -> ECP4 {
+        let mut W = ECP4::new();
+        let mut P = ECP4::new();
+
+        let mut T1: [ECP4; 8] = [
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+        ];
+        let mut T2: [ECP4; 8] = [
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+            ECP4::new(),
+        ];
+
+        let mut mt = BIG::new();
+
+        let mut t: [BIG; 8] = [
+            BIG::new_copy(&u[0]),
+            BIG::new_copy(&u[1]),
+            BIG::new_copy(&u[2]),
+            BIG::new_copy(&u[3]),
+            BIG::new_copy(&u[4]),
+            BIG::new_copy(&u[5]),
+            BIG::new_copy(&u[6]),
+            BIG::new_copy(&u[7]),
+        ];
+
+        const CT: usize = 1 + big::NLEN * (big::BASEBITS as usize);
+        let mut w1: [i8; CT] = [0; CT];
+        let mut s1: [i8; CT] = [0; CT];
+        let mut w2: [i8; CT] = [0; CT];
+        let mut s2: [i8; CT] = [0; CT];
+
+        for i in 0..8 {
+            //Q[i].affine();
+            t[i].norm();
+        }
+
+        T1[0].copy(&Q[0]);
+        W.copy(&T1[0]);
+        T1[1].copy(&W);
+        T1[1].add(&mut Q[1]); // Q[0]+Q[1]
+        T1[2].copy(&W);
+        T1[2].add(&mut Q[2]);
+        W.copy(&T1[1]); // Q[0]+Q[2]
+        T1[3].copy(&W);
+        T1[3].add(&mut Q[2]);
+        W.copy(&T1[0]); // Q[0]+Q[1]+Q[2]
+        T1[4].copy(&W);
+        T1[4].add(&mut Q[3]);
+        W.copy(&T1[1]); // Q[0]+Q[3]
+        T1[5].copy(&W);
+        T1[5].add(&mut Q[3]);
+        W.copy(&T1[2]); // Q[0]+Q[1]+Q[3]
+        T1[6].copy(&W);
+        T1[6].add(&mut Q[3]);
+        W.copy(&T1[3]); // Q[0]+Q[2]+Q[3]
+        T1[7].copy(&W);
+        T1[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
+
+        // Use frobenius
+        let f = ECP4::frob_constants();
+        for i in 0..8 {
+            T2[i].copy(&T1[i]);
+            T2[i].frob(&f, 4);
+        }
+
+        // Make it odd
+        let pb1 = 1 - t[0].parity();
+        t[0].inc(pb1);
+        t[0].norm();
+
+        let pb2 = 1 - t[4].parity();
+        t[4].inc(pb2);
+        t[4].norm();
+
+        // Number of bits
+        mt.zero();
+        for i in 0..8 {
+            mt.or(&t[i]);
+        }
+
+        let nb = 1 + mt.nbits();
+
+        // Sign pivot
+
+        s1[nb - 1] = 1;
+        s2[nb - 1] = 1;
+        for i in 0..nb - 1 {
+            t[0].fshr(1);
+            s1[i] = (2 * t[0].parity() - 1) as i8;
+            t[4].fshr(1);
+            s2[i] = (2 * t[4].parity() - 1) as i8;
+        }
+
+        // Recoded exponent
+        for i in 0..nb {
+            w1[i] = 0;
+            let mut k = 1;
+            for j in 1..4 {
+                let bt = s1[i] * (t[j].parity() as i8);
+                t[j].fshr(1);
+                t[j].dec((bt >> 1) as isize);
+                t[j].norm();
+                w1[i] += bt * (k as i8);
+                k = 2 * k;
+            }
+
+            w2[i] = 0;
+            k = 1;
+            for j in 5..8 {
+                let bt = s2[i] * (t[j].parity() as i8);
+                t[j].fshr(1);
+                t[j].dec((bt >> 1) as isize);
+                t[j].norm();
+                w2[i] += bt * (k as i8);
+                k = 2 * k;
+            }
+        }
+
+        // Main loop
+        P.selector(&T1, (2 * w1[nb - 1] + 1) as i32);
+        W.selector(&T2, (2 * w2[nb - 1] + 1) as i32);
+        P.add(&mut W);
+        for i in (0..nb - 1).rev() {
+            P.dbl();
+            W.selector(&T1, (2 * w1[i] + s1[i]) as i32);
+            P.add(&mut W);
+            W.selector(&T2, (2 * w2[i] + s2[i]) as i32);
+            P.add(&mut W);
+        }
+
+        // apply correction
+        W.copy(&P);
+        W.sub(&mut Q[0]);
+        P.cmove(&W, pb1);
+
+        W.copy(&P);
+        W.sub(&mut Q[4]);
+        P.cmove(&W, pb2);
+
+        P.affine();
+
+        return P;
+    }
+
+    pub fn generator() -> ECP4 {
+        return ECP4::new_fp4s(
+            &FP4::new_fp2s(
+                &FP2::new_bigs(
+                    &BIG::new_ints(&rom::CURVE_PXAA),
+                    &BIG::new_ints(&rom::CURVE_PXAB),
+                ),
+                &FP2::new_bigs(
+                    &BIG::new_ints(&rom::CURVE_PXBA),
+                    &BIG::new_ints(&rom::CURVE_PXBB),
+                ),
+            ),
+            &FP4::new_fp2s(
+                &FP2::new_bigs(
+                    &BIG::new_ints(&rom::CURVE_PYAA),
+                    &BIG::new_ints(&rom::CURVE_PYAB),
+                ),
+                &FP2::new_bigs(
+                    &BIG::new_ints(&rom::CURVE_PYBA),
+                    &BIG::new_ints(&rom::CURVE_PYBB),
+                ),
+            ),
+        );
+    }
+
+    #[allow(non_snake_case)]
+    pub fn mapit(h: &[u8]) -> ECP4 {
+        let mut q = BIG::new_ints(&rom::MODULUS);
+        let mut x = BIG::frombytes(h);
+        x.rmod(&mut q);
+        let mut Q: ECP4;
+        let one = BIG::new_int(1);
+
+        loop {
+            let X = FP4::new_fp2(&FP2::new_bigs(&one, &x));
+            Q = ECP4::new_fp4(&X);
+            if !Q.is_infinity() {
+                break;
+            }
+            x.inc(1);
+            x.norm();
+        }
+
+        let f = ECP4::frob_constants();
+        x = BIG::new_ints(&rom::CURVE_BNX);
+
+        let mut xQ = Q.mul(&mut x);
+        let mut x2Q = xQ.mul(&mut x);
+        let mut x3Q = x2Q.mul(&mut x);
+        let mut x4Q = x3Q.mul(&mut x);
+
+        if ecp::SIGN_OF_X == SignOfX::NEGATIVEX {
+            xQ.neg();
+            x3Q.neg();
+        }
+
+        x4Q.sub(&x3Q);
+        x4Q.sub(&Q);
+
+        x3Q.sub(&x2Q);
+        x3Q.frob(&f, 1);
+
+        x2Q.sub(&xQ);
+        x2Q.frob(&f, 2);
+
+        xQ.sub(&Q);
+        xQ.frob(&f, 3);
+
+        Q.dbl();
+        Q.frob(&f, 4);
+
+        Q.add(&x4Q);
+        Q.add(&x3Q);
+        Q.add(&x2Q);
+        Q.add(&xQ);
+
+        Q.affine();
+        return Q;
+    }
+}
diff --git a/src/ecp8.rs b/src/ecp8.rs
new file mode 100644
index 0000000..a6d32a4
--- /dev/null
+++ b/src/ecp8.rs
@@ -0,0 +1,1155 @@
+/*
+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 super::rom;
+use super::big;
+use super::ecp;
+use super::fp2::FP2;
+use super::fp4::FP4;
+use super::fp8::FP8;
+use super::big::BIG;
+use types::{SexticTwist, SignOfX};
+
+pub struct ECP8 {
+    x: FP8,
+    y: FP8,
+    z: FP8,
+}
+
+#[allow(non_snake_case)]
+impl ECP8 {
+    pub fn new() -> ECP8 {
+        ECP8 {
+            x: FP8::new(),
+            y: FP8::new_int(1),
+            z: FP8::new(),
+        }
+    }
+    #[allow(non_snake_case)]
+    /* construct this from (x,y) - but set to O if not on curve */
+    pub fn new_fp8s(ix: &FP8, iy: &FP8) -> ECP8 {
+        let mut E = ECP8::new();
+        E.x.copy(&ix);
+        E.y.copy(&iy);
+        E.z.one();
+        E.x.norm();
+
+        let mut rhs = ECP8::rhs(&E.x);
+        let mut y2 = FP8::new_copy(&E.y);
+        y2.sqr();
+        if !y2.equals(&mut rhs) {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* construct this from x - but set to O if not on curve */
+    pub fn new_fp8(ix: &FP8) -> ECP8 {
+        let mut E = ECP8::new();
+        E.x.copy(&ix);
+        E.y.one();
+        E.z.one();
+        E.x.norm();
+
+        let mut rhs = ECP8::rhs(&E.x);
+        if rhs.sqrt() {
+            E.y.copy(&rhs);
+        } else {
+            E.inf();
+        }
+        return E;
+    }
+
+    /* Test this=O? */
+    pub fn is_infinity(&self) -> bool {
+        let xx = FP8::new_copy(&self.x);
+        let zz = FP8::new_copy(&self.z);
+        return xx.iszilch() && zz.iszilch();
+    }
+
+    /* copy self=P */
+    pub fn copy(&mut self, P: &ECP8) {
+        self.x.copy(&P.x);
+        self.y.copy(&P.y);
+        self.z.copy(&P.z);
+    }
+
+    /* set self=O */
+    pub fn inf(&mut self) {
+        self.x.zero();
+        self.y.one();
+        self.z.zero();
+    }
+
+    /* set self=-self */
+    pub fn neg(&mut self) {
+        self.y.norm();
+        self.y.neg();
+        self.y.norm();
+    }
+
+    /* Conditional move of Q to self dependant on d */
+    pub fn cmove(&mut self, Q: &ECP8, d: isize) {
+        self.x.cmove(&Q.x, d);
+        self.y.cmove(&Q.y, d);
+        self.z.cmove(&Q.z, d);
+    }
+
+    /* 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: &[ECP8], b: i32) {
+        let mut MP = ECP8::new();
+        let m = b >> 31;
+        let mut babs = (b ^ m) - m;
+
+        babs = (babs - 1) / 2;
+
+        self.cmove(&W[0], ECP8::teq(babs, 0)); // conditional move
+        self.cmove(&W[1], ECP8::teq(babs, 1));
+        self.cmove(&W[2], ECP8::teq(babs, 2));
+        self.cmove(&W[3], ECP8::teq(babs, 3));
+        self.cmove(&W[4], ECP8::teq(babs, 4));
+        self.cmove(&W[5], ECP8::teq(babs, 5));
+        self.cmove(&W[6], ECP8::teq(babs, 6));
+        self.cmove(&W[7], ECP8::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 ECP8) -> bool {
+        let mut a = FP8::new_copy(&self.x);
+        let mut b = FP8::new_copy(&Q.x);
+
+        a.mul(&Q.z);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+        a.copy(&self.y);
+        a.mul(&Q.z);
+        b.copy(&Q.y);
+        b.mul(&self.z);
+        if !a.equals(&mut b) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /* set to Affine - (x,y,z) to (x,y) */
+    pub fn affine(&mut self) {
+        if self.is_infinity() {
+            return;
+        }
+        let mut one = FP8::new_int(1);
+        if self.z.equals(&mut one) {
+            return;
+        }
+        self.z.inverse();
+
+        self.x.mul(&self.z);
+        self.x.reduce();
+        self.y.mul(&self.z);
+        self.y.reduce();
+        self.z.copy(&one);
+    }
+
+    /* extract affine x as FP8 */
+    pub fn getx(&self) -> FP8 {
+        let mut W = ECP8::new();
+        W.copy(self);
+        W.affine();
+        return FP8::new_copy(&W.x);
+    }
+
+    /* extract affine y as FP8 */
+    pub fn gety(&self) -> FP8 {
+        let mut W = ECP8::new();
+        W.copy(self);
+        W.affine();
+        return FP8::new_copy(&W.y);
+    }
+
+    /* extract projective x */
+    pub fn getpx(&self) -> FP8 {
+        return FP8::new_copy(&self.x);
+    }
+    /* extract projective y */
+    pub fn getpy(&self) -> FP8 {
+        return FP8::new_copy(&self.y);
+    }
+    /* extract projective z */
+    pub fn getpz(&self) -> FP8 {
+        return FP8::new_copy(&self.z);
+    }
+
+    /* convert to byte array */
+    pub fn tobytes(&self, b: &mut [u8]) {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+        let mut W = ECP8::new();
+        W.copy(self);
+
+        W.affine();
+
+        W.x.geta().geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i] = t[i]
+        }
+        W.x.geta().geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + mb] = t[i]
+        }
+
+        W.x.geta().getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 2 * mb] = t[i]
+        }
+        W.x.geta().getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 3 * mb] = t[i]
+        }
+
+        W.x.getb().geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 4 * mb] = t[i]
+        }
+        W.x.getb().geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 5 * mb] = t[i]
+        }
+
+        W.x.getb().getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 6 * mb] = t[i]
+        }
+        W.x.getb().getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 7 * mb] = t[i]
+        }
+
+        W.y.geta().geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 8 * mb] = t[i]
+        }
+        W.y.geta().geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 9 * mb] = t[i]
+        }
+
+        W.y.geta().getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 10 * mb] = t[i]
+        }
+        W.y.geta().getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 11 * mb] = t[i]
+        }
+
+        W.y.getb().geta().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 12 * mb] = t[i]
+        }
+        W.y.getb().geta().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 13 * mb] = t[i]
+        }
+
+        W.y.getb().getb().geta().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 14 * mb] = t[i]
+        }
+        W.y.getb().getb().getb().tobytes(&mut t);
+        for i in 0..mb {
+            b[i + 15 * mb] = t[i]
+        }
+    }
+
+    /* convert from byte array to point */
+    pub fn frombytes(b: &[u8]) -> ECP8 {
+        let mut t: [u8; big::MODBYTES as usize] = [0; big::MODBYTES as usize];
+        let mb = big::MODBYTES as usize;
+
+        for i in 0..mb {
+            t[i] = b[i]
+        }
+        let mut ra = BIG::frombytes(&t);
+        for i in 0..mb {
+            t[i] = b[i + mb]
+        }
+        let mut rb = BIG::frombytes(&t);
+
+        let mut ra4 = 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 mut rb4 = FP2::new_bigs(&ra, &rb);
+
+        let mut ra8 = FP4::new_fp2s(&ra4, &rb4);
+
+        for i in 0..mb {
+            t[i] = b[i + 4 * mb]
+        }
+        let mut ra = BIG::frombytes(&t);
+        for i in 0..mb {
+            t[i] = b[i + 5 * mb]
+        }
+        let mut rb = BIG::frombytes(&t);
+
+        ra4.copy(&FP2::new_bigs(&ra, &rb));
+
+        for i in 0..mb {
+            t[i] = b[i + 6 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 7 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        rb4.copy(&FP2::new_bigs(&ra, &rb));
+
+        let mut rb8 = FP4::new_fp2s(&ra4, &rb4);
+
+        let rx = FP8::new_fp4s(&ra8, &rb8);
+
+        for i in 0..mb {
+            t[i] = b[i + 8 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 9 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        ra4.copy(&FP2::new_bigs(&ra, &rb));
+
+        for i in 0..mb {
+            t[i] = b[i + 10 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 11 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        rb4.copy(&FP2::new_bigs(&ra, &rb));
+
+        ra8.copy(&FP4::new_fp2s(&ra4, &rb4));
+
+        for i in 0..mb {
+            t[i] = b[i + 12 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 13 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        ra4.copy(&FP2::new_bigs(&ra, &rb));
+
+        for i in 0..mb {
+            t[i] = b[i + 14 * mb]
+        }
+        ra.copy(&BIG::frombytes(&t));
+        for i in 0..mb {
+            t[i] = b[i + 15 * mb]
+        }
+        rb.copy(&BIG::frombytes(&t));
+
+        rb4.copy(&FP2::new_bigs(&ra, &rb));
+
+        rb8.copy(&FP4::new_fp2s(&ra4, &rb4));
+
+        let ry = FP8::new_fp4s(&ra8, &rb8);
+
+        return ECP8::new_fp8s(&rx, &ry);
+    }
+
+    /* convert this to hex string */
+    pub fn tostring(&self) -> String {
+        let mut W = ECP8::new();
+        W.copy(self);
+        W.affine();
+        if W.is_infinity() {
+            return String::from("infinity");
+        }
+        return format!("({},{})", W.x.tostring(), W.y.tostring());
+    }
+
+    /* Calculate RHS of twisted curve equation x^3+B/i */
+    pub fn rhs(x: &FP8) -> FP8 {
+        let mut r = FP8::new_copy(x);
+        r.sqr();
+        let mut b = FP8::new_fp4(&FP4::new_fp2(&FP2::new_big(&BIG::new_ints(&rom::CURVE_B))));
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            b.div_i();
+        }
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            b.times_i();
+        }
+
+        r.mul(x);
+        r.add(&b);
+
+        r.reduce();
+        return r;
+    }
+
+    /* self+=self */
+    pub fn dbl(&mut self) -> isize {
+        let mut iy = FP8::new_copy(&self.y);
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            iy.times_i(); //iy.norm();
+        }
+
+        let mut t0 = FP8::new_copy(&self.y);
+        t0.sqr();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.times_i();
+        }
+        let mut t1 = FP8::new_copy(&iy);
+        t1.mul(&self.z);
+        let mut t2 = FP8::new_copy(&self.z);
+        t2.sqr();
+
+        self.z.copy(&t0);
+        self.z.add(&t0);
+        self.z.norm();
+        self.z.dbl();
+        self.z.dbl();
+        self.z.norm();
+
+        t2.imul(3 * rom::CURVE_B_I);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.times_i();
+        }
+        let mut x3 = FP8::new_copy(&t2);
+        x3.mul(&self.z);
+
+        let mut y3 = FP8::new_copy(&t0);
+
+        y3.add(&t2);
+        y3.norm();
+        self.z.mul(&t1);
+        t1.copy(&t2);
+        t1.add(&t2);
+        t2.add(&t1);
+        t2.norm();
+        t0.sub(&t2);
+        t0.norm(); //y^2-9bz^2
+        y3.mul(&t0);
+        y3.add(&x3); //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+        t1.copy(&self.x);
+        t1.mul(&iy); //
+        self.x.copy(&t0);
+        self.x.norm();
+        self.x.mul(&t1);
+        self.x.dbl(); //(y^2-9bz^2)xy2
+
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+
+        return 1;
+    }
+
+    /* self+=Q - return 0 for add, 1 for double, -1 for O */
+    pub fn add(&mut self, Q: &ECP8) -> isize {
+        let b = 3 * rom::CURVE_B_I;
+        let mut t0 = FP8::new_copy(&self.x);
+        t0.mul(&Q.x); // x.Q.x
+        let mut t1 = FP8::new_copy(&self.y);
+        t1.mul(&Q.y); // y.Q.y
+
+        let mut t2 = FP8::new_copy(&self.z);
+        t2.mul(&Q.z);
+        let mut t3 = FP8::new_copy(&self.x);
+        t3.add(&self.y);
+        t3.norm(); //t3=X1+Y1
+        let mut t4 = FP8::new_copy(&Q.x);
+        t4.add(&Q.y);
+        t4.norm(); //t4=X2+Y2
+        t3.mul(&t4); //t3=(X1+Y1)(X2+Y2)
+        t4.copy(&t0);
+        t4.add(&t1); //t4=X1.X2+Y1.Y2
+
+        t3.sub(&t4);
+        t3.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t3.times_i(); //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+        }
+        t4.copy(&self.y);
+        t4.add(&self.z);
+        t4.norm(); //t4=Y1+Z1
+        let mut x3 = FP8::new_copy(&Q.y);
+        x3.add(&Q.z);
+        x3.norm(); //x3=Y2+Z2
+
+        t4.mul(&x3); //t4=(Y1+Z1)(Y2+Z2)
+        x3.copy(&t1); //
+        x3.add(&t2); //X3=Y1.Y2+Z1.Z2
+
+        t4.sub(&x3);
+        t4.norm();
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t4.times_i(); //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+        }
+        x3.copy(&self.x);
+        x3.add(&self.z);
+        x3.norm(); // x3=X1+Z1
+        let mut y3 = FP8::new_copy(&Q.x);
+        y3.add(&Q.z);
+        y3.norm(); // y3=X2+Z2
+        x3.mul(&y3); // x3=(X1+Z1)(X2+Z2)
+        y3.copy(&t0);
+        y3.add(&t2); // y3=X1.X2+Z1+Z2
+        y3.rsub(&x3);
+        y3.norm(); // y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+        if ecp::SEXTIC_TWIST == SexticTwist::D_TYPE {
+            t0.times_i(); // x.Q.x
+            t1.times_i(); // y.Q.y
+        }
+        x3.copy(&t0);
+        x3.add(&t0);
+        t0.add(&x3);
+        t0.norm();
+        t2.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            t2.times_i();
+        }
+        let mut z3 = FP8::new_copy(&t1);
+        z3.add(&t2);
+        z3.norm();
+        t1.sub(&t2);
+        t1.norm();
+        y3.imul(b);
+        if ecp::SEXTIC_TWIST == SexticTwist::M_TYPE {
+            y3.times_i();
+        }
+        x3.copy(&y3);
+        x3.mul(&t4);
+        t2.copy(&t3);
+        t2.mul(&t1);
+        x3.rsub(&t2);
+        y3.mul(&t0);
+        t1.mul(&z3);
+        y3.add(&t1);
+        t0.mul(&t3);
+        z3.mul(&t4);
+        z3.add(&t0);
+
+        self.x.copy(&x3);
+        self.x.norm();
+        self.y.copy(&y3);
+        self.y.norm();
+        self.z.copy(&z3);
+        self.z.norm();
+
+        return 0;
+    }
+
+    /* set this-=Q */
+    pub fn sub(&mut self, Q: &ECP8) -> isize {
+        let mut NQ = ECP8::new();
+        NQ.copy(Q);
+        NQ.neg();
+        let d = self.add(&NQ);
+        return d;
+    }
+
+    pub fn frob_constants() -> [FP2; 3] {
+        let f = FP2::new_bigs(&BIG::new_ints(&rom::FRA), &BIG::new_ints(&rom::FRB));
+
+        let mut f0 = FP2::new_copy(&f);
+        f0.sqr();
+        let mut f2 = FP2::new_copy(&f0);
+        f2.mul_ip();
+        f2.norm();
... 24926 lines suppressed ...


[incubator-milagro-crypto-rust] 09/44: Merge pull request #5 from sigp/formatting

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit d358b74b046d859d2b9f3aa2b3506bc582678103
Merge: 176c3f5 8626350
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Thu Aug 8 06:53:14 2019 +0100

    Merge pull request #5 from sigp/formatting
    
    A lot of Formatting and style

 .gitignore                    |   1 +
 BenchtestALL.rs               |  16 +-
 Cargo.toml                    |  12 +-
 readme.md                     |  37 ++--
 src/aes.rs                    |  65 +++---
 src/big.rs                    | 461 ++++++++++++++++++++----------------------
 src/bls.rs                    |  33 ++-
 src/bls192.rs                 |  29 ++-
 src/bls256.rs                 |  31 ++-
 src/dbig.rs                   | 123 +++++------
 src/ecdh.rs                   | 154 +++++++-------
 src/ecp.rs                    | 164 +++++++--------
 src/ecp2.rs                   | 124 ++++++------
 src/ecp4.rs                   | 100 ++++-----
 src/ecp8.rs                   | 156 +++++++-------
 src/ff.rs                     |  60 +++---
 src/fp.rs                     | 180 ++++++++---------
 src/fp12.rs                   |  84 ++++----
 src/fp16.rs                   |  30 +--
 src/fp2.rs                    |  32 +--
 src/fp24.rs                   | 102 +++++-----
 src/fp4.rs                    |  32 +--
 src/fp48.rs                   | 166 +++++++--------
 src/fp8.rs                    |  30 +--
 src/hash256.rs                |  16 +-
 src/mpin.rs                   | 160 +++++++--------
 src/mpin192.rs                |  70 +++----
 src/mpin256.rs                |  70 +++----
 src/nhs.rs                    |  10 +-
 src/pair.rs                   | 214 ++++++++++----------
 src/pair192.rs                | 130 ++++++------
 src/pair256.rs                | 178 ++++++++--------
 src/rand.rs                   |   2 +-
 src/roms/rom_anssi_32.rs      |  10 +-
 src/roms/rom_anssi_64.rs      |  10 +-
 src/roms/rom_bls24_32.rs      |  10 +-
 src/roms/rom_bls24_64.rs      |  10 +-
 src/roms/rom_bls381_32.rs     |  10 +-
 src/roms/rom_bls381_64.rs     |  10 +-
 src/roms/rom_bls383_32.rs     |  10 +-
 src/roms/rom_bls383_64.rs     |  10 +-
 src/roms/rom_bls461_32.rs     |  10 +-
 src/roms/rom_bls461_64.rs     |  10 +-
 src/roms/rom_bls48_32.rs      |  10 +-
 src/roms/rom_bls48_64.rs      |  10 +-
 src/roms/rom_bn254CX_32.rs    |  10 +-
 src/roms/rom_bn254CX_64.rs    |  10 +-
 src/roms/rom_bn254_32.rs      |  10 +-
 src/roms/rom_bn254_64.rs      |  10 +-
 src/roms/rom_brainpool_32.rs  |  10 +-
 src/roms/rom_brainpool_64.rs  |  10 +-
 src/roms/rom_c25519_32.rs     |  10 +-
 src/roms/rom_c25519_64.rs     |  10 +-
 src/roms/rom_c41417_32.rs     |  10 +-
 src/roms/rom_c41417_64.rs     |  10 +-
 src/roms/rom_ed25519_32.rs    |  10 +-
 src/roms/rom_ed25519_64.rs    |  10 +-
 src/roms/rom_fp256bn_32.rs    |  10 +-
 src/roms/rom_fp256bn_64.rs    |  10 +-
 src/roms/rom_fp512bn_32.rs    |  10 +-
 src/roms/rom_fp512bn_64.rs    |  10 +-
 src/roms/rom_goldilocks_32.rs |  10 +-
 src/roms/rom_goldilocks_64.rs |  10 +-
 src/roms/rom_hifive_32.rs     |  10 +-
 src/roms/rom_hifive_64.rs     |  10 +-
 src/roms/rom_nist256_32.rs    |  10 +-
 src/roms/rom_nist256_64.rs    |  10 +-
 src/roms/rom_nist384_32.rs    |  10 +-
 src/roms/rom_nist384_64.rs    |  10 +-
 src/roms/rom_nist521_32.rs    |  10 +-
 src/roms/rom_nist521_64.rs    |  10 +-
 src/roms/rom_nums256e_32.rs   |  10 +-
 src/roms/rom_nums256e_64.rs   |  10 +-
 src/roms/rom_nums256w_32.rs   |  10 +-
 src/roms/rom_nums256w_64.rs   |  10 +-
 src/roms/rom_nums384e_32.rs   |  10 +-
 src/roms/rom_nums384e_64.rs   |  10 +-
 src/roms/rom_nums384w_32.rs   |  10 +-
 src/roms/rom_nums384w_64.rs   |  10 +-
 src/roms/rom_nums512e_32.rs   |  10 +-
 src/roms/rom_nums512e_64.rs   |  10 +-
 src/roms/rom_nums512w_32.rs   |  10 +-
 src/roms/rom_nums512w_64.rs   |  10 +-
 src/roms/rom_secp256k1_32.rs  |  10 +-
 src/roms/rom_secp256k1_64.rs  |  10 +-
 src/sha3.rs                   |   2 +-
 src/types.rs                  |  38 ++--
 87 files changed, 1810 insertions(+), 1822 deletions(-)


[incubator-milagro-crypto-rust] 21/44: Fix issue displaying FP values

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit a8d03306201b9654658201d8eefb4dcd99c0b2d7
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Thu Jan 23 10:15:36 2020 +1100

    Fix issue displaying FP values
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 src/fp.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/fp.rs b/src/fp.rs
index 72b7390..54eff31 100644
--- a/src/fp.rs
+++ b/src/fp.rs
@@ -40,13 +40,13 @@ impl PartialEq for FP {
 
 impl fmt::Display for FP {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "FP: [ {} ]", self.x)
+        write!(f, "FP: [ {} ]", self.tostring())
     }
 }
 
 impl fmt::Debug for FP {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "FP: [ {} ]", self.x)
+        write!(f, "FP: [ {} ]", self.tostring())
     }
 }
 


[incubator-milagro-crypto-rust] 36/44: Merge pull request #17 from sigp/standard-update

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit d6bd9142892f169fb0d01a8746dbdf9fd2458608
Merge: d9bdc2f 17c208e
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Tue Apr 21 09:48:36 2020 +0100

    Merge pull request #17 from sigp/standard-update
    
    Write hash to curve functions for BLS381 G1 and G2

 Cargo.lock                                         | 662 +++++++++++++++++++++
 Cargo.toml                                         |  16 +-
 src/big.rs                                         |  11 +-
 src/bls.rs                                         |   6 +-
 src/bls256.rs                                      |   6 +-
 src/bls381.rs                                      | 424 +++++++++++++
 src/bls381/iso.rs                                  | 335 +++++++++++
 src/dbig.rs                                        |  21 +-
 src/ecdh.rs                                        |   3 +-
 src/ecp.rs                                         |  23 +
 src/ecp2.rs                                        |  45 +-
 src/errors.rs                                      |   4 +
 src/fp.rs                                          |  76 ++-
 src/fp2.rs                                         |  23 +
 src/hash256.rs                                     | 266 ++++++++-
 src/hash384.rs                                     | 228 +++++--
 src/hash512.rs                                     | 296 ++++++++-
 src/hash_to_curve.rs                               | 307 ++++++++++
 src/lib.rs                                         |  45 +-
 src/nhs.rs                                         |   1 -
 src/roms/{rom_bls381_32.rs => rom_bls381g1_32.rs}  |  36 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g1_64.rs}  |  38 +-
 src/roms/{rom_bls381_32.rs => rom_bls381g2_32.rs}  |  38 +-
 src/roms/{rom_bls381_64.rs => rom_bls381g2_64.rs}  |  38 +-
 .../BLS12381G1_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G1_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SSWU_RO_.json           |  97 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_NU_.json           |  77 +++
 .../BLS12381G2_XMD:SHA-256_SVDW_RO_.json           |  97 +++
 src/test_utils/mod.rs                              |  20 +
 src/test_utils/test_vector_structs.rs              |  44 ++
 34 files changed, 3550 insertions(+), 158 deletions(-)


[incubator-milagro-crypto-rust] 42/44: Merge branch 'standard-update' into hash-to-curve-07

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 9a2581fcaa8ad50a9ee23ef1b7d4774ad94a4859
Merge: cc1b6e8 1fd5b33
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Mon May 4 17:28:46 2020 +1000

    Merge branch 'standard-update' into hash-to-curve-07

 src/ecp.rs  | 2 ++
 src/ecp2.rs | 2 ++
 src/fp.rs   | 2 ++
 src/fp12.rs | 2 ++
 src/fp2.rs  | 2 ++
 src/fp4.rs  | 2 ++
 6 files changed, 12 insertions(+)



[incubator-milagro-crypto-rust] 20/44: Merge pull request #10 from sigp/features-all

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit 87a97b6296a15cef6be8bc81c05b20757dcc3ffa
Merge: f54d090 b0b021d
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Tue Jan 21 09:08:49 2020 +0000

    Merge pull request #10 from sigp/features-all
    
    All feature

 Cargo.toml | 6 ++++++
 1 file changed, 6 insertions(+)


[incubator-milagro-crypto-rust] 26/44: Update readme

Posted by km...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kmccusker pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git

commit cd3c739eb43e92e5c359670a81a6bb1d45cf6c72
Author: Kirk Baird <ba...@outlook.com>
AuthorDate: Wed Mar 25 19:02:22 2020 +1100

    Update readme
    
    Signed-off-by: Kirk Baird <ba...@outlook.com>
---
 readme.md | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/readme.md b/readme.md
index 17091d5..b739d74 100644
--- a/readme.md
+++ b/readme.md
@@ -1,5 +1,7 @@
 # Apache Milagro Crypto Library - Rust Version
 
+## Updates
+
 NOTE: Updated to Rust 2018
 
 NOTE: This version of the library requires Version 1.31+ of Rust for 64-bit
@@ -9,6 +11,20 @@ Now AMCL version 3 is distributed as a cargo crate.
 
 Namespaces are used to separate different curves.
 
+## Testing
+
+Unit testing can be done using cargo testing framework. it is recommended to
+run these in release mode as some tests especially `mpin` tests are very slow.
+
+Additional `--all-features` can be replaced by `--features xx` where `xx` is
+the desired feature e.g. `bls381`.
+
+```
+cargo test --all --all-features --release
+```
+
+## Benchmarking
+
 To build the library and see it in action, copy all of the files in this
 directory and its subdirectories to a fresh root directory.
 
@@ -23,13 +39,7 @@ This will create a build of the library for the current default target (be it 32
 Next copy the library from `target/release/libamcl.rlib` into the root
 directory and execute
 ```
-rustc TestALL.rs --extern amcl=libamcl.rlib
-
-rustc TestBLS.rs --extern amcl=libamcl.rlib
-
 rustc BenchtestALL.rs --extern amcl=libamcl.rlib
-
-rustc TestNHS.rs --extern amcl=libamcl.rlib
 ```
 
 Finally execute these programs.
@@ -54,7 +64,7 @@ And to use primitives of the needed curve in your source code:
 use amcl::bls48::{ECP, ECP8}; // any primitive you need
 ```
 
-Full list of features:
+## Features
 
 * Elliptic Curves
   * ed25519
@@ -88,3 +98,10 @@ Full list of features:
   * rsa2048
   * rsa3072
   * rsa4096
+* SHA-2
+  * SHA256
+  * SHA384
+  * SHA512
+
+Note `SHA-2` features will always be compiled however all other features require
+the feature flag `--features xx`