Merge pull request #7 from apache/update

update code
diff --git a/version3/c/arch.h b/version3/c/arch.h
index 1de0332..aa726db 100644
--- a/version3/c/arch.h
+++ b/version3/c/arch.h
@@ -110,12 +110,9 @@
 /**< Note - no 128-bit type available    */
 #else
 #define chunk int64_t		/**< C type corresponding to word length */
-#ifdef __GNUC__
-#define dchunk __int128		/**< Always define double length chunk type if available - GCC supports 128 bit type  ??? */
-#endif
 
-#ifdef __clang__
-#define dchunk __int128
+#if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
+#define dchunk __int128                /**< Always define double length chunk type if available (supported by GCC & Clang on 64-bit architectures) */
 #endif
 
 #endif
diff --git a/version3/c/big.c b/version3/c/big.c
index 3b1a655..664cccf 100644
--- a/version3/c/big.c
+++ b/version3/c/big.c
@@ -1466,6 +1466,20 @@
     for (i=wd+1; i<NLEN_XXX; i++) x[i]=0;
 }
 
+/* set x = x mod 2^m */
+void BIG_XXX_dmod2m(DBIG_XXX x,int m)
+{
+    int i,wd,bt;
+    chunk msk;
+    BIG_XXX_norm(x);
+
+    wd=m/BASEBITS_XXX;
+    bt=m%BASEBITS_XXX;
+    msk=((chunk)1<<bt)-1;
+    x[wd]&=msk;
+    for (i=wd+1; i<DNLEN_XXX; i++) x[i]=0;
+}
+
 // new
 /* Convert to DBIG number from byte array of given length */
 void BIG_XXX_dfromBytesLen(DBIG_XXX a,char *b,int s)
diff --git a/version3/c/big.h b/version3/c/big.h
index 36b0c7c..7874450 100644
--- a/version3/c/big.h
+++ b/version3/c/big.h
@@ -553,6 +553,14 @@
 */
 extern void BIG_XXX_mod2m(BIG_XXX x,int m);
 
+/** @brief Calculate x=x mod 2^m
+ *
+	Truncation
+	@param x DBIG number, on reduced mod 2^m
+	@param m new truncated size
+*/
+extern void BIG_XXX_dmod2m(DBIG_XXX x,int m);
+
 /**	@brief Calculates a*b+c+*d
  *
 	Calculate partial product of a.b, add in carry c, and add total to d
diff --git a/version3/c/rom_curve_BN254CX.c b/version3/c/rom_curve_BN254CX.c
index 4b85d21..5543f54 100644
--- a/version3/c/rom_curve_BN254CX.c
+++ b/version3/c/rom_curve_BN254CX.c
@@ -58,7 +58,7 @@
 #if CHUNK==64
 
 const int CURVE_Cof_I_BN254CX= 1;
-const int CURVE_A_BN254CX= 1;
+const int CURVE_A_BN254CX= 0;
 const int CURVE_B_I_BN254CX= 2;
 const BIG_256_56 CURVE_B_BN254CX= {0x2L,0x0L,0x0L,0x0L,0x0L};
 const BIG_256_56 CURVE_Order_BN254CX= {0x11C0A636EB1F6DL,0xD6EE0CC906CEBEL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L};
diff --git a/version3/cpp/big.cpp b/version3/cpp/big.cpp
index ae72936..761a9bf 100644
--- a/version3/cpp/big.cpp
+++ b/version3/cpp/big.cpp
@@ -1439,6 +1439,20 @@
     for (i=wd+1; i<NLEN_XXX; i++) x[i]=0;
 }
 
+/* set x = x mod 2^m */
+void XXX::BIG_dmod2m(DBIG x,int m)
+{
+    int i,wd,bt;
+    chunk msk;
+	BIG_norm(x);
+
+    wd=m/BASEBITS_XXX;
+    bt=m%BASEBITS_XXX;
+    msk=((chunk)1<<bt)-1;
+    x[wd]&=msk;
+    for (i=wd+1; i<DNLEN_XXX; i++) x[i]=0;
+}
+
 // new
 /* Convert to DBIG number from byte array of given length */
 void XXX::BIG_dfromBytesLen(DBIG a,char *b,int s)
diff --git a/version3/cpp/big.h b/version3/cpp/big.h
index 1f4f451..08c50e3 100644
--- a/version3/cpp/big.h
+++ b/version3/cpp/big.h
@@ -537,6 +537,14 @@
 */
 extern void BIG_mod2m(BIG x,int m);
 
+/** @brief Calculate x=x mod 2^m
+ *
+	Truncation
+	@param x DBIG number, on reduced mod 2^m
+	@param m new truncated size
+*/
+extern void BIG_dmod2m(DBIG x,int m);
+
 /**	@brief Calculates a*b+c+*d
  *
 	Calculate partial product of a.b, add in carry c, and add total to d
diff --git a/version3/cpp/ecp.cpp b/version3/cpp/ecp.cpp
index 020c667..237e04e 100644
--- a/version3/cpp/ecp.cpp
+++ b/version3/cpp/ecp.cpp
@@ -257,7 +257,7 @@
 {
 	ECP W;
 	ECP_copy(&W,P);
-	ECP_affine(W);
+	ECP_affine(&W);
     if (ECP_isinf(&W)) return -1;
     FP_redc(x,&(W.x));
     return 0;
diff --git a/version3/cpp/rom_field_NIST521.cpp b/version3/cpp/rom_field_NIST521.cpp
index a92393c..2521618 100644
--- a/version3/cpp/rom_field_NIST521.cpp
+++ b/version3/cpp/rom_field_NIST521.cpp
@@ -23,7 +23,7 @@
 
 #if CHUNK==64
 
-using namespace B528_56;
+using namespace B528_60;
 
 // Base Bits= 60
 const BIG Modulus= {0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0x1FFFFFFFFFFL};
diff --git a/version3/go/DBIG.go b/version3/go/DBIG.go
index d3afc77..e73ba22 100644
--- a/version3/go/DBIG.go
+++ b/version3/go/DBIG.go
@@ -169,6 +169,17 @@
 	}
 }
 
+/* set x = x mod 2^m */
+func (r *BIG) mod2m(m uint) {
+	wd := int(m / BASEBITS)
+	bt := m % BASEBITS
+	msk := (Chunk(1) << bt) - 1
+	r.w[wd] &= msk
+	for i := wd + 1; i < DNLEN; i++ {
+		r.w[i] = 0
+	}
+}
+
 /* reduces this DBIG mod a BIG, and returns the BIG */
 func (r *DBIG) mod(c *BIG) *BIG {
 	r.norm()
diff --git a/version3/go/ROM_SECP256K1_64.go b/version3/go/ROM_SECP256K1_64.go
index ef4ae91..1dc205c 100644
--- a/version3/go/ROM_SECP256K1_64.go
+++ b/version3/go/ROM_SECP256K1_64.go
@@ -19,7 +19,7 @@
 
 /* Fixed Data in ROM - Field and Curve parameters */
 
-package NIST256
+package SECP256K1
 
 // Base Bits= 56
 
diff --git a/version3/java/DBIG32.java b/version3/java/DBIG32.java
index c5a6d94..f010f5b 100644
--- a/version3/java/DBIG32.java
+++ b/version3/java/DBIG32.java
@@ -228,6 +228,16 @@
 		return new BIG(this);
 	}
 
+	/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/CONFIG_BIG.BASEBITS;
+		bt=m%CONFIG_BIG.BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
 /* return this/c */
 	public BIG div(BIG c)
 	{
diff --git a/version3/java/DBIG64.java b/version3/java/DBIG64.java
index 473f40b..db1d70e 100644
--- a/version3/java/DBIG64.java
+++ b/version3/java/DBIG64.java
@@ -226,6 +226,16 @@
 		return new BIG(this);
 	}
 
+	/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/CONFIG_BIG.BASEBITS;
+		bt=m%CONFIG_BIG.BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
 /* return this/c */
 	public BIG div(BIG c)
 	{
diff --git a/version3/js/fp.js b/version3/js/fp.js
index 925c20b..8b96743 100644
--- a/version3/js/fp.js
+++ b/version3/js/fp.js
@@ -31,7 +31,7 @@
         } else {
             this.f = new ctx.BIG(x);
 			this.XES = 1;
-			if (x!=0)
+			if (!this.f.iszilch())
 				this.nres();
         }
     };
@@ -185,7 +185,7 @@
         /* set this=1 */
         one: function() {
             this.f.one();
-            return this.nres();
+            this.nres();
         },
 
         /* normalise this */
diff --git a/version3/js/fp12.js b/version3/js/fp12.js
index c68f3cd..45f2595 100644
--- a/version3/js/fp12.js
+++ b/version3/js/fp12.js
@@ -26,27 +26,32 @@
 
     /* general purpose constructor */
     var FP12 = function(d, e, f) {
-		if (!isNaN(d))
-		{
-			this.a = new ctx.FP4(d);
-			this.b = new ctx.FP4(0);
-			this.c = new ctx.FP4(0);
-			if (d==1) this.stype=ctx.FP.ONE;
-			else this.stype=ctx.FP.SPARSER;
-		}
-		else
-		{
-			if (d instanceof FP12) {
-				this.a = new ctx.FP4(d.a);
-				this.b = new ctx.FP4(d.b);
-				this.c = new ctx.FP4(d.c);
-			} else {
-				this.a = new ctx.FP4(d);
-				this.b = new ctx.FP4(e);
-				this.c = new ctx.FP4(f);
-			}
-			this.stype=ctx.FP.DENSE;
-		}
+        if (d instanceof FP12) {
+            // ignore e, d, which are assumed be undefined in this case
+            this.a = new ctx.FP4(d.a);
+            this.b = new ctx.FP4(d.b);
+            this.c = new ctx.FP4(d.c);
+            this.stype=ctx.FP.DENSE;
+        } else if (typeof d !== "undefined" && typeof e !== "undefined" && typeof f !== "undefined") {
+            // all 3 components set to (can be anything that the FP4 constructor supports)
+            this.a = new ctx.FP4(d);
+            this.b = new ctx.FP4(e);
+            this.c = new ctx.FP4(f);
+            this.stype=ctx.FP.DENSE;
+        } else if (typeof d === "number") {
+            // first component is number
+            this.a = new ctx.FP4(d);
+            this.b = new ctx.FP4(0);
+            this.c = new ctx.FP4(0);
+            if (d==1) this.stype=ctx.FP.ONE;
+            else this.stype=ctx.FP.SPARSER;
+        } else {
+            // other cases, including `new ctx.FP12()` fall back to zero
+            this.a = new ctx.FP4(0);
+            this.b = new ctx.FP4(0);
+            this.c = new ctx.FP4(0);
+            this.stype=ctx.FP.ZERO;
+        }
     };
 
     FP12.prototype = {
diff --git a/version3/readme.txt b/version3/readme.txt
index e648fc1..0e3dcd9 100644
--- a/version3/readme.txt
+++ b/version3/readme.txt
@@ -2,15 +2,14 @@
 
 Several helper programs are provided to assist with the addition of
 new elliptic curves. Note that these programs will not be needed if using
-one of the supported curves. These programs must be build using the MIRACL
+one of the supported curves. These programs must be built using the MIRACL
 library. See source code for compilation instructions
 
 bigtobig.cpp - converts to BIG number format
 
 check.cpp - checks for optimal choice of number base
 
-bestpair.cpp - finds best BN, BLS12 and BLS24 pairing-friendly curves
-(Note - the library does not currently support BLS24 curves)
+bestpair.cpp - finds best BN, BLS12, BLS24 and BLS48 pairing-friendly curves
 
 romgen.cpp - rough-and-ready program used to help generate ROM files for
 all of the different languages.
diff --git a/version3/rust/src/dbig.rs b/version3/rust/src/dbig.rs
index d987d97..353443a 100644
--- a/version3/rust/src/dbig.rs
+++ b/version3/rust/src/dbig.rs
@@ -22,10 +22,15 @@
 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 {
@@ -243,6 +248,17 @@
         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;
diff --git a/version3/rust/src/ecp.rs b/version3/rust/src/ecp.rs
index a6856a8..9e7b29c 100644
--- a/version3/rust/src/ecp.rs
+++ b/version3/rust/src/ecp.rs
@@ -192,20 +192,11 @@
 
     /* test for O point-at-infinity */
     pub fn is_infinity(&self) -> bool {
-        let xx = FP::new_copy(&self.x);
-        let zz = FP::new_copy(&self.z);
-
-        if CURVETYPE == CurveType::EDWARDS {
-            let yy = FP::new_copy(&self.y);
-            return xx.iszilch() && yy.equals(&zz);
+        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(),
         }
-        if CURVETYPE == CurveType::WEIERSTRASS {
-            return xx.iszilch() && zz.iszilch();
-        }
-        if CURVETYPE == CurveType::MONTGOMERY {
-            return zz.iszilch();
-        }
-        return true;
     }
 
     /* Conditional swap of P and Q dependant on d */
@@ -1202,6 +1193,7 @@
         return S;
     }
 
+    // Multiply itself by cofactor of the curve
     pub fn cfp(&mut self) {
         let cf = rom::CURVE_COF_I;
         if cf == 1 {
@@ -1223,6 +1215,7 @@
         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);
diff --git a/version3/rust/src/ecp2.rs b/version3/rust/src/ecp2.rs
index bd44e40..afd9376 100644
--- a/version3/rust/src/ecp2.rs
+++ b/version3/rust/src/ecp2.rs
@@ -96,9 +96,7 @@
 
     /* Test this=O? */
     pub fn is_infinity(&self) -> bool {
-        let xx = FP2::new_copy(&self.x);
-        let zz = FP2::new_copy(&self.z);
-        return xx.iszilch() && zz.iszilch();
+        self.x.iszilch() && self.z.iszilch()
     }
 
     /* copy self=P */
diff --git a/version3/rust/src/fp.rs b/version3/rust/src/fp.rs
index 5db950e..57345c1 100644
--- a/version3/rust/src/fp.rs
+++ b/version3/rust/src/fp.rs
@@ -312,7 +312,7 @@
         return r;
     }
 
-    // find appoximation to quotient of a/m
+    // 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 {
@@ -590,6 +590,8 @@
             y.sqr();
             self.mul(&y);
         } 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);
             m2.dec(2);
             m2.norm();
diff --git a/version3/swift/dbig.swift b/version3/swift/dbig.swift
index 00e449b..7630d32 100644
--- a/version3/swift/dbig.swift
+++ b/version3/swift/dbig.swift
@@ -135,6 +135,15 @@
         }
         return 0;
     }
+    /* set x = x mod 2^m */
+    mutating func mod2m(_ m: UInt)
+    {
+        let wd=Int(m/CONFIG_BIG.BASEBITS)
+        let bt=m%CONFIG_BIG.BASEBITS
+        let msk=Chunk(1<<bt)-1;
+        w[wd]&=msk;
+        for i in wd+1 ..< CONFIG_BIG.DNLEN {w[i]=0}
+    }
     /* normalise BIG - force all digits < 2^BASEBITS */
     mutating func norm()
     {