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 2019/05/30 09:40:20 UTC

[incubator-milagro-crypto] branch bug-fix created (now f9be3e8)

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

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


      at f9be3e8  bug fixes / updates

This branch includes the following new commits:

     new f9be3e8  bug fixes / updates

The 1 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.



[incubator-milagro-crypto] 01/01: bug fixes / updates

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

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

commit f9be3e845f9569424b1de88f43562eb49f88d4a2
Author: Kealan McCusker <ke...@qredo.com>
AuthorDate: Thu May 30 10:40:02 2019 +0100

    bug fixes / updates
---
 version3/c/fp12.c            |  8 +++++
 version3/c/fp12.h            |  7 ++++
 version3/c/fp24.c            |  8 +++++
 version3/c/fp24.h            |  7 ++++
 version3/c/fp48.c            |  8 +++++
 version3/c/fp48.h            |  7 ++++
 version3/c/pair.c            |  6 ++++
 version3/c/pair192.c         |  5 +++
 version3/c/pair256.c         |  6 ++++
 version3/cpp/fp12.cpp        |  8 +++++
 version3/cpp/fp12.h          |  8 +++++
 version3/cpp/fp24.cpp        |  8 +++++
 version3/cpp/fp24.h          |  7 ++++
 version3/cpp/fp48.cpp        |  8 +++++
 version3/cpp/fp48.h          |  7 ++++
 version3/cpp/pair.cpp        |  5 +++
 version3/cpp/pair192.cpp     |  5 +++
 version3/cpp/pair256.cpp     |  6 +++-
 version3/go/AES.go           | 19 +++++++++--
 version3/go/BIG32.go         |  2 +-
 version3/go/BIG64.go         |  2 +-
 version3/go/BLS.go           |  2 +-
 version3/go/BLS192.go        |  2 +-
 version3/go/BLS256.go        |  2 +-
 version3/go/BenchtestALL.go  | 18 +++++-----
 version3/go/ECDH.go          |  2 +-
 version3/go/ECP.go           | 44 ++++++++++++------------
 version3/go/ECP2.go          |  4 +--
 version3/go/ECP4.go          |  4 +--
 version3/go/ECP8.go          |  4 +--
 version3/go/FF32.go          |  2 +-
 version3/go/FF64.go          |  2 +-
 version3/go/FP.go            | 11 ++++--
 version3/go/FP12.go          | 65 ++++++++++++++++++++++-------------
 version3/go/FP16.go          | 23 ++++++++-----
 version3/go/FP2.go           | 19 +++++++----
 version3/go/FP24.go          | 55 +++++++++++++++++++-----------
 version3/go/FP4.go           | 23 ++++++++-----
 version3/go/FP48.go          | 55 +++++++++++++++++++-----------
 version3/go/FP8.go           | 23 ++++++++-----
 version3/go/MPIN.go          |  2 +-
 version3/go/MPIN192.go       |  2 +-
 version3/go/MPIN256.go       |  2 +-
 version3/go/PAIR.go          | 14 +++++---
 version3/go/PAIR192.go       | 15 +++++----
 version3/go/PAIR256.go       | 15 +++++----
 version3/go/RSA.go           |  2 +-
 version3/go/TestALL.go       | 18 +++++-----
 version3/go/TestBLS.go       | 10 +++---
 version3/go/TestNHS.go       |  2 +-
 version3/go/readme.txt       |  7 ++--
 version3/java/AES.java       | 18 ++++++++--
 version3/java/ECP.java       | 44 ++++++++++++------------
 version3/java/ECP2.java      |  4 +--
 version3/java/ECP4.java      |  4 +--
 version3/java/ECP8.java      |  4 +--
 version3/java/FP12.java      | 62 ++++++++++++++++++++++------------
 version3/java/FP16.java      | 22 +++++++-----
 version3/java/FP2.java       | 18 ++++++----
 version3/java/FP24.java      | 57 ++++++++++++++++++++-----------
 version3/java/FP32.java      |  1 +
 version3/java/FP4.java       | 22 +++++++-----
 version3/java/FP48.java      | 58 +++++++++++++++++++++-----------
 version3/java/FP64.java      |  1 +
 version3/java/FP8.java       | 22 +++++++-----
 version3/java/OLDECP.java    | 44 ++++++++++++------------
 version3/java/OLDECP2.java   |  4 +--
 version3/java/PAIR.java      | 15 ++++++---
 version3/java/PAIR192.java   | 18 ++++++----
 version3/java/PAIR256.java   | 18 ++++++----
 version3/js/aes.js           | 21 ++++++++++--
 version3/js/fp.js            |  6 ++--
 version3/js/fp12.js          |  8 +++++
 version3/js/fp24.js          |  8 +++++
 version3/js/fp48.js          |  8 +++++
 version3/js/pair.js          |  6 +++-
 version3/js/pair192.js       |  6 +++-
 version3/js/pair256.js       |  6 +++-
 version3/python/fp12.py      |  4 +++
 version3/python/pair.py      |  5 ++-
 version3/rust/src/aes.rs     | 32 ++++++++++++++----
 version3/rust/src/ecp8.rs    | 80 ++++++++++++++++++++++++++++++++++++--------
 version3/rust/src/fp12.rs    |  8 +++++
 version3/rust/src/fp24.rs    |  8 +++++
 version3/rust/src/fp48.rs    |  8 +++++
 version3/rust/src/pair.rs    |  5 +++
 version3/rust/src/pair192.rs |  5 ++-
 version3/rust/src/pair256.rs |  5 ++-
 version3/swift/aes.swift     | 62 +++++++++++++++++++++++-----------
 version3/swift/ecdh.swift    |  4 +--
 version3/swift/ecp.swift     | 44 ++++++++++++------------
 version3/swift/ecp2.swift    |  4 +--
 version3/swift/ecp4.swift    |  4 +--
 version3/swift/ecp8.swift    |  4 +--
 version3/swift/fp.swift      |  4 +--
 version3/swift/fp12.swift    | 66 +++++++++++++++++++++++-------------
 version3/swift/fp16.swift    | 22 +++++++-----
 version3/swift/fp2.swift     | 18 ++++++----
 version3/swift/fp24.swift    | 68 +++++++++++++++++++++++--------------
 version3/swift/fp4.swift     | 22 +++++++-----
 version3/swift/fp48.swift    | 72 ++++++++++++++++++++++++---------------
 version3/swift/fp8.swift     | 22 +++++++-----
 version3/swift/gcm.swift     |  4 +--
 version3/swift/pair.swift    | 17 ++++++----
 version3/swift/pair192.swift | 17 ++++++----
 version3/swift/pair256.swift | 17 ++++++----
 version3/swift/readme.txt    | 16 +++++++++
 version3/wasm/config.py      | 64 +++++++++++++++++++----------------
 108 files changed, 1228 insertions(+), 584 deletions(-)

diff --git a/version3/c/fp12.c b/version3/c/fp12.c
index a6a7830..726e9ec 100644
--- a/version3/c/fp12.c
+++ b/version3/c/fp12.c
@@ -95,6 +95,14 @@ void FP12_YYY_one(FP12_YYY *w)
 	w->type=FP_UNITY;
 }
 
+void FP12_YYY_zero(FP12_YYY *w)
+{
+    FP4_YYY_zero(&(w->a));
+    FP4_YYY_zero(&(w->b));
+    FP4_YYY_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int FP12_YYY_equals(FP12_YYY *x,FP12_YYY *y)
diff --git a/version3/c/fp12.h b/version3/c/fp12.h
index bf83a57..bc23ec1 100644
--- a/version3/c/fp12.h
+++ b/version3/c/fp12.h
@@ -68,6 +68,13 @@ extern void FP12_YYY_copy(FP12_YYY *x,FP12_YYY *y);
 	@param x FP12 instance to be set to one
  */
 extern void FP12_YYY_one(FP12_YYY *x);
+
+/**	@brief Set FP12 to zero
+ *
+	@param x FP12 instance to be set to zero
+ */
+extern void FP12_YYY_zero(FP12_YYY *x);
+
 /**	@brief Tests for equality of two FP12s
  *
 	@param x FP12 instance to be compared
diff --git a/version3/c/fp24.c b/version3/c/fp24.c
index 8951b22..8711e96 100644
--- a/version3/c/fp24.c
+++ b/version3/c/fp24.c
@@ -92,6 +92,14 @@ void FP24_YYY_one(FP24_YYY *w)
 	w->type=FP_UNITY;
 }
 
+void FP24_YYY_zero(FP24_YYY *w)
+{
+    FP8_YYY_zero(&(w->a));
+    FP8_YYY_zero(&(w->b));
+    FP8_YYY_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int FP24_YYY_equals(FP24_YYY *x,FP24_YYY *y)
diff --git a/version3/c/fp24.h b/version3/c/fp24.h
index 02e09fa..12b0209 100644
--- a/version3/c/fp24.h
+++ b/version3/c/fp24.h
@@ -42,6 +42,13 @@ extern void FP24_YYY_copy(FP24_YYY *x,FP24_YYY *y);
 	@param x FP24 instance to be set to one
  */
 extern void FP24_YYY_one(FP24_YYY *x);
+
+/**	@brief Set FP24 to zero
+ *
+	@param x FP24 instance to be set to zero
+ */
+extern void FP24_YYY_zero(FP24_YYY *x);
+
 /**	@brief Tests for equality of two FP24s
  *
 	@param x FP24 instance to be compared
diff --git a/version3/c/fp48.c b/version3/c/fp48.c
index 88bf25b..e99257c 100644
--- a/version3/c/fp48.c
+++ b/version3/c/fp48.c
@@ -93,6 +93,14 @@ void FP48_YYY_one(FP48_YYY *w)
 	w->type=FP_UNITY;
 }
 
+void FP48_YYY_zero(FP48_YYY *w)
+{
+    FP16_YYY_zero(&(w->a));
+    FP16_YYY_zero(&(w->b));
+    FP16_YYY_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int FP48_YYY_equals(FP48_YYY *x,FP48_YYY *y)
diff --git a/version3/c/fp48.h b/version3/c/fp48.h
index e0a1f80..f445af7 100644
--- a/version3/c/fp48.h
+++ b/version3/c/fp48.h
@@ -42,6 +42,13 @@ extern void FP48_YYY_copy(FP48_YYY *x,FP48_YYY *y);
 	@param x FP48 instance to be set to one
  */
 extern void FP48_YYY_one(FP48_YYY *x);
+
+/**	@brief Set FP48 to zero
+ *
+	@param x FP48 instance to be set to zero
+ */
+extern void FP48_YYY_zero(FP48_YYY *x);
+
 /**	@brief Tests for equality of two FP48s
  *
 	@param x FP48 instance to be compared
diff --git a/version3/c/pair.c b/version3/c/pair.c
index f88a3d5..47265fa 100644
--- a/version3/c/pair.c
+++ b/version3/c/pair.c
@@ -487,6 +487,12 @@ void PAIR_ZZZ_fexp(FP12_YYY *r)
     FP12_YYY_frob(r,&X);
     FP12_YYY_mul(r,&t0);
 
+	if (FP12_YYY_isunity(r))
+	{
+		FP12_YYY_zero(r);
+		return;
+	}
+
     /* Hard part of final exp - see Duquesne & Ghamman eprint 2015/192.pdf */
 #if PAIRING_FRIENDLY_ZZZ==BN
     FP12_YYY_pow(&t0,r,x); // t0=f^-u
diff --git a/version3/c/pair192.c b/version3/c/pair192.c
index d543bbf..790a2d7 100644
--- a/version3/c/pair192.c
+++ b/version3/c/pair192.c
@@ -377,6 +377,11 @@ void PAIR_ZZZ_fexp(FP24_YYY *r)
 
     FP24_YYY_mul(r,&t0);
 
+	if (FP24_YYY_isunity(r))
+	{
+		FP24_YYY_zero(r);
+		return;
+	}
 // Ghamman & Fouotsa Method - (completely garbled in  https://eprint.iacr.org/2016/130)
 
 	FP24_YYY_usqr(&t7,r);			// t7=f^2
diff --git a/version3/c/pair256.c b/version3/c/pair256.c
index f378315..9dab331 100644
--- a/version3/c/pair256.c
+++ b/version3/c/pair256.c
@@ -373,6 +373,12 @@ void PAIR_ZZZ_fexp(FP48_YYY *r)
 
     FP48_YYY_mul(r,&t7);
 
+	if (FP48_YYY_isunity(r))
+	{
+		FP48_YYY_zero(r);
+		return;
+	}
+
 // f^e0.f^e1^p.f^e2^p^2.. .. f^e14^p^14.f^e15^p^15
 
 	FP48_YYY_usqr(&t7,r);			// t7=f^2
diff --git a/version3/cpp/fp12.cpp b/version3/cpp/fp12.cpp
index 20ceea0..f1bb437 100644
--- a/version3/cpp/fp12.cpp
+++ b/version3/cpp/fp12.cpp
@@ -95,6 +95,14 @@ void YYY::FP12_one(FP12 *w)
 	w->type=FP_UNITY;
 }
 
+void YYY::FP12_zero(FP12 *w)
+{
+    FP4_zero(&(w->a));
+    FP4_zero(&(w->b));
+    FP4_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int YYY::FP12_equals(FP12 *x,FP12 *y)
diff --git a/version3/cpp/fp12.h b/version3/cpp/fp12.h
index 69bc87c..84f2faf 100644
--- a/version3/cpp/fp12.h
+++ b/version3/cpp/fp12.h
@@ -52,6 +52,14 @@ extern void FP12_copy(FP12 *x,FP12 *y);
 	@param x FP12 instance to be set to one
  */
 extern void FP12_one(FP12 *x);
+
+
+/**	@brief Set FP12 to zero
+ *
+	@param x FP12 instance to be set to zero
+ */
+extern void FP12_zero(FP12 *x);
+
 /**	@brief Tests for equality of two FP12s
  *
 	@param x FP12 instance to be compared
diff --git a/version3/cpp/fp24.cpp b/version3/cpp/fp24.cpp
index 79cbdf8..4ca87d8 100644
--- a/version3/cpp/fp24.cpp
+++ b/version3/cpp/fp24.cpp
@@ -96,6 +96,14 @@ void YYY::FP24_one(FP24 *w)
 
 }
 
+void YYY::FP24_zero(FP24 *w)
+{
+    FP8_zero(&(w->a));
+    FP8_zero(&(w->b));
+    FP8_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int YYY::FP24_equals(FP24 *x,FP24 *y)
diff --git a/version3/cpp/fp24.h b/version3/cpp/fp24.h
index 41639f0..3d4b637 100644
--- a/version3/cpp/fp24.h
+++ b/version3/cpp/fp24.h
@@ -52,6 +52,13 @@ extern void FP24_copy(FP24 *x,FP24 *y);
 	@param x FP24 instance to be set to one
  */
 extern void FP24_one(FP24 *x);
+
+/**	@brief Set FP24 to zero
+ *
+	@param x FP24 instance to be set to zero
+ */
+extern void FP24_zero(FP24 *x);
+
 /**	@brief Tests for equality of two FP24s
  *
 	@param x FP24 instance to be compared
diff --git a/version3/cpp/fp48.cpp b/version3/cpp/fp48.cpp
index 7f0ff85..71d048f 100644
--- a/version3/cpp/fp48.cpp
+++ b/version3/cpp/fp48.cpp
@@ -96,6 +96,14 @@ void YYY::FP48_one(FP48 *w)
 	w->type=FP_UNITY;
 }
 
+void YYY::FP48_zero(FP48 *w)
+{
+    FP16_zero(&(w->a));
+    FP16_zero(&(w->b));
+    FP16_zero(&(w->c));
+	w->type=FP_ZERO;
+}
+
 /* return 1 if x==y, else 0 */
 /* SU= 16 */
 int YYY::FP48_equals(FP48 *x,FP48 *y)
diff --git a/version3/cpp/fp48.h b/version3/cpp/fp48.h
index 407ed17..d0557f9 100644
--- a/version3/cpp/fp48.h
+++ b/version3/cpp/fp48.h
@@ -52,6 +52,13 @@ extern void FP48_copy(FP48 *x,FP48 *y);
 	@param x FP48 instance to be set to one
  */
 extern void FP48_one(FP48 *x);
+
+/**	@brief Set FP48 to zero
+ *
+	@param x FP48 instance to be set to zero
+ */
+extern void FP48_zero(FP48 *x);
+
 /**	@brief Tests for equality of two FP48s
  *
 	@param x FP48 instance to be compared
diff --git a/version3/cpp/pair.cpp b/version3/cpp/pair.cpp
index 3cad837..1018b40 100644
--- a/version3/cpp/pair.cpp
+++ b/version3/cpp/pair.cpp
@@ -491,6 +491,11 @@ void ZZZ::PAIR_fexp(FP12 *r)
     FP12_frob(r,&X);
     FP12_mul(r,&t0);
 
+	if (FP12_isunity(r))
+	{
+		FP12_zero(r);
+		return;
+	}
     /* Hard part of final exp - see Duquesne & Ghamman eprint 2015/192.pdf */
 #if PAIRING_FRIENDLY_ZZZ==BN
     FP12_pow(&t0,r,x); // t0=f^-u
diff --git a/version3/cpp/pair192.cpp b/version3/cpp/pair192.cpp
index 2d673fd..1f3be7c 100644
--- a/version3/cpp/pair192.cpp
+++ b/version3/cpp/pair192.cpp
@@ -388,6 +388,11 @@ void ZZZ::PAIR_fexp(FP24 *r)
 
     FP24_mul(r,&t0);
 
+	if (FP24_isunity(r))
+	{
+		FP24_zero(r);
+		return;
+	}
 // Ghamman & Fouotsa Method - (completely garbled in  https://eprint.iacr.org/2016/130)
 
 	FP24_usqr(&t7,r);			// t7=f^2
diff --git a/version3/cpp/pair256.cpp b/version3/cpp/pair256.cpp
index e5719e4..2da3cb5 100644
--- a/version3/cpp/pair256.cpp
+++ b/version3/cpp/pair256.cpp
@@ -384,7 +384,11 @@ void ZZZ::PAIR_fexp(FP48 *r)
 
     FP48_mul(r,&t7);
 
-
+	if (FP48_isunity(r))
+	{
+		FP48_zero(r);
+		return;
+	}
 // f^e0.f^e1^p.f^e2^p^2.. .. f^e14^p^14.f^e15^p^15
 
 	FP48_usqr(&t7,r);			// t7=f^2
diff --git a/version3/go/AES.go b/version3/go/AES.go
index 04ef2f1..d3eb3f9 100644
--- a/version3/go/AES.go
+++ b/version3/go/AES.go
@@ -328,13 +328,28 @@ func (A *AES) Init(m int, nk int, key []byte, iv []byte) bool {
 	for i := 0; i < nk; i++ {
 		A.fkey[i] = CipherKey[i]
 	}
+
 	j = nk
 	for k := 0; j < N; k++ {
 		A.fkey[j] = A.fkey[j-nk] ^ aes_SubByte(aes_ROTL24(A.fkey[j-1])) ^ uint32(aes_rco[k])
-		for i := 1; i < nk && (i+j) < N; i++ {
-			A.fkey[i+j] = A.fkey[i+j-nk] ^ A.fkey[i+j-1]
+		if nk<=6 {
+			for i := 1; i < nk && (i+j) < N; i++ {
+				A.fkey[i+j] = A.fkey[i+j-nk] ^ A.fkey[i+j-1]
+			}
+		} else {
+			i:=0
+			for i = 1; i < 4 && (i + j) < N; i++ {
+				A.fkey[i + j] = A.fkey[i + j - nk] ^ A.fkey[i + j - 1];
+			}
+			if (j + 4) < N {
+				A.fkey[j + 4] = A.fkey[j + 4 - nk] ^ aes_SubByte(A.fkey[j + 3]);
+			}
+			for i = 5; i < nk && (i + j) < N; i++ {
+				A.fkey[i + j] = A.fkey[i + j - nk] ^ A.fkey[i + j - 1];
+			}
 		}
 		j += nk
+		
 	}
 
 	/* now for the expanded decrypt key in reverse order */
diff --git a/version3/go/BIG32.go b/version3/go/BIG32.go
index 65dd1fc..f3d5440 100644
--- a/version3/go/BIG32.go
+++ b/version3/go/BIG32.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 import "strconv"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/BIG64.go b/version3/go/BIG64.go
index 52fb829..cad1954 100644
--- a/version3/go/BIG64.go
+++ b/version3/go/BIG64.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 import "strconv"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/BLS.go b/version3/go/BLS.go
index db4db41..f4af616 100644
--- a/version3/go/BLS.go
+++ b/version3/go/BLS.go
@@ -21,7 +21,7 @@ under the License.
 
 package XXX
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/BLS192.go b/version3/go/BLS192.go
index 999d0ae..8e2ccaf 100644
--- a/version3/go/BLS192.go
+++ b/version3/go/BLS192.go
@@ -21,7 +21,7 @@ under the License.
 
 package XXX
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/BLS256.go b/version3/go/BLS256.go
index 74519ad..179e979 100644
--- a/version3/go/BLS256.go
+++ b/version3/go/BLS256.go
@@ -21,7 +21,7 @@ under the License.
 
 package XXX
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/BenchtestALL.go b/version3/go/BenchtestALL.go
index 2381443..2f00a01 100644
--- a/version3/go/BenchtestALL.go
+++ b/version3/go/BenchtestALL.go
@@ -23,15 +23,15 @@ package main
 
 import "fmt"
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/ED25519"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/NIST256"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/GOLDILOCKS"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BN254"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS383"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/RSA2048"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS24"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS48"
+import "github.com/miracl/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl/ED25519"
+import "github.com/miracl/amcl/version3/go/amcl/NIST256"
+import "github.com/miracl/amcl/version3/go/amcl/GOLDILOCKS"
+import "github.com/miracl/amcl/version3/go/amcl/BN254"
+import "github.com/miracl/amcl/version3/go/amcl/BLS383"
+import "github.com/miracl/amcl/version3/go/amcl/RSA2048"
+import "github.com/miracl/amcl/version3/go/amcl/BLS24"
+import "github.com/miracl/amcl/version3/go/amcl/BLS48"
 
 //import "amcl"
 //import "amcl/BN254"
diff --git a/version3/go/ECDH.go b/version3/go/ECDH.go
index f0896df..e3b9003 100644
--- a/version3/go/ECDH.go
+++ b/version3/go/ECDH.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 //import "fmt"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 const INVALID_PUBLIC_KEY int = -2
 const ERROR int = -3
diff --git a/version3/go/ECP.go b/version3/go/ECP.go
index d604903..261da85 100644
--- a/version3/go/ECP.go
+++ b/version3/go/ECP.go
@@ -52,12 +52,12 @@ type ECP struct {
 /* Constructors */
 func NewECP() *ECP {
 	E := new(ECP)
-	E.x = NewFPint(0)
+	E.x = NewFP()
 	E.y = NewFPint(1)
 	if CURVETYPE == EDWARDS {
 		E.z = NewFPint(1)
 	} else {
-		E.z = NewFPint(0)
+		E.z = NewFP()
 	}
 	return E
 }
@@ -89,7 +89,7 @@ func NewECPbigs(ix *BIG, iy *BIG) *ECP {
 func NewECPbigint(ix *BIG, s int) *ECP {
 	E := new(ECP)
 	E.x = NewFPbig(ix)
-	E.y = NewFPint(0)
+	E.y = NewFP()
 	E.x.norm()
 	rhs := RHS(E.x)
 	E.z = NewFPint(1)
@@ -109,7 +109,7 @@ func NewECPbigint(ix *BIG, s int) *ECP {
 func NewECPbig(ix *BIG) *ECP {
 	E := new(ECP)
 	E.x = NewFPbig(ix)
-	E.y = NewFPint(0)
+	E.y = NewFP()
 	E.x.norm()
 	rhs := RHS(E.x)
 	E.z = NewFPint(1)
@@ -226,8 +226,8 @@ func (E *ECP) inf() {
 
 /* Test P == Q */
 func (E *ECP) Equals(Q *ECP) bool {
-	a := NewFPint(0)
-	b := NewFPint(0)
+	a := NewFP()
+	b := NewFP()
 	a.copy(E.x)
 	a.mul(Q.z)
 	a.reduce()
@@ -285,7 +285,7 @@ func RHS(x *FP) *FP {
 		r.mul(b)
 	}
 	if CURVETYPE == MONTGOMERY { // x^3+Ax^2+x
-		x3 := NewFPint(0)
+		x3 := NewFP()
 		x3.copy(r)
 		x3.mul(x)
 		r.imul(CURVE_A)
@@ -486,9 +486,9 @@ func (E *ECP) dbl() {
 			t2 := NewFPcopy(E.z)
 			t3 := NewFPcopy(E.x)
 			z3 := NewFPcopy(E.z)
-			y3 := NewFPint(0)
-			x3 := NewFPint(0)
-			b := NewFPint(0)
+			y3 := NewFP()
+			x3 := NewFP()
+			b := NewFP()
 
 			if CURVE_B_I == 0 {
 				b.copy(NewFPbig(NewBIGints(CURVE_B)))
@@ -577,7 +577,7 @@ func (E *ECP) dbl() {
 		C := NewFPcopy(E.x)
 		D := NewFPcopy(E.y)
 		H := NewFPcopy(E.z)
-		J := NewFPint(0)
+		J := NewFP()
 
 		E.x.mul(E.y)
 		E.x.add(E.x)
@@ -607,9 +607,9 @@ func (E *ECP) dbl() {
 	if CURVETYPE == MONTGOMERY {
 		A := NewFPcopy(E.x)
 		B := NewFPcopy(E.x)
-		AA := NewFPint(0)
-		BB := NewFPint(0)
-		C := NewFPint(0)
+		AA := NewFP()
+		BB := NewFP()
+		C := NewFP()
 
 		A.add(E.z)
 		A.norm()
@@ -723,10 +723,10 @@ func (E *ECP) Add(Q *ECP) {
 			t2 := NewFPcopy(E.z)
 			t3 := NewFPcopy(E.x)
 			t4 := NewFPcopy(Q.x)
-			z3 := NewFPint(0)
+			z3 := NewFP()
 			y3 := NewFPcopy(Q.x)
 			x3 := NewFPcopy(Q.y)
-			b := NewFPint(0)
+			b := NewFP()
 
 			if CURVE_B_I == 0 {
 				b.copy(NewFPbig(NewBIGints(CURVE_B)))
@@ -838,12 +838,12 @@ func (E *ECP) Add(Q *ECP) {
 	if CURVETYPE == EDWARDS {
 		b := NewFPbig(NewBIGints(CURVE_B))
 		A := NewFPcopy(E.z)
-		B := NewFPint(0)
+		B := NewFP()
 		C := NewFPcopy(E.x)
 		D := NewFPcopy(E.y)
-		EE := NewFPint(0)
-		F := NewFPint(0)
-		G := NewFPint(0)
+		EE := NewFP()
+		F := NewFP()
+		G := NewFP()
 
 		A.mul(Q.z)
 		B.copy(A)
@@ -902,8 +902,8 @@ func (E *ECP) dadd(Q *ECP, W *ECP) {
 	B := NewFPcopy(E.x)
 	C := NewFPcopy(Q.x)
 	D := NewFPcopy(Q.x)
-	DA := NewFPint(0)
-	CB := NewFPint(0)
+	DA := NewFP()
+	CB := NewFP()
 
 	A.add(E.z)
 	B.sub(E.z)
diff --git a/version3/go/ECP2.go b/version3/go/ECP2.go
index 0f400ef..ee2c08b 100644
--- a/version3/go/ECP2.go
+++ b/version3/go/ECP2.go
@@ -31,9 +31,9 @@ type ECP2 struct {
 
 func NewECP2() *ECP2 {
 	E := new(ECP2)
-	E.x = NewFP2int(0)
+	E.x = NewFP2()
 	E.y = NewFP2int(1)
-	E.z = NewFP2int(0)
+	E.z = NewFP2()
 	return E
 }
 
diff --git a/version3/go/ECP4.go b/version3/go/ECP4.go
index 4603189..0f8570c 100644
--- a/version3/go/ECP4.go
+++ b/version3/go/ECP4.go
@@ -31,9 +31,9 @@ type ECP4 struct {
 
 func NewECP4() *ECP4 {
 	E := new(ECP4)
-	E.x = NewFP4int(0)
+	E.x = NewFP4()
 	E.y = NewFP4int(1)
-	E.z = NewFP4int(0)
+	E.z = NewFP4()
 	return E
 }
 
diff --git a/version3/go/ECP8.go b/version3/go/ECP8.go
index 186454d..a8f7b16 100644
--- a/version3/go/ECP8.go
+++ b/version3/go/ECP8.go
@@ -31,9 +31,9 @@ type ECP8 struct {
 
 func NewECP8() *ECP8 {
 	E := new(ECP8)
-	E.x = NewFP8int(0)
+	E.x = NewFP8()
 	E.y = NewFP8int(1)
-	E.z = NewFP8int(0)
+	E.z = NewFP8()
 	return E
 }
 
diff --git a/version3/go/FF32.go b/version3/go/FF32.go
index 6f532a1..f56cdb4 100644
--- a/version3/go/FF32.go
+++ b/version3/go/FF32.go
@@ -21,7 +21,7 @@ package XXX
 
 //import "fmt"
 //import "os"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //const FFLEN int = @ML@
 
diff --git a/version3/go/FF64.go b/version3/go/FF64.go
index fbcf6c4..c951e70 100644
--- a/version3/go/FF64.go
+++ b/version3/go/FF64.go
@@ -21,7 +21,7 @@ package XXX
 
 //import "fmt"
 //import "os"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //const FFLEN int = @ML@
 
diff --git a/version3/go/FP.go b/version3/go/FP.go
index 7e91f3c..8154f89 100644
--- a/version3/go/FP.go
+++ b/version3/go/FP.go
@@ -44,6 +44,13 @@ type FP struct {
 }
 
 /* Constructors */
+func NewFP() *FP {
+	F := new(FP)
+	F.x = NewBIG()
+	F.XES = 1
+	return F
+}
+
 func NewFPint(a int) *FP {
 	F := new(FP)
 	F.x = NewBIGint(a)
@@ -400,7 +407,7 @@ func (F *FP) fpow() *FP {
 	k := w - c
 
 	i := 10
-	key := NewFPint(0)
+	key := NewFP()
 
 	if k != 0 {
 		for ac[i] > k {
@@ -426,7 +433,7 @@ func (F *FP) fpow() *FP {
 	j := 3
 	m := 8
 	nw := n - bw
-	t := NewFPint(0)
+	t := NewFP()
 	for 2*m < nw {
 		t.copy(xp[j])
 		j++
diff --git a/version3/go/FP12.go b/version3/go/FP12.go
index 60af7c6..31c8fea 100644
--- a/version3/go/FP12.go
+++ b/version3/go/FP12.go
@@ -32,11 +32,20 @@ type FP12 struct {
 }
 
 /* Constructors */
+func NewFP12() *FP12 {
+	F := new(FP12)
+	F.a = NewFP4()
+	F.b = NewFP4()
+	F.c = NewFP4()
+	F.stype=FP_ZERO
+	return F
+}
+
 func NewFP12fp4(d *FP4) *FP12 {
 	F := new(FP12)
 	F.a = NewFP4copy(d)
-	F.b = NewFP4int(0)
-	F.c = NewFP4int(0)
+	F.b = NewFP4()
+	F.c = NewFP4()
 	F.stype=FP_SPARSER
 	return F
 }
@@ -44,13 +53,13 @@ func NewFP12fp4(d *FP4) *FP12 {
 func NewFP12int(d int) *FP12 {
 	F := new(FP12)
 	F.a = NewFP4int(d)
-	F.b = NewFP4int(0)
-	F.c = NewFP4int(0)
-//	if d==1 {
-//		F.stype=FP_ONE
-//	} else {
-//		F.stype=FP_SPARSER
-//	}
+	F.b = NewFP4()
+	F.c = NewFP4()
+	if d==1 {
+		F.stype=FP_ONE
+	} else {
+		F.stype=FP_SPARSER
+	}
 	return F
 }
 
@@ -164,6 +173,14 @@ func (F *FP12) one() {
 	F.stype=FP_ONE
 }
 
+/* set this=0 */
+func (F *FP12) zero() {
+	F.a.zero()
+	F.b.zero()
+	F.c.zero()
+	F.stype=FP_ZERO
+}
+
 /* this=conj(this) */
 func (F *FP12) conj() {
 	F.a.conj()
@@ -176,7 +193,7 @@ func (F *FP12) usqr() {
 	A := NewFP4copy(F.a)
 	B := NewFP4copy(F.c)
 	C := NewFP4copy(F.b)
-	D := NewFP4int(0)
+	D := NewFP4()
 
 	F.a.sqr()
 	D.copy(F.a)
@@ -266,9 +283,9 @@ func (F *FP12) sqr() {
 /* FP12 full multiplication this=this*y */
 func (F *FP12) Mul(y *FP12) {
 	z0 := NewFP4copy(F.a)
-	z1 := NewFP4int(0)
+	z1 := NewFP4()
 	z2 := NewFP4copy(F.b)
-	z3 := NewFP4int(0)
+	z3 := NewFP4()
 	t0 := NewFP4copy(F.a)
 	t1 := NewFP4copy(y.a)
 
@@ -345,9 +362,9 @@ func (F *FP12) ssmul(y *FP12) {
 	}
 	if y.stype>=FP_SPARSE {
 		z0:=NewFP4copy(F.a)
-		z1:=NewFP4int(0)
-		z2:=NewFP4int(0)
-		z3:=NewFP4int(0)
+		z1:=NewFP4()
+		z2:=NewFP4()
+		z3:=NewFP4()
 		z0.mul(y.a)
 
 		if SEXTIC_TWIST==M_TYPE {
@@ -437,7 +454,7 @@ func (F *FP12) ssmul(y *FP12) {
 			z0:=NewFP4copy(F.a)
 			z2:=NewFP4copy(F.b)
 			z3:=NewFP4copy(F.b)
-			t0:=NewFP4int(0)
+			t0:=NewFP4()
 			t1:=NewFP4copy(y.a)
 			z0.mul(y.a)
 			z2.pmul(y.b.real())
@@ -470,11 +487,11 @@ func (F *FP12) ssmul(y *FP12) {
 		}
 		if SEXTIC_TWIST==M_TYPE {
 			z0:=NewFP4copy(F.a)
-			z1:=NewFP4int(0)
-			z2:=NewFP4int(0)
-			z3:=NewFP4int(0)
+			z1:=NewFP4()
+			z2:=NewFP4()
+			z3:=NewFP4()
 			t0:=NewFP4copy(F.a)
-			t1:=NewFP4int(0)
+			t1:=NewFP4()
 		
 			z0.mul(y.a)
 			t0.add(F.b); t0.norm()
@@ -629,7 +646,7 @@ func (F *FP12) Inverse() {
 	f0 := NewFP4copy(F.a)
 	f1 := NewFP4copy(F.b)
 	f2 := NewFP4copy(F.a)
-	f3 := NewFP4int(0)
+	f3 := NewFP4()
 
 	F.norm()
 	f0.sqr()
@@ -691,7 +708,7 @@ func (F *FP12) frob(f *FP2) {
 
 /* trace function */
 func (F *FP12) trace() *FP4 {
-	t := NewFP4int(0)
+	t := NewFP4()
 	t.copy(F.a)
 	t.imul(3)
 	t.reduce()
@@ -923,8 +940,8 @@ func pow4(q []*FP12, u []*BIG) *FP12 {
 	var w [NLEN*int(BASEBITS) + 1]int8
 	var s [NLEN*int(BASEBITS) + 1]int8
 	var t []*BIG
-	r := NewFP12int(0)
-	p := NewFP12int(0)
+	r := NewFP12()
+	p := NewFP12()
 	mt := NewBIGint(0)
 
 	for i := 0; i < 4; i++ {
diff --git a/version3/go/FP16.go b/version3/go/FP16.go
index 29c7d45..7d41075 100644
--- a/version3/go/FP16.go
+++ b/version3/go/FP16.go
@@ -31,10 +31,17 @@ type FP16 struct {
 }
 
 /* Constructors */
+func NewFP16() *FP16 {
+	F := new(FP16)
+	F.a = NewFP8()
+	F.b = NewFP8()
+	return F
+}
+
 func NewFP16int(a int) *FP16 {
 	F := new(FP16)
 	F.a = NewFP8int(a)
-	F.b = NewFP8int(0)
+	F.b = NewFP8()
 	return F
 }
 
@@ -55,7 +62,7 @@ func NewFP16fp8s(c *FP8, d *FP8) *FP16 {
 func NewFP16fp8(c *FP8) *FP16 {
 	F := new(FP16)
 	F.a = NewFP8copy(c)
-	F.b = NewFP8int(0)
+	F.b = NewFP8()
 	return F
 }
 
@@ -134,7 +141,7 @@ func (F *FP16) one() {
 func (F *FP16) neg() {
 	F.norm()
 	m := NewFP8copy(F.a)
-	t := NewFP8int(0)
+	t := NewFP8()
 	m.add(F.b)
 	m.neg()
 	t.copy(m)
@@ -229,7 +236,7 @@ func (F *FP16) sqr() {
 func (F *FP16) mul(y *FP16) {
 	t1 := NewFP8copy(F.a)
 	t2 := NewFP8copy(F.b)
-	t3 := NewFP8int(0)
+	t3 := NewFP8()
 	t4 := NewFP8copy(F.b)
 
 	t1.mul(y.a)
@@ -376,8 +383,8 @@ func (F *FP16) xtr_pow(n *BIG) *FP16 {
 	b := NewFP16copy(sf)
 	c := NewFP16copy(b)
 	c.xtr_D()
-	t := NewFP16int(0)
-	r := NewFP16int(0)
+	t := NewFP16()
+	r := NewFP16()
 
 	par := n.parity()
 	v := NewBIGcopy(n)
@@ -429,8 +436,8 @@ func (F *FP16) xtr_pow2(ck *FP16, ckml *FP16, ckm2l *FP16, a *BIG, b *BIG) *FP16
 	cv := NewFP16copy(F)
 	cumv := NewFP16copy(ckml)
 	cum2v := NewFP16copy(ckm2l)
-	r := NewFP16int(0)
-	t := NewFP16int(0)
+	r := NewFP16()
+	t := NewFP16()
 
 	f2 := 0
 	for d.parity() == 0 && e.parity() == 0 {
diff --git a/version3/go/FP2.go b/version3/go/FP2.go
index 53a34d3..801e32b 100644
--- a/version3/go/FP2.go
+++ b/version3/go/FP2.go
@@ -31,10 +31,17 @@ type FP2 struct {
 }
 
 /* Constructors */
+func NewFP2() *FP2 {
+	F := new(FP2)
+	F.a = NewFP()
+	F.b = NewFP()
+	return F
+}
+
 func NewFP2int(a int) *FP2 {
 	F := new(FP2)
 	F.a = NewFPint(a)
-	F.b = NewFPint(0)
+	F.b = NewFP()
 	return F
 }
 
@@ -62,14 +69,14 @@ func NewFP2bigs(c *BIG, d *BIG) *FP2 {
 func NewFP2fp(c *FP) *FP2 {
 	F := new(FP2)
 	F.a = NewFPcopy(c)
-	F.b = NewFPint(0)
+	F.b = NewFP()
 	return F
 }
 
 func NewFP2big(c *BIG) *FP2 {
 	F := new(FP2)
 	F.a = NewFPbig(c)
-	F.b = NewFPint(0)
+	F.b = NewFP()
 	return F
 }
 
@@ -137,7 +144,7 @@ func (F *FP2) one() {
 /* negate this mod Modulus */
 func (F *FP2) neg() {
 	m := NewFPcopy(F.a)
-	t := NewFPint(0)
+	t := NewFP()
 
 	m.add(F.b)
 	m.neg()
@@ -335,7 +342,7 @@ func (F *FP2) mul_ip() {
 }
 
 func (F *FP2) div_ip2() {
-	t := NewFP2int(0)
+	t := NewFP2()
 	F.norm()
 	t.a.copy(F.a)
 	t.a.add(F.b)
@@ -347,7 +354,7 @@ func (F *FP2) div_ip2() {
 
 /* w/=(1+sqrt(-1)) */
 func (F *FP2) div_ip() {
-	t := NewFP2int(0)
+	t := NewFP2()
 	F.norm()
 	t.a.copy(F.a)
 	t.a.add(F.b)
diff --git a/version3/go/FP24.go b/version3/go/FP24.go
index 32bae65..e71ea07 100644
--- a/version3/go/FP24.go
+++ b/version3/go/FP24.go
@@ -32,11 +32,20 @@ type FP24 struct {
 }
 
 /* Constructors */
+func NewFP24() *FP24 {
+	F := new(FP24)
+	F.a = NewFP8()
+	F.b = NewFP8()
+	F.c = NewFP8()
+	F.stype=FP_ZERO
+	return F
+}
+
 func NewFP24fp8(d *FP8) *FP24 {
 	F := new(FP24)
 	F.a = NewFP8copy(d)
-	F.b = NewFP8int(0)
-	F.c = NewFP8int(0)
+	F.b = NewFP8()
+	F.c = NewFP8()
 	F.stype=FP_SPARSER
 	return F
 }
@@ -44,8 +53,8 @@ func NewFP24fp8(d *FP8) *FP24 {
 func NewFP24int(d int) *FP24 {
 	F := new(FP24)
 	F.a = NewFP8int(d)
-	F.b = NewFP8int(0)
-	F.c = NewFP8int(0)
+	F.b = NewFP8()
+	F.c = NewFP8()
 	if d==1 {
 		F.stype=FP_ONE
 	} else {
@@ -164,6 +173,14 @@ func (F *FP24) one() {
 	F.stype=FP_ONE
 }
 
+/* set this=0 */
+func (F *FP24) zero() {
+	F.a.zero()
+	F.b.zero()
+	F.c.zero()
+	F.stype=FP_ZERO
+}
+
 /* this=conj(this) */
 func (F *FP24) conj() {
 	F.a.conj()
@@ -176,7 +193,7 @@ func (F *FP24) usqr() {
 	A := NewFP8copy(F.a)
 	B := NewFP8copy(F.c)
 	C := NewFP8copy(F.b)
-	D := NewFP8int(0)
+	D := NewFP8()
 
 	F.a.sqr()
 	D.copy(F.a)
@@ -264,9 +281,9 @@ func (F *FP24) sqr() {
 /* FP24 full multiplication this=this*y */
 func (F *FP24) Mul(y *FP24) {
 	z0 := NewFP8copy(F.a)
-	z1 := NewFP8int(0)
+	z1 := NewFP8()
 	z2 := NewFP8copy(F.b)
-	z3 := NewFP8int(0)
+	z3 := NewFP8()
 	t0 := NewFP8copy(F.a)
 	t1 := NewFP8copy(y.a)
 
@@ -343,9 +360,9 @@ func (F *FP24) ssmul(y *FP24) {
 	}
 	if y.stype>=FP_SPARSE {
 		z0:=NewFP8copy(F.a)
-		z1:=NewFP8int(0)
-		z2:=NewFP8int(0)
-		z3:=NewFP8int(0)
+		z1:=NewFP8()
+		z2:=NewFP8()
+		z3:=NewFP8()
 		z0.mul(y.a)
 
 		if SEXTIC_TWIST==M_TYPE {
@@ -435,7 +452,7 @@ func (F *FP24) ssmul(y *FP24) {
 			z0:=NewFP8copy(F.a)
 			z2:=NewFP8copy(F.b)
 			z3:=NewFP8copy(F.b)
-			t0:=NewFP8int(0)
+			t0:=NewFP8()
 			t1:=NewFP8copy(y.a)
 			z0.mul(y.a)
 			z2.pmul(y.b.real())
@@ -468,11 +485,11 @@ func (F *FP24) ssmul(y *FP24) {
 		}
 		if SEXTIC_TWIST==M_TYPE {
 			z0:=NewFP8copy(F.a)
-			z1:=NewFP8int(0)
-			z2:=NewFP8int(0)
-			z3:=NewFP8int(0)
+			z1:=NewFP8()
+			z2:=NewFP8()
+			z3:=NewFP8()
 			t0:=NewFP8copy(F.a)
-			t1:=NewFP8int(0)
+			t1:=NewFP8()
 		
 			z0.mul(y.a)
 			t0.add(F.b); t0.norm()
@@ -627,7 +644,7 @@ func (F *FP24) Inverse() {
 	f0 := NewFP8copy(F.a)
 	f1 := NewFP8copy(F.b)
 	f2 := NewFP8copy(F.a)
-	f3 := NewFP8int(0)
+	f3 := NewFP8()
 
 	//F.norm()
 	f0.sqr()
@@ -697,7 +714,7 @@ func (F *FP24) frob(f *FP2, n int) {
 
 /* trace function */
 func (F *FP24) trace() *FP8 {
-	t := NewFP8int(0)
+	t := NewFP8()
 	t.copy(F.a)
 	t.imul(3)
 	t.reduce()
@@ -1057,8 +1074,8 @@ func pow8(q []*FP24, u []*BIG) *FP24 {
 	var w2 [NLEN*int(BASEBITS) + 1]int8
 	var s2 [NLEN*int(BASEBITS) + 1]int8
 	var t []*BIG
-	r := NewFP24int(0)
-	p := NewFP24int(0)
+	r := NewFP24()
+	p := NewFP24()
 	mt := NewBIGint(0)
 	var bt int8
 	var k int
diff --git a/version3/go/FP4.go b/version3/go/FP4.go
index 869ff85..c4f998a 100644
--- a/version3/go/FP4.go
+++ b/version3/go/FP4.go
@@ -31,10 +31,17 @@ type FP4 struct {
 }
 
 /* Constructors */
+func NewFP4() *FP4 {
+	F := new(FP4)
+	F.a = NewFP2()
+	F.b = NewFP2()
+	return F
+}
+
 func NewFP4int(a int) *FP4 {
 	F := new(FP4)
 	F.a = NewFP2int(a)
-	F.b = NewFP2int(0)
+	F.b = NewFP2()
 	return F
 }
 
@@ -55,7 +62,7 @@ func NewFP4fp2s(c *FP2, d *FP2) *FP4 {
 func NewFP4fp2(c *FP2) *FP4 {
 	F := new(FP4)
 	F.a = NewFP2copy(c)
-	F.b = NewFP2int(0)
+	F.b = NewFP2()
 	return F
 }
 
@@ -134,7 +141,7 @@ func (F *FP4) one() {
 func (F *FP4) neg() {
 	F.norm()
 	m := NewFP2copy(F.a)
-	t := NewFP2int(0)
+	t := NewFP2()
 	m.add(F.b)
 	m.neg()
 	t.copy(m)
@@ -230,7 +237,7 @@ func (F *FP4) sqr() {
 func (F *FP4) mul(y *FP4) {
 	t1 := NewFP2copy(F.a)
 	t2 := NewFP2copy(F.b)
-	t3 := NewFP2int(0)
+	t3 := NewFP2()
 	t4 := NewFP2copy(F.b)
 
 	t1.mul(y.a)
@@ -359,8 +366,8 @@ func (F *FP4) xtr_pow(n *BIG) *FP4 {
 	b := NewFP4copy(F)
 	c := NewFP4copy(b)
 	c.xtr_D()
-	t := NewFP4int(0)
-	r := NewFP4int(0)
+	t := NewFP4()
+	r := NewFP4()
 	sf := NewFP4copy(F)
 	sf.norm()
 
@@ -415,8 +422,8 @@ func (F *FP4) xtr_pow2(ck *FP4, ckml *FP4, ckm2l *FP4, a *BIG, b *BIG) *FP4 {
 	cv := NewFP4copy(F)
 	cumv := NewFP4copy(ckml)
 	cum2v := NewFP4copy(ckm2l)
-	r := NewFP4int(0)
-	t := NewFP4int(0)
+	r := NewFP4()
+	t := NewFP4()
 
 	f2 := 0
 	for d.parity() == 0 && e.parity() == 0 {
diff --git a/version3/go/FP48.go b/version3/go/FP48.go
index 481e21a..f2e83ad 100644
--- a/version3/go/FP48.go
+++ b/version3/go/FP48.go
@@ -32,11 +32,20 @@ type FP48 struct {
 }
 
 /* Constructors */
+func NewFP48() *FP48 {
+	F := new(FP48)
+	F.a = NewFP16()
+	F.b = NewFP16()
+	F.c = NewFP16()
+	F.stype=FP_ZERO
+	return F
+}
+
 func NewFP48fp16(d *FP16) *FP48 {
 	F := new(FP48)
 	F.a = NewFP16copy(d)
-	F.b = NewFP16int(0)
-	F.c = NewFP16int(0)
+	F.b = NewFP16()
+	F.c = NewFP16()
 	F.stype=FP_SPARSER
 	return F
 }
@@ -44,8 +53,8 @@ func NewFP48fp16(d *FP16) *FP48 {
 func NewFP48int(d int) *FP48 {
 	F := new(FP48)
 	F.a = NewFP16int(d)
-	F.b = NewFP16int(0)
-	F.c = NewFP16int(0)
+	F.b = NewFP16()
+	F.c = NewFP16()
 	if d==1 {
 		F.stype=FP_ONE
 	} else {
@@ -164,6 +173,14 @@ func (F *FP48) one() {
 	F.c.zero()
 }
 
+/* set this=0 */
+func (F *FP48) zero() {
+	F.stype=FP_ZERO
+	F.a.zero()
+	F.b.zero()
+	F.c.zero()
+}
+
 /* this=conj(this) */
 func (F *FP48) conj() {
 	F.a.conj()
@@ -176,7 +193,7 @@ func (F *FP48) usqr() {
 	A := NewFP16copy(F.a)
 	B := NewFP16copy(F.c)
 	C := NewFP16copy(F.b)
-	D := NewFP16int(0)
+	D := NewFP16()
 
 	F.a.sqr()
 	D.copy(F.a)
@@ -264,9 +281,9 @@ func (F *FP48) sqr() {
 /* FP48 full multiplication this=this*y */
 func (F *FP48) Mul(y *FP48) {
 	z0 := NewFP16copy(F.a)
-	z1 := NewFP16int(0)
+	z1 := NewFP16()
 	z2 := NewFP16copy(F.b)
-	z3 := NewFP16int(0)
+	z3 := NewFP16()
 	t0 := NewFP16copy(F.a)
 	t1 := NewFP16copy(y.a)
 
@@ -343,9 +360,9 @@ func (F *FP48) ssmul(y *FP48) {
 	}
 	if y.stype>=FP_SPARSE {
 		z0:=NewFP16copy(F.a)
-		z1:=NewFP16int(0)
-		z2:=NewFP16int(0)
-		z3:=NewFP16int(0)
+		z1:=NewFP16()
+		z2:=NewFP16()
+		z3:=NewFP16()
 		z0.mul(y.a)
 
 		if SEXTIC_TWIST==M_TYPE {
@@ -435,7 +452,7 @@ func (F *FP48) ssmul(y *FP48) {
 			z0:=NewFP16copy(F.a)
 			z2:=NewFP16copy(F.b)
 			z3:=NewFP16copy(F.b)
-			t0:=NewFP16int(0)
+			t0:=NewFP16()
 			t1:=NewFP16copy(y.a)
 			z0.mul(y.a)
 			z2.pmul(y.b.real())
@@ -468,11 +485,11 @@ func (F *FP48) ssmul(y *FP48) {
 		}
 		if SEXTIC_TWIST==M_TYPE {
 			z0:=NewFP16copy(F.a)
-			z1:=NewFP16int(0)
-			z2:=NewFP16int(0)
-			z3:=NewFP16int(0)
+			z1:=NewFP16()
+			z2:=NewFP16()
+			z3:=NewFP16()
 			t0:=NewFP16copy(F.a)
-			t1:=NewFP16int(0)
+			t1:=NewFP16()
 		
 			z0.mul(y.a)
 			t0.add(F.b); t0.norm()
@@ -627,7 +644,7 @@ func (F *FP48) Inverse() {
 	f0 := NewFP16copy(F.a)
 	f1 := NewFP16copy(F.b)
 	f2 := NewFP16copy(F.a)
-	f3 := NewFP16int(0)
+	f3 := NewFP16()
 
 	//F.norm()
 	f0.sqr()
@@ -701,7 +718,7 @@ func (F *FP48) frob(f *FP2, n int) {
 
 /* trace function */
 func (F *FP48) trace() *FP16 {
-	t := NewFP16int(0)
+	t := NewFP16()
 	t.copy(F.a)
 	t.imul(3)
 	t.reduce()
@@ -1305,8 +1322,8 @@ func pow16(q []*FP48, u []*BIG) *FP48 {
 	var w4 [NLEN*int(BASEBITS) + 1]int8
 	var s4 [NLEN*int(BASEBITS) + 1]int8
 	var t []*BIG
-	r := NewFP48int(0)
-	p := NewFP48int(0)
+	r := NewFP48()
+	p := NewFP48()
 	mt := NewBIGint(0)
 	var bt int8
 	var k int
diff --git a/version3/go/FP8.go b/version3/go/FP8.go
index 6b1f329..a656cd9 100644
--- a/version3/go/FP8.go
+++ b/version3/go/FP8.go
@@ -31,10 +31,17 @@ type FP8 struct {
 }
 
 /* Constructors */
+func NewFP8() *FP8 {
+	F := new(FP8)
+	F.a = NewFP4()
+	F.b = NewFP4()
+	return F
+}
+
 func NewFP8int(a int) *FP8 {
 	F := new(FP8)
 	F.a = NewFP4int(a)
-	F.b = NewFP4int(0)
+	F.b = NewFP4()
 	return F
 }
 
@@ -55,7 +62,7 @@ func NewFP8fp4s(c *FP4, d *FP4) *FP8 {
 func NewFP8fp4(c *FP4) *FP8 {
 	F := new(FP8)
 	F.a = NewFP4copy(c)
-	F.b = NewFP4int(0)
+	F.b = NewFP4()
 	return F
 }
 
@@ -134,7 +141,7 @@ func (F *FP8) one() {
 func (F *FP8) neg() {
 	F.norm()
 	m := NewFP4copy(F.a)
-	t := NewFP4int(0)
+	t := NewFP4()
 	m.add(F.b)
 	m.neg()
 	t.copy(m)
@@ -235,7 +242,7 @@ func (F *FP8) sqr() {
 func (F *FP8) mul(y *FP8) {
 	t1 := NewFP4copy(F.a)
 	t2 := NewFP4copy(F.b)
-	t3 := NewFP4int(0)
+	t3 := NewFP4()
 	t4 := NewFP4copy(F.b)
 
 	t1.mul(y.a)
@@ -375,8 +382,8 @@ func (F *FP8) xtr_pow(n *BIG) *FP8 {
 	b := NewFP8copy(F)
 	c := NewFP8copy(b)
 	c.xtr_D()
-	t := NewFP8int(0)
-	r := NewFP8int(0)
+	t := NewFP8()
+	r := NewFP8()
 	sf := NewFP8copy(F)
 	sf.norm()
 
@@ -430,8 +437,8 @@ func (F *FP8) xtr_pow2(ck *FP8, ckml *FP8, ckm2l *FP8, a *BIG, b *BIG) *FP8 {
 	cv := NewFP8copy(F)
 	cumv := NewFP8copy(ckml)
 	cum2v := NewFP8copy(ckm2l)
-	r := NewFP8int(0)
-	t := NewFP8int(0)
+	r := NewFP8()
+	t := NewFP8()
 
 	f2 := 0
 	for d.parity() == 0 && e.parity() == 0 {
diff --git a/version3/go/MPIN.go b/version3/go/MPIN.go
index e52b7fa..1996cc5 100644
--- a/version3/go/MPIN.go
+++ b/version3/go/MPIN.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 import "time"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/MPIN192.go b/version3/go/MPIN192.go
index f764a3e..a300396 100644
--- a/version3/go/MPIN192.go
+++ b/version3/go/MPIN192.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 import "time"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/MPIN256.go b/version3/go/MPIN256.go
index 63cfa41..9b19c0e 100644
--- a/version3/go/MPIN256.go
+++ b/version3/go/MPIN256.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 import "time"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "fmt"
 
diff --git a/version3/go/PAIR.go b/version3/go/PAIR.go
index acacc69..4b4a2e4 100644
--- a/version3/go/PAIR.go
+++ b/version3/go/PAIR.go
@@ -68,10 +68,10 @@ func line(A *ECP2, B *ECP2, Qx *FP, Qy *FP) *FP12 {
 		if SEXTIC_TWIST == D_TYPE {
 
 			b = NewFP4fp2(XX) // L(0,1) | L(0,0) | L(1,0)
-			c = NewFP4int(0)
+			c = NewFP4()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP4int(0)
+			b = NewFP4()
 			c = NewFP4fp2(XX)
 			c.times_i()
 		}
@@ -113,10 +113,10 @@ func line(A *ECP2, B *ECP2, Qx *FP, Qy *FP) *FP12 {
 		a = NewFP4fp2s(X1, T2) // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
 		if SEXTIC_TWIST == D_TYPE {
 			b = NewFP4fp2(Y1)
-			c = NewFP4int(0)
+			c = NewFP4()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP4int(0)
+			b = NewFP4()
 			c = NewFP4fp2(Y1)
 			c.times_i()
 		}
@@ -429,6 +429,10 @@ func Fexp(m *FP12) *FP12 {
 	r.frob(f)
 	r.frob(f)
 	r.Mul(lv)
+	if r.Isunity() {
+		r.zero()
+		return r
+	}
 	/* Hard part of final exp */
 	if CURVE_PAIRING_TYPE == BN {
 		lv.Copy(r)
@@ -725,7 +729,7 @@ func GTpow(d *FP12, e *BIG) *FP12 {
 
 		g = append(g, NewFP12copy(d))
 		for i := 1; i < 4; i++ {
-			g = append(g, NewFP12int(0))
+			g = append(g, NewFP12())
 			g[i].Copy(g[i-1])
 			g[i].frob(f)
 		}
diff --git a/version3/go/PAIR192.go b/version3/go/PAIR192.go
index a22877f..5c84f71 100644
--- a/version3/go/PAIR192.go
+++ b/version3/go/PAIR192.go
@@ -68,10 +68,10 @@ func line(A *ECP4, B *ECP4, Qx *FP, Qy *FP) *FP24 {
 		if SEXTIC_TWIST == D_TYPE {
 
 			b = NewFP8fp4(XX) // L(0,1) | L(0,0) | L(1,0)
-			c = NewFP8int(0)
+			c = NewFP8()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP8int(0)
+			b = NewFP8()
 			c = NewFP8fp4(XX)
 			c.times_i()
 		}
@@ -113,10 +113,10 @@ func line(A *ECP4, B *ECP4, Qx *FP, Qy *FP) *FP24 {
 		a = NewFP8fp4s(X1, T2) // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
 		if SEXTIC_TWIST == D_TYPE {
 			b = NewFP8fp4(Y1)
-			c = NewFP8int(0)
+			c = NewFP8()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP8int(0)
+			b = NewFP8()
 			c = NewFP8fp4(Y1)
 			c.times_i()
 		}
@@ -336,7 +336,10 @@ func Fexp(m *FP24) *FP24 {
 	lv.Copy(r)
 	r.frob(f, 4)
 	r.Mul(lv)
-
+	if r.Isunity() {
+		r.zero()
+		return r
+	}
 	/* Hard part of final exp */
 	// Ghamman & Fouotsa Method
 
@@ -549,7 +552,7 @@ func GTpow(d *FP24, e *BIG) *FP24 {
 
 		g = append(g, NewFP24copy(d))
 		for i := 1; i < 8; i++ {
-			g = append(g, NewFP24int(0))
+			g = append(g, NewFP24())
 			g[i].Copy(g[i-1])
 			g[i].frob(f, 1)
 		}
diff --git a/version3/go/PAIR256.go b/version3/go/PAIR256.go
index fcd8821..e5e9ef6 100644
--- a/version3/go/PAIR256.go
+++ b/version3/go/PAIR256.go
@@ -68,10 +68,10 @@ func line(A *ECP8, B *ECP8, Qx *FP, Qy *FP) *FP48 {
 		if SEXTIC_TWIST == D_TYPE {
 
 			b = NewFP16fp8(XX) // L(0,1) | L(0,0) | L(1,0)
-			c = NewFP16int(0)
+			c = NewFP16()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP16int(0)
+			b = NewFP16()
 			c = NewFP16fp8(XX)
 			c.times_i()
 		}
@@ -113,10 +113,10 @@ func line(A *ECP8, B *ECP8, Qx *FP, Qy *FP) *FP48 {
 		a = NewFP16fp8s(X1, T2) // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
 		if SEXTIC_TWIST == D_TYPE {
 			b = NewFP16fp8(Y1)
-			c = NewFP16int(0)
+			c = NewFP16()
 		}
 		if SEXTIC_TWIST == M_TYPE {
-			b = NewFP16int(0)
+			b = NewFP16()
 			c = NewFP16fp8(Y1)
 			c.times_i()
 		}
@@ -335,7 +335,10 @@ func Fexp(m *FP48) *FP48 {
 	lv.Copy(r)
 	r.frob(f, 8)
 	r.Mul(lv)
-
+	if r.Isunity() {
+		r.zero()
+		return r
+	}
 	/* Hard part of final exp */
 	// Ghamman & Fouotsa Method
 
@@ -623,7 +626,7 @@ func GTpow(d *FP48, e *BIG) *FP48 {
 
 		g = append(g, NewFP48copy(d))
 		for i := 1; i < 16; i++ {
-			g = append(g, NewFP48int(0))
+			g = append(g, NewFP48())
 			g[i].Copy(g[i-1])
 			g[i].frob(f, 1)
 		}
diff --git a/version3/go/RSA.go b/version3/go/RSA.go
index de095fb..dc33c25 100644
--- a/version3/go/RSA.go
+++ b/version3/go/RSA.go
@@ -22,7 +22,7 @@ under the License.
 package XXX
 
 //import "fmt"
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 const RFS int = int(MODBYTES) * FFLEN
 
diff --git a/version3/go/TestALL.go b/version3/go/TestALL.go
index 8dab85b..a0fbdad 100644
--- a/version3/go/TestALL.go
+++ b/version3/go/TestALL.go
@@ -23,15 +23,15 @@ package main
 
 import "fmt"
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/ED25519"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/NIST256"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/GOLDILOCKS"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BN254"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS383"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS24"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS48"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/RSA2048"
+import "github.com/miracl/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl/ED25519"
+import "github.com/miracl/amcl/version3/go/amcl/NIST256"
+import "github.com/miracl/amcl/version3/go/amcl/GOLDILOCKS"
+import "github.com/miracl/amcl/version3/go/amcl/BN254"
+import "github.com/miracl/amcl/version3/go/amcl/BLS383"
+import "github.com/miracl/amcl/version3/go/amcl/BLS24"
+import "github.com/miracl/amcl/version3/go/amcl/BLS48"
+import "github.com/miracl/amcl/version3/go/amcl/RSA2048"
 
 //import "amcl"
 //import "amcl/ED25519"
diff --git a/version3/go/TestBLS.go b/version3/go/TestBLS.go
index 954f8f8..e5a6434 100644
--- a/version3/go/TestBLS.go
+++ b/version3/go/TestBLS.go
@@ -23,12 +23,12 @@ package main
 
 import "fmt"
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BN254"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS383"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS24"
-import "github.com/milagro-crypto/amcl/version3/go/amcl/BLS48"
+import "github.com/miracl/amcl/version3/go/amcl/BN254"
+import "github.com/miracl/amcl/version3/go/amcl/BLS383"
+import "github.com/miracl/amcl/version3/go/amcl/BLS24"
+import "github.com/miracl/amcl/version3/go/amcl/BLS48"
 
 func printBinary(array []byte) {
 	for i := 0; i < len(array); i++ {
diff --git a/version3/go/TestNHS.go b/version3/go/TestNHS.go
index 61f2f26..ea338bd 100644
--- a/version3/go/TestNHS.go
+++ b/version3/go/TestNHS.go
@@ -24,7 +24,7 @@ package main
 
 import "fmt"
 
-import "github.com/milagro-crypto/amcl/version3/go/amcl"
+import "github.com/miracl/amcl/version3/go/amcl"
 
 //import "amcl"
 
diff --git a/version3/go/readme.txt b/version3/go/readme.txt
index 3589b01..0cf43bb 100644
--- a/version3/go/readme.txt
+++ b/version3/go/readme.txt
@@ -13,14 +13,17 @@ Make sure that the GOPATH environmental variable is set.
 
 Then clone the AMCL repository by executing
 
-go get github.com/milagro-crypto/amcl
+go get github.com/miracl/amcl
 
 Ignore the warning message about "no Go files"
 
 This assumes that Git is installed on your machine - see 
 https://git-scm.com/download/
 
-Next navigate to $GOPATH/src/github.com/milagro-crypto/amcl/version3/go
+Next navigate to $GOPATH/src/github.com/miracl/amcl/version3/go
+
+NOTE: If the repository address changes, then change the above, and also
+change import statements at the start of some files.
 
 To build the library and see it in action, execute the python3 
 script config32.py or config64.py (depending om whether you want a 
diff --git a/version3/java/AES.java b/version3/java/AES.java
index 35d04dc..5b96394 100644
--- a/version3/java/AES.java
+++ b/version3/java/AES.java
@@ -350,11 +350,25 @@ public class AES {
 			CipherKey[i]=pack(b);
 		}
 		for (i=0;i<nk;i++) fkey[i]=CipherKey[i];
+
 		for (j=nk,k=0;j<N;j+=nk,k++)
 		{
 			fkey[j]=fkey[j-nk]^SubByte(ROTL24(fkey[j-1]))^((int)rco[k])&0xff;
-			for (i=1;i<nk && (i+j)<N;i++)
-				fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1];
+			if (nk<=6)
+			{
+				for (i=1;i<nk && (i+j)<N;i++)
+					fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1];
+			} else {
+				for (i = 1; i < 4 && (i + j) < N; i++) {
+					fkey[i + j] = fkey[i + j - nk] ^ fkey[i + j - 1];
+				}
+				if ((j + 4) < N) {
+					fkey[j + 4] = fkey[j + 4 - nk] ^ SubByte(fkey[j + 3]);
+				}
+				for (i = 5; i < nk && (i + j) < N; i++) {
+					fkey[i + j] = fkey[i + j - nk] ^ fkey[i + j - 1];
+				}
+			}
 		}
 
  /* now for the expanded decrypt key in reverse order */
diff --git a/version3/java/ECP.java b/version3/java/ECP.java
index ce5e3f0..7f8735c 100644
--- a/version3/java/ECP.java
+++ b/version3/java/ECP.java
@@ -29,7 +29,7 @@ public final class ECP {
 
 /* Constructor - set to O */
 	public ECP() {
-		x=new FP(0);
+		x=new FP();
 		y=new FP(1);
 		if (CONFIG_CURVE.CURVETYPE==CONFIG_CURVE.EDWARDS)
 		{
@@ -37,7 +37,7 @@ public final class ECP {
 		}
 		else
 		{
-			z=new FP(0);
+			z=new FP();
 		}
 	}
 
@@ -113,8 +113,8 @@ public final class ECP {
 /* Test P == Q */
 	public boolean equals(ECP Q) {
 
-		FP a=new FP(0);                                        // Edits made
-		FP b=new FP(0);
+		FP a=new FP();                                        // Edits made
+		FP b=new FP();
 		a.copy(x); a.mul(Q.z); 
 		b.copy(Q.x); b.mul(z); 
 		if (!a.equals(b)) return false;
@@ -189,7 +189,7 @@ public final class ECP {
 		}
 		if (CONFIG_CURVE.CURVETYPE==CONFIG_CURVE.MONTGOMERY)
 		{ // x^3+Ax^2+x
-			FP x3=new FP(0);
+			FP x3=new FP();
 			x3.copy(r);
 			x3.mul(x);
 			r.imul(ROM.CURVE_A);
@@ -224,7 +224,7 @@ public final class ECP {
 		x=new FP(ix);
 		x.norm();
 		FP rhs=RHS(x);
-		y=new FP(0);
+		y=new FP();
 		z=new FP(1);
 		if (rhs.jacobi()==1)
 		{
@@ -240,7 +240,7 @@ public final class ECP {
 		x=new FP(ix);
 		x.norm();
 		FP rhs=RHS(x);
-		y=new FP(0);
+		y=new FP();
 		z=new FP(1);
 		if (rhs.jacobi()==1)
 		{
@@ -410,9 +410,9 @@ public final class ECP {
 				FP t2=new FP(z);
 				FP t3=new FP(x);
 				FP z3=new FP(z);
-				FP y3=new FP(0);
-				FP x3=new FP(0);
-				FP b=new FP(0);
+				FP y3=new FP();
+				FP x3=new FP();
+				FP b=new FP();
 
 				if (ROM.CURVE_B_I==0)
 					b.copy(new FP(new BIG(ROM.CURVE_B)));
@@ -477,7 +477,7 @@ public final class ECP {
 			FP C=new FP(x);
 			FP D=new FP(y);
 			FP H=new FP(z);
-			FP J=new FP(0);
+			FP J=new FP();
 
 			x.mul(y); x.add(x); x.norm();
 			C.sqr();
@@ -502,9 +502,9 @@ public final class ECP {
 		{
 			FP A=new FP(x);
 			FP B=new FP(x);		
-			FP AA=new FP(0);
-			FP BB=new FP(0);
-			FP C=new FP(0);
+			FP AA=new FP();
+			FP BB=new FP();
+			FP C=new FP();
 
 			A.add(z); A.norm();
 			AA.copy(A); AA.sqr();
@@ -583,10 +583,10 @@ public final class ECP {
 				FP t2=new FP(z);
 				FP t3=new FP(x);
 				FP t4=new FP(Q.x);
-				FP z3=new FP(0);
+				FP z3=new FP();
 				FP y3=new FP(Q.x);
 				FP x3=new FP(Q.y);
-				FP b=new FP(0);
+				FP b=new FP();
 
 				if (ROM.CURVE_B_I==0)
 					b.copy(new FP(new BIG(ROM.CURVE_B)));
@@ -662,12 +662,12 @@ public final class ECP {
 		if (CONFIG_CURVE.CURVETYPE==CONFIG_CURVE.EDWARDS)
 		{
 			FP A=new FP(z);
-			FP B=new FP(0);
+			FP B=new FP();
 			FP C=new FP(x);
 			FP D=new FP(y);
-			FP E=new FP(0);
-			FP F=new FP(0);
-			FP G=new FP(0);
+			FP E=new FP();
+			FP F=new FP();
+			FP G=new FP();
 
 			A.mul(Q.z);   
 			B.copy(A); B.sqr();    
@@ -721,8 +721,8 @@ public final class ECP {
 		FP B=new FP(x);
 		FP C=new FP(Q.x);
 		FP D=new FP(Q.x);
-		FP DA=new FP(0);
-		FP CB=new FP(0);	
+		FP DA=new FP();
+		FP CB=new FP();	
 			
 		A.add(z); 
 		B.sub(z); 
diff --git a/version3/java/ECP2.java b/version3/java/ECP2.java
index d86375a..cc2ab16 100644
--- a/version3/java/ECP2.java
+++ b/version3/java/ECP2.java
@@ -28,9 +28,9 @@ public final class ECP2 {
 
 /* Constructor - set this=O */
 	public ECP2() {
-		x=new FP2(0);
+		x=new FP2();
 		y=new FP2(1);
-		z=new FP2(0);
+		z=new FP2();
 	}
 
     public ECP2(ECP2 e) {
diff --git a/version3/java/ECP4.java b/version3/java/ECP4.java
index c84af43..88bb225 100644
--- a/version3/java/ECP4.java
+++ b/version3/java/ECP4.java
@@ -28,9 +28,9 @@ public final class ECP4 {
 
 /* Constructor - set this=O */
 	public ECP4() {
-		x=new FP4(0);
+		x=new FP4();
 		y=new FP4(1);
-		z=new FP4(0);
+		z=new FP4();
 	}
 
     public ECP4(ECP4 e) {
diff --git a/version3/java/ECP8.java b/version3/java/ECP8.java
index 395952b..e5b3733 100644
--- a/version3/java/ECP8.java
+++ b/version3/java/ECP8.java
@@ -28,9 +28,9 @@ public final class ECP8 {
 
 /* Constructor - set this=O */
 	public ECP8() {
-		x=new FP8(0);
+		x=new FP8();
 		y=new FP8(1);
-		z=new FP8(0);
+		z=new FP8();
 	}
 
     public ECP8(ECP8 e) {
diff --git a/version3/java/FP12.java b/version3/java/FP12.java
index 551037c..0cad174 100644
--- a/version3/java/FP12.java
+++ b/version3/java/FP12.java
@@ -145,6 +145,16 @@ public final class FP12 {
 		c.zero();
 		type=ONE;
 	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+		c.zero();
+		type=ZERO;
+	}
+
 /* this=conj(this) */
 	public void conj()
 	{
@@ -156,16 +166,24 @@ public final class FP12 {
 	public FP12(FP4 d)
 	{
 		a=new FP4(d);
-		b=new FP4(0);
-		c=new FP4(0);
+		b=new FP4();
+		c=new FP4();
 		type=SPARSER;
 	}
 
+	public FP12()
+	{
+		a=new FP4();
+		b=new FP4();
+		c=new FP4();
+		type=ZERO;
+	}
+
 	public FP12(int d)
 	{
 		a=new FP4(d);
-		b=new FP4(0);
-		c=new FP4(0);
+		b=new FP4();
+		c=new FP4();
 		if (d==1)
 			type=ONE;
 		else
@@ -194,7 +212,7 @@ public final class FP12 {
 		FP4 A=new FP4(a);
 		FP4 B=new FP4(c);
 		FP4 C=new FP4(b);
-		FP4 D=new FP4(0);
+		FP4 D=new FP4();
 
 		a.sqr();
 		D.copy(a); D.add(a);
@@ -279,9 +297,9 @@ public final class FP12 {
 	public void mul(FP12 y)
 	{
 		FP4 z0=new FP4(a);
-		FP4 z1=new FP4(0);
+		FP4 z1=new FP4();
 		FP4 z2=new FP4(b);
-		FP4 z3=new FP4(0);
+		FP4 z3=new FP4();
 		FP4 t0=new FP4(a);
 		FP4 t1=new FP4(y.a);
 
@@ -464,9 +482,9 @@ public final class FP12 {
 		if (y.type>=SPARSE)
 		{
 			FP4 z0=new FP4(a);
-			FP4 z1=new FP4(0);
-			FP4 z2=new FP4(0);
-			FP4 z3=new FP4(0);
+			FP4 z1=new FP4();
+			FP4 z2=new FP4();
+			FP4 z3=new FP4();
 			z0.mul(y.a);
 
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
@@ -566,7 +584,7 @@ public final class FP12 {
 				FP4 z0=new FP4(a);
 				FP4 z2=new FP4(b);
 				FP4 z3=new FP4(b);
-				FP4 t0=new FP4(0);
+				FP4 t0=new FP4();
 				FP4 t1=new FP4(y.a);
 				z0.mul(y.a);
 				z2.pmul(y.b.real());
@@ -600,11 +618,11 @@ public final class FP12 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
 				FP4 z0=new FP4(a);
-				FP4 z1=new FP4(0);
-				FP4 z2=new FP4(0);
-				FP4 z3=new FP4(0);
+				FP4 z1=new FP4();
+				FP4 z2=new FP4();
+				FP4 z3=new FP4();
 				FP4 t0=new FP4(a);
-				FP4 t1=new FP4(0);
+				FP4 t1=new FP4();
 		
 				z0.mul(y.a);
 				t0.add(b); t0.norm();
@@ -654,7 +672,7 @@ public final class FP12 {
 			FP4 z0=new FP4(a);
 			FP4 z2=new FP4(b);
 			FP4 z3=new FP4(b);
-			FP4 t0=new FP4(0);
+			FP4 t0=new FP4();
 			FP4 t1=new FP4(y.a);
 			z0.mul(y.a);
 			z2.pmul(y.b.real());
@@ -689,11 +707,11 @@ public final class FP12 {
 		if (type==CONFIG_CURVE.M_TYPE)
 		{
 			FP4 z0=new FP4(a);
-			FP4 z1=new FP4(0);
-			FP4 z2=new FP4(0);
-			FP4 z3=new FP4(0);
+			FP4 z1=new FP4();
+			FP4 z2=new FP4();
+			FP4 z3=new FP4();
 			FP4 t0=new FP4(a);
-			FP4 t1=new FP4(0);
+			FP4 t1=new FP4();
 		
 			z0.mul(y.a);
 			t0.add(b);
@@ -746,7 +764,7 @@ public final class FP12 {
 		FP4 f0=new FP4(a);
 		FP4 f1=new FP4(b);
 		FP4 f2=new FP4(a);
-		FP4 f3=new FP4(0);
+		FP4 f3=new FP4();
 
 		norm();
 		f0.sqr();
@@ -803,7 +821,7 @@ public final class FP12 {
 /* trace function */
 	public FP4 trace()
 	{
-		FP4 t=new FP4(0);
+		FP4 t=new FP4();
 		t.copy(a);
 		t.imul(3);
 		t.reduce();
diff --git a/version3/java/FP16.java b/version3/java/FP16.java
index dc2415d..6ebfd92 100644
--- a/version3/java/FP16.java
+++ b/version3/java/FP16.java
@@ -81,10 +81,16 @@ public final class FP16 {
 		return (a.equals(x.a) && b.equals(x.b));
 	}
 /* constructors */
+	public FP16()
+	{
+		a=new FP8();
+		b=new FP8();
+	}
+
 	public FP16(int c)
 	{
 		a=new FP8(c);
-		b=new FP8(0);
+		b=new FP8();
 	}
 
 	public FP16(FP16 x)
@@ -102,7 +108,7 @@ public final class FP16 {
 	public FP16(FP8 c)
 	{
 		a=new FP8(c);
-		b=new FP8(0);
+		b=new FP8();
 	}
 /* copy this=x */
 	public void copy(FP16 x)
@@ -128,7 +134,7 @@ public final class FP16 {
 	{
 		norm();
 		FP8 m=new FP8(a);
-		FP8 t=new FP8(0);
+		FP8 t=new FP8();
 		m.add(b);
 		m.neg();
 		t.copy(m); t.add(b);
@@ -227,7 +233,7 @@ public final class FP16 {
 	{
 		FP8 t1=new FP8(a);
 		FP8 t2=new FP8(b);
-		FP8 t3=new FP8(0);
+		FP8 t3=new FP8();
 		FP8 t4=new FP8(b);
 
 		t1.mul(y.a);
@@ -375,8 +381,8 @@ public final class FP16 {
 		FP16 b=new FP16(sf);
 		FP16 c=new FP16(b);
 		c.xtr_D();
-		FP16 t=new FP16(0);
-		FP16 r=new FP16(0);
+		FP16 t=new FP16();
+		FP16 r=new FP16();
 
 		
 		int par=n.parity();
@@ -423,8 +429,8 @@ public final class FP16 {
 		FP16 cv=new FP16(this);
 		FP16 cumv=new FP16(ckml);
 		FP16 cum2v=new FP16(ckm2l);
-		FP16 r=new FP16(0);
-		FP16 t=new FP16(0);
+		FP16 r=new FP16();
+		FP16 t=new FP16();
 
 		int f2=0;
 		while (d.parity()==0 && e.parity()==0)
diff --git a/version3/java/FP2.java b/version3/java/FP2.java
index 7446dcd..e3b2918 100644
--- a/version3/java/FP2.java
+++ b/version3/java/FP2.java
@@ -64,10 +64,16 @@ public final class FP2 {
 	}
 
 /* Constructors */
+	public FP2()
+	{
+		a=new FP();
+		b=new FP();
+	}
+
 	public FP2(int c)
 	{
 		a=new FP(c);
-		b=new FP(0);
+		b=new FP();
 	}
 
 	public FP2(FP2 x)
@@ -91,13 +97,13 @@ public final class FP2 {
 	public FP2(FP c)
 	{
 		a=new FP(c);
-		b=new FP(0);
+		b=new FP();
 	}
 
 	public FP2(BIG c)
 	{
 		a=new FP(c);
-		b=new FP(0);
+		b=new FP();
 	}
 
 /* extract a */
@@ -137,7 +143,7 @@ public final class FP2 {
 	public void neg()
 	{
 		FP m=new FP(a);
-		FP t=new FP(0);
+		FP t=new FP();
 
 		m.add(b);
 		m.neg();
@@ -327,7 +333,7 @@ public final class FP2 {
 
 	public void div_ip2()
 	{
-		FP2 t=new FP2(0);
+		FP2 t=new FP2();
 		norm();
 		t.a.copy(a); t.a.add(b);
 		t.b.copy(b); t.b.sub(a);
@@ -338,7 +344,7 @@ public final class FP2 {
 /* w/=(1+sqrt(-1)) */
 	public void div_ip()
 	{
-		FP2 t=new FP2(0);
+		FP2 t=new FP2();
 		norm();
 		t.a.copy(a); t.a.add(b);
 		t.b.copy(b); t.b.sub(a);
diff --git a/version3/java/FP24.java b/version3/java/FP24.java
index 9338ea6..3bc18ae 100644
--- a/version3/java/FP24.java
+++ b/version3/java/FP24.java
@@ -144,6 +144,15 @@ public final class FP24 {
 		c.zero();
 		type=ONE;
 	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+		c.zero();
+		type=ZERO;
+	}
+
 /* this=conj(this) */
 	public void conj()
 	{
@@ -155,16 +164,24 @@ public final class FP24 {
 	public FP24(FP8 d)
 	{
 		a=new FP8(d);
-		b=new FP8(0);
-		c=new FP8(0);
+		b=new FP8();
+		c=new FP8();
 		type=SPARSER;
 	}
 
+	public FP24()
+	{
+		a=new FP8();
+		b=new FP8();
+		c=new FP8();
+		type=ZERO;
+	}
+
 	public FP24(int d)
 	{
 		a=new FP8(d);
-		b=new FP8(0);
-		c=new FP8(0);
+		b=new FP8();
+		c=new FP8();
 		if (d==1)
 			type=ONE;
 		else
@@ -193,7 +210,7 @@ public final class FP24 {
 		FP8 A=new FP8(a);
 		FP8 B=new FP8(c);
 		FP8 C=new FP8(b);
-		FP8 D=new FP8(0);
+		FP8 D=new FP8();
 
 		a.sqr();
 		D.copy(a); D.add(a);
@@ -278,9 +295,9 @@ public final class FP24 {
 	public void mul(FP24 y)
 	{
 		FP8 z0=new FP8(a);
-		FP8 z1=new FP8(0);
+		FP8 z1=new FP8();
 		FP8 z2=new FP8(b);
-		FP8 z3=new FP8(0);
+		FP8 z3=new FP8();
 		FP8 t0=new FP8(a);
 		FP8 t1=new FP8(y.a);
 
@@ -464,9 +481,9 @@ public final class FP24 {
 		if (y.type>=SPARSE)
 		{
 			FP8 z0=new FP8(a);
-			FP8 z1=new FP8(0);
-			FP8 z2=new FP8(0);
-			FP8 z3=new FP8(0);
+			FP8 z1=new FP8();
+			FP8 z2=new FP8();
+			FP8 z3=new FP8();
 			z0.mul(y.a);
 
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
@@ -566,7 +583,7 @@ public final class FP24 {
 				FP8 z0=new FP8(a);
 				FP8 z2=new FP8(b);
 				FP8 z3=new FP8(b);
-				FP8 t0=new FP8(0);
+				FP8 t0=new FP8();
 				FP8 t1=new FP8(y.a);
 				z0.mul(y.a);
 				z2.pmul(y.b.real());
@@ -600,11 +617,11 @@ public final class FP24 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
 				FP8 z0=new FP8(a);
-				FP8 z1=new FP8(0);
-				FP8 z2=new FP8(0);
-				FP8 z3=new FP8(0);
+				FP8 z1=new FP8();
+				FP8 z2=new FP8();
+				FP8 z3=new FP8();
 				FP8 t0=new FP8(a);
-				FP8 t1=new FP8(0);
+				FP8 t1=new FP8();
 		
 				z0.mul(y.a);
 				t0.add(b); t0.norm();
@@ -652,7 +669,7 @@ public final class FP24 {
 		FP8 f0=new FP8(a);
 		FP8 f1=new FP8(b);
 		FP8 f2=new FP8(a);
-		FP8 f3=new FP8(0);
+		FP8 f3=new FP8();
 
 		//norm();
 		f0.sqr();
@@ -714,7 +731,7 @@ public final class FP24 {
 /* trace function */
 	public FP8 trace()
 	{
-		FP8 t=new FP8(0);
+		FP8 t=new FP8();
 		t.copy(a);
 		t.imul(3);
 		t.reduce();
@@ -943,8 +960,8 @@ public final class FP24 {
 
 	public FP8 compow(BIG e,BIG r)
 	{
-		FP24 g1=new FP24(0);
-		FP24 g2=new FP24(0);
+		FP24 g1=new FP24();
+		FP24 g2=new FP24();
 		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
 		BIG q=new BIG(ROM.Modulus);
 
@@ -992,7 +1009,7 @@ public final class FP24 {
 		FP24 [] g1=new FP24[8];
 		FP24 [] g2=new FP24[8];
 		FP24 r=new FP24(1);
-		FP24 p=new FP24(0);
+		FP24 p=new FP24();
 		BIG [] t=new BIG[8];
 		BIG mt=new BIG(0);
 		byte[] w1=new byte[BIG.NLEN*CONFIG_BIG.BASEBITS+1];
diff --git a/version3/java/FP32.java b/version3/java/FP32.java
index 6830e09..25284fd 100644
--- a/version3/java/FP32.java
+++ b/version3/java/FP32.java
@@ -545,6 +545,7 @@ public final class FP {
 	{
 		byte[] w=new byte[1+(BIG.NLEN*CONFIG_BIG.BASEBITS+3)/4];
 		FP [] tb=new FP[16];
+		norm();
 		BIG t=new BIG(e);
 		t.norm();
 		int nb=1+(t.nbits()+3)/4;
diff --git a/version3/java/FP4.java b/version3/java/FP4.java
index 52bcb44..d69cc67 100644
--- a/version3/java/FP4.java
+++ b/version3/java/FP4.java
@@ -81,10 +81,16 @@ public final class FP4 {
 		return (a.equals(x.a) && b.equals(x.b));
 	}
 /* constructors */
+	public FP4()
+	{
+		a=new FP2();
+		b=new FP2();
+	}
+
 	public FP4(int c)
 	{
 		a=new FP2(c);
-		b=new FP2(0);
+		b=new FP2();
 	}
 
 	public FP4(FP4 x)
@@ -102,7 +108,7 @@ public final class FP4 {
 	public FP4(FP2 c)
 	{
 		a=new FP2(c);
-		b=new FP2(0);
+		b=new FP2();
 	}
 /* copy this=x */
 	public void copy(FP4 x)
@@ -127,7 +133,7 @@ public final class FP4 {
 	{
 		norm();
 		FP2 m=new FP2(a);
-		FP2 t=new FP2(0);
+		FP2 t=new FP2();
 		m.add(b);
 		m.neg();
 		t.copy(m); t.add(b);
@@ -218,7 +224,7 @@ public final class FP4 {
 	{
 		FP2 t1=new FP2(a);
 		FP2 t2=new FP2(b);
-		FP2 t3=new FP2(0);
+		FP2 t3=new FP2();
 		FP2 t4=new FP2(b);
 
 		t1.mul(y.a);
@@ -355,8 +361,8 @@ public final class FP4 {
 		FP4 b=new FP4(sf);
 		FP4 c=new FP4(b);
 		c.xtr_D();
-		FP4 t=new FP4(0);
-		FP4 r=new FP4(0);
+		FP4 t=new FP4();
+		FP4 r=new FP4();
 
 		int par=n.parity();
 		BIG v=new BIG(n); v.norm(); v.fshr(1);
@@ -404,8 +410,8 @@ public final class FP4 {
 		FP4 cv=new FP4(this);
 		FP4 cumv=new FP4(ckml);
 		FP4 cum2v=new FP4(ckm2l);
-		FP4 r=new FP4(0);
-		FP4 t=new FP4(0);
+		FP4 r=new FP4();
+		FP4 t=new FP4();
 
 		int f2=0;
 		while (d.parity()==0 && e.parity()==0)
diff --git a/version3/java/FP48.java b/version3/java/FP48.java
index e0dc3c4..dabb633 100644
--- a/version3/java/FP48.java
+++ b/version3/java/FP48.java
@@ -145,6 +145,16 @@ public final class FP48 {
 		c.zero();
 		type=ONE;
 	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+		c.zero();
+		type=ZERO;
+	}
+
 /* this=conj(this) */
 	public void conj()
 	{
@@ -156,16 +166,24 @@ public final class FP48 {
 	public FP48(FP16 d)
 	{
 		a=new FP16(d);
-		b=new FP16(0);
-		c=new FP16(0);
+		b=new FP16();
+		c=new FP16();
 		type=SPARSER;
 	}
 
+	public FP48()
+	{
+		a=new FP16();
+		b=new FP16();
+		c=new FP16();
+		type=ZERO;
+	}
+
 	public FP48(int d)
 	{
 		a=new FP16(d);
-		b=new FP16(0);
-		c=new FP16(0);
+		b=new FP16();
+		c=new FP16();
 		if (d==1)
 			type=ONE;
 		else
@@ -194,7 +212,7 @@ public final class FP48 {
 		FP16 A=new FP16(a);
 		FP16 B=new FP16(c);
 		FP16 C=new FP16(b);
-		FP16 D=new FP16(0);
+		FP16 D=new FP16();
 
 		a.sqr();
 		D.copy(a); D.add(a);
@@ -279,9 +297,9 @@ public final class FP48 {
 	public void mul(FP48 y)
 	{
 		FP16 z0=new FP16(a);
-		FP16 z1=new FP16(0);
+		FP16 z1=new FP16();
 		FP16 z2=new FP16(b);
-		FP16 z3=new FP16(0);
+		FP16 z3=new FP16();
 		FP16 t0=new FP16(a);
 		FP16 t1=new FP16(y.a);
 
@@ -464,9 +482,9 @@ public final class FP48 {
 		if (y.type>=SPARSE)
 		{
 			FP16 z0=new FP16(a);
-			FP16 z1=new FP16(0);
-			FP16 z2=new FP16(0);
-			FP16 z3=new FP16(0);
+			FP16 z1=new FP16();
+			FP16 z2=new FP16();
+			FP16 z3=new FP16();
 			z0.mul(y.a);
 
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
@@ -566,7 +584,7 @@ public final class FP48 {
 				FP16 z0=new FP16(a);
 				FP16 z2=new FP16(b);
 				FP16 z3=new FP16(b);
-				FP16 t0=new FP16(0);
+				FP16 t0=new FP16();
 				FP16 t1=new FP16(y.a);
 				z0.mul(y.a);
 				z2.pmul(y.b.real());
@@ -600,11 +618,11 @@ public final class FP48 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
 				FP16 z0=new FP16(a);
-				FP16 z1=new FP16(0);
-				FP16 z2=new FP16(0);
-				FP16 z3=new FP16(0);
+				FP16 z1=new FP16();
+				FP16 z2=new FP16();
+				FP16 z3=new FP16();
 				FP16 t0=new FP16(a);
-				FP16 t1=new FP16(0);
+				FP16 t1=new FP16();
 		
 				z0.mul(y.a);
 				t0.add(b); t0.norm();
@@ -651,7 +669,7 @@ public final class FP48 {
 		FP16 f0=new FP16(a);
 		FP16 f1=new FP16(b);
 		FP16 f2=new FP16(a);
-		FP16 f3=new FP16(0);
+		FP16 f3=new FP16();
 
 		//norm();
 		f0.sqr();
@@ -714,7 +732,7 @@ public final class FP48 {
 /* trace function */
 	public FP16 trace()
 	{
-		FP16 t=new FP16(0);
+		FP16 t=new FP16();
 		t.copy(a);
 		t.imul(3);
 		t.reduce();
@@ -1085,8 +1103,8 @@ public final class FP48 {
 
 	public FP16 compow(BIG e,BIG r)
 	{
-		FP48 g1=new FP48(0);
-		FP48 g2=new FP48(0);
+		FP48 g1=new FP48();
+		FP48 g2=new FP48();
 		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
 		BIG q=new BIG(ROM.Modulus);
 
@@ -1136,7 +1154,7 @@ public final class FP48 {
 		FP48 [] g3=new FP48[8];
 		FP48 [] g4=new FP48[8];
 		FP48 r=new FP48(1);
-		FP48 p=new FP48(0);
+		FP48 p=new FP48();
 		BIG [] t=new BIG[16];
 		BIG mt=new BIG(0);
 		byte[] w1=new byte[BIG.NLEN*CONFIG_BIG.BASEBITS+1];
diff --git a/version3/java/FP64.java b/version3/java/FP64.java
index a72bbb9..eca22c5 100644
--- a/version3/java/FP64.java
+++ b/version3/java/FP64.java
@@ -546,6 +546,7 @@ public final class FP {
 	{
 		byte[] w=new byte[1+(BIG.NLEN*CONFIG_BIG.BASEBITS+3)/4];
 		FP [] tb=new FP[16];
+		norm();
 		BIG t=new BIG(e);
 		t.norm();
 		int nb=1+(t.nbits()+3)/4;
diff --git a/version3/java/FP8.java b/version3/java/FP8.java
index 58dee2b..23de47c 100644
--- a/version3/java/FP8.java
+++ b/version3/java/FP8.java
@@ -81,10 +81,16 @@ public final class FP8 {
 		return (a.equals(x.a) && b.equals(x.b));
 	}
 /* constructors */
+	public FP8()
+	{
+		a=new FP4();
+		b=new FP4();
+	}
+
 	public FP8(int c)
 	{
 		a=new FP4(c);
-		b=new FP4(0);
+		b=new FP4();
 	}
 
 	public FP8(FP8 x)
@@ -102,7 +108,7 @@ public final class FP8 {
 	public FP8(FP4 c)
 	{
 		a=new FP4(c);
-		b=new FP4(0);
+		b=new FP4();
 	}
 /* copy this=x */
 	public void copy(FP8 x)
@@ -127,7 +133,7 @@ public final class FP8 {
 	{
 		norm();
 		FP4 m=new FP4(a);
-		FP4 t=new FP4(0);
+		FP4 t=new FP4();
 		m.add(b);
 
 		m.neg();
@@ -233,7 +239,7 @@ public final class FP8 {
 	{
 		FP4 t1=new FP4(a);
 		FP4 t2=new FP4(b);
-		FP4 t3=new FP4(0);
+		FP4 t3=new FP4();
 		FP4 t4=new FP4(b);
 
 		t1.mul(y.a);
@@ -377,8 +383,8 @@ public final class FP8 {
 		FP8 b=new FP8(sf);
 		FP8 c=new FP8(b);
 		c.xtr_D();
-		FP8 t=new FP8(0);
-		FP8 r=new FP8(0);
+		FP8 t=new FP8();
+		FP8 r=new FP8();
 		
 		int par=n.parity();
 		BIG v=new BIG(n); v.norm(); v.fshr(1);
@@ -426,8 +432,8 @@ public final class FP8 {
 		FP8 cv=new FP8(this);
 		FP8 cumv=new FP8(ckml);
 		FP8 cum2v=new FP8(ckm2l);
-		FP8 r=new FP8(0);
-		FP8 t=new FP8(0);
+		FP8 r=new FP8();
+		FP8 t=new FP8();
 
 		int f2=0;
 		while (d.parity()==0 && e.parity()==0)
diff --git a/version3/java/OLDECP.java b/version3/java/OLDECP.java
index 6d5bb2e..3e0f049 100644
--- a/version3/java/OLDECP.java
+++ b/version3/java/OLDECP.java
@@ -54,9 +54,9 @@ public final class ECP {
 /* Constructor - set to O */
 	public ECP() {
 		INF=true;
-		x=new FP(0);
+		x=new FP();
 		y=new FP(1);
-		z=new FP(0);
+		z=new FP();
 	}
 /* test for O point-at-infinity */
 	public boolean is_infinity() {
@@ -142,8 +142,8 @@ public final class ECP {
 		if (is_infinity() && Q.is_infinity()) return true;
 		if (is_infinity() || Q.is_infinity()) return false;
 
-		FP a=new FP(0);                                        // Edits made
-		FP b=new FP(0);
+		FP a=new FP();                                        // Edits made
+		FP b=new FP();
 		a.copy(x); a.mul(Q.z); 
 		b.copy(Q.x); b.mul(z); 
 		if (!a.equals(b)) return false;
@@ -221,7 +221,7 @@ public final class ECP {
 		}
 		if (CURVETYPE==MONTGOMERY)
 		{ // x^3+Ax^2+x
-			FP x3=new FP(0);
+			FP x3=new FP();
 			x3.copy(r);
 			x3.mul(x);
 			r.imul(ROM.CURVE_A);
@@ -256,7 +256,7 @@ public final class ECP {
 	public ECP(BIG ix,int s) {
 		x=new FP(ix);
 		FP rhs=RHS(x);
-		y=new FP(0);
+		y=new FP();
 		z=new FP(1);
 		if (rhs.jacobi()==1)
 		{
@@ -272,7 +272,7 @@ public final class ECP {
 	public ECP(BIG ix) {
 		x=new FP(ix);
 		FP rhs=RHS(x);
-		y=new FP(0);
+		y=new FP();
 		z=new FP(1);
 		if (rhs.jacobi()==1)
 		{
@@ -423,9 +423,9 @@ public final class ECP {
 				FP t2=new FP(z);
 				FP t3=new FP(x);
 				FP z3=new FP(z);
-				FP y3=new FP(0);
-				FP x3=new FP(0);
-				FP b=new FP(0);
+				FP y3=new FP();
+				FP x3=new FP();
+				FP b=new FP();
 
 				if (ROM.CURVE_B_I==0)
 					b.copy(new FP(new BIG(ROM.CURVE_B)));
@@ -491,7 +491,7 @@ public final class ECP {
 			FP C=new FP(x);
 			FP D=new FP(y);
 			FP H=new FP(z);
-			FP J=new FP(0);
+			FP J=new FP();
 
 			x.mul(y); x.add(x); x.norm();
 			C.sqr();
@@ -517,9 +517,9 @@ public final class ECP {
 		{
 			FP A=new FP(x);
 			FP B=new FP(x);		
-			FP AA=new FP(0);
-			FP BB=new FP(0);
-			FP C=new FP(0);
+			FP AA=new FP();
+			FP BB=new FP();
+			FP C=new FP();
 
 			A.add(z); A.norm();
 			AA.copy(A); AA.sqr();
@@ -609,10 +609,10 @@ public final class ECP {
 				FP t2=new FP(z);
 				FP t3=new FP(x);
 				FP t4=new FP(Q.x);
-				FP z3=new FP(0);
+				FP z3=new FP();
 				FP y3=new FP(Q.x);
 				FP x3=new FP(Q.y);
-				FP b=new FP(0);
+				FP b=new FP();
 
 				if (ROM.CURVE_B_I==0)
 					b.copy(new FP(new BIG(ROM.CURVE_B)));
@@ -689,12 +689,12 @@ public final class ECP {
 		{
 //System.out.println("Into add");
 			FP A=new FP(z);
-			FP B=new FP(0);
+			FP B=new FP();
 			FP C=new FP(x);
 			FP D=new FP(y);
-			FP E=new FP(0);
-			FP F=new FP(0);
-			FP G=new FP(0);
+			FP E=new FP();
+			FP F=new FP();
+			FP G=new FP();
 
 			A.mul(Q.z);   
 			B.copy(A); B.sqr();    
@@ -749,8 +749,8 @@ public final class ECP {
 		FP B=new FP(x);
 		FP C=new FP(Q.x);
 		FP D=new FP(Q.x);
-		FP DA=new FP(0);
-		FP CB=new FP(0);	
+		FP DA=new FP();
+		FP CB=new FP();	
 			
 		A.add(z); 
 		B.sub(z); 
diff --git a/version3/java/OLDECP2.java b/version3/java/OLDECP2.java
index fb11645..f07419c 100644
--- a/version3/java/OLDECP2.java
+++ b/version3/java/OLDECP2.java
@@ -30,9 +30,9 @@ public final class ECP2 {
 /* Constructor - set this=O */
 	public ECP2() {
 		INF=true;
-		x=new FP2(0);
+		x=new FP2();
 		y=new FP2(1);
-		z=new FP2(0);
+		z=new FP2();
 	}
 
 /* Test this=O? */
diff --git a/version3/java/PAIR.java b/version3/java/PAIR.java
index 2ad5e7c..35fee5f 100644
--- a/version3/java/PAIR.java
+++ b/version3/java/PAIR.java
@@ -71,11 +71,11 @@ public final class PAIR {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{			
 				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
-				c=new FP4(0);
+				c=new FP4();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP4(0);
+				b=new FP4();
 				c=new FP4(XX); c.times_i();
 			}
 			A.dbl();
@@ -114,17 +114,17 @@ public final class PAIR {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{
 				b=new FP4(Y1);
-				c=new FP4(0);
+				c=new FP4();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP4(0);
+				b=new FP4();
 				c=new FP4(Y1); c.times_i();
 			}
 			A.add(B);
 		}
 		FP12 r=new FP12(a,b,c);
-		r.settype(FP12.SPARSE);
+		r.settype(FP12.SPARSER);
 		return r;
 	}
 
@@ -462,6 +462,11 @@ public final class PAIR {
 		r.frob(f);
 		r.frob(f);
 		r.mul(lv);
+		if (r.isunity())
+		{
+			r.zero();
+			return r;
+		}
 /* Hard part of final exp */
 		if (CONFIG_CURVE.CURVE_PAIRING_TYPE==CONFIG_CURVE.BN)
 		{
diff --git a/version3/java/PAIR192.java b/version3/java/PAIR192.java
index 9b9f975..c470ca2 100644
--- a/version3/java/PAIR192.java
+++ b/version3/java/PAIR192.java
@@ -72,11 +72,11 @@ public final class PAIR192 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{			
 				b=new FP8(XX);             // L(0,1) | L(0,0) | L(1,0)
-				c=new FP8(0);
+				c=new FP8();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP8(0);
+				b=new FP8();
 				c=new FP8(XX); c.times_i();
 			}
 			A.dbl();
@@ -115,17 +115,17 @@ public final class PAIR192 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{
 				b=new FP8(Y1);
-				c=new FP8(0);
+				c=new FP8();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP8(0);
+				b=new FP8();
 				c=new FP8(Y1); c.times_i();
 			}
 			A.add(B);
 		}
 		FP24 r=new FP24(a,b,c);
-		r.settype(FP24.SPARSE);
+		r.settype(FP24.SPARSER);
 		return r;
 	}
 
@@ -356,7 +356,11 @@ public final class PAIR192 {
 		lv.copy(r);
 		r.frob(f,4);
 		r.mul(lv);
-
+		if (r.isunity())
+		{
+			r.zero();
+			return r;
+		}
 		FP24 t0,t1,t2,t3,t4,t5,t6,t7;
 /* Hard part of final exp */	
 // Ghamman & Fouotsa Method
@@ -582,7 +586,7 @@ public final class PAIR192 {
 			g[0]=new FP24(d);
 			for (i=1;i<8;i++)
 			{
-				g[i]=new FP24(0); g[i].copy(g[i-1]);
+				g[i]=new FP24(); g[i].copy(g[i-1]);
 				g[i].frob(f,1);
 			}
 			for (i=0;i<8;i++)
diff --git a/version3/java/PAIR256.java b/version3/java/PAIR256.java
index d327975..2eb0b63 100644
--- a/version3/java/PAIR256.java
+++ b/version3/java/PAIR256.java
@@ -71,11 +71,11 @@ public final class PAIR256 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{			
 				b=new FP16(XX);             // L(0,1) | L(0,0) | L(1,0)
-				c=new FP16(0);
+				c=new FP16();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP16(0);
+				b=new FP16();
 				c=new FP16(XX); c.times_i();
 			}
 			A.dbl();
@@ -114,17 +114,17 @@ public final class PAIR256 {
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.D_TYPE)
 			{
 				b=new FP16(Y1);
-				c=new FP16(0);
+				c=new FP16();
 			}
 			if (CONFIG_CURVE.SEXTIC_TWIST==CONFIG_CURVE.M_TYPE)
 			{
-				b=new FP16(0);
+				b=new FP16();
 				c=new FP16(Y1); c.times_i();
 			}
 			A.add(B);
 		}
 		FP48 r=new FP48(a,b,c);
-		r.settype(FP48.SPARSE);
+		r.settype(FP48.SPARSER);
 		return r;
 	}
 
@@ -355,7 +355,11 @@ public final class PAIR256 {
 		lv.copy(r);
 		r.frob(f,8);
 		r.mul(lv);
-
+		if (r.isunity())
+		{
+			r.zero();
+			return r;
+		}
 		FP48 t0,t1,t2,t3,t4,t5,t6,t7;
 /* Hard part of final exp */	
 // Ghamman & Fouotsa Method
@@ -658,7 +662,7 @@ public final class PAIR256 {
 			g[0]=new FP48(d);
 			for (i=1;i<16;i++)
 			{
-				g[i]=new FP48(0); g[i].copy(g[i-1]);
+				g[i]=new FP48(); g[i].copy(g[i-1]);
 				g[i].frob(f,1);
 			}
 			for (i=0;i<16;i++)
diff --git a/version3/js/aes.js b/version3/js/aes.js
index 59a53dc..712c4ec 100644
--- a/version3/js/aes.js
+++ b/version3/js/aes.js
@@ -122,11 +122,26 @@ var AES = function() {
 
             for (j = nk, k = 0; j < N; j += nk, k++) {
                 this.fkey[j] = this.fkey[j - nk] ^ AES.SubByte(AES.ROTL24(this.fkey[j - 1])) ^ (AES.rco[k]) & 0xff;
-                for (i = 1; i < nk && (i + j) < N; i++) {
-                    this.fkey[i + j] = this.fkey[i + j - nk] ^ this.fkey[i + j - 1];
-                }
+
+				if (nk<=6)
+				{
+					for (i = 1; i < nk && (i + j) < N; i++) {
+						this.fkey[i + j] = this.fkey[i + j - nk] ^ this.fkey[i + j - 1];
+					}
+				} else {
+					for (i = 1; i < 4 && (i + j) < N; i++) {
+						this.fkey[i + j] = this.fkey[i + j - nk] ^ this.fkey[i + j - 1];
+					}
+					if ((j + 4) < N) {
+						this.fkey[j + 4] = this.fkey[j + 4 - nk] ^ AES.SubByte(this.fkey[j + 3]);
+					}
+					for (i = 5; i < nk && (i + j) < N; i++) {
+						this.fkey[i + j] = this.fkey[i + j - nk] ^ this.fkey[i + j - 1];
+					}
+				}
             }
 
+
             /* now for the expanded decrypt key in reverse order */
 
             for (j = 0; j < 4; j++) {
diff --git a/version3/js/fp.js b/version3/js/fp.js
index 2b939a2..925c20b 100644
--- a/version3/js/fp.js
+++ b/version3/js/fp.js
@@ -30,7 +30,9 @@ var FP = function(ctx) {
             this.XES = x.XES;
         } else {
             this.f = new ctx.BIG(x);
-            this.nres();
+			this.XES = 1;
+			if (x!=0)
+				this.nres();
         }
     };
 
@@ -472,7 +474,7 @@ var FP = function(ctx) {
                 tb=[],
                 t=new ctx.BIG(e),
                 nb, lsbs, r;
-
+			this.norm();
             t.norm();
             nb= 1 + Math.floor((t.nbits() + 3) / 4);
 
diff --git a/version3/js/fp12.js b/version3/js/fp12.js
index e013e42..c68f3cd 100644
--- a/version3/js/fp12.js
+++ b/version3/js/fp12.js
@@ -153,6 +153,14 @@ var FP12 = function(ctx) {
 			this.stype=ctx.FP.ONE;
         },
 
+        /* set this=0 */
+        zero: function() {
+            this.a.zero();
+            this.b.zero();
+            this.c.zero();
+			this.stype=ctx.FP.ZERO;
+        },
+
         /* this=conj(this) */
         conj: function() {
             this.a.conj();
diff --git a/version3/js/fp24.js b/version3/js/fp24.js
index 609d00e..c235d8f 100644
--- a/version3/js/fp24.js
+++ b/version3/js/fp24.js
@@ -150,6 +150,14 @@ var FP24 = function(ctx) {
 			this.stype=ctx.FP.ONE;
         },
 
+        /* set this=0 */
+        zero: function() {
+            this.a.zero();
+            this.b.zero();
+            this.c.zero();
+			this.stype=ctx.FP.ZERO;
+        },
+
         /* this=conj(this) */
         conj: function() {
             this.a.conj();
diff --git a/version3/js/fp48.js b/version3/js/fp48.js
index e5a4bea..ca9e0ad 100644
--- a/version3/js/fp48.js
+++ b/version3/js/fp48.js
@@ -152,6 +152,14 @@ var FP48 = function(ctx) {
 			this.stype=ctx.FP.ONE;
         },
 
+        /* set this=0 */
+        zero: function() {
+            this.a.zero();
+            this.b.zero();
+            this.c.zero();
+			this.stype=ctx.FP.ZERO;
+        },
+
         /* this=conj(this) */
         conj: function() {
             this.a.conj();
diff --git a/version3/js/pair.js b/version3/js/pair.js
index 1c229b1..7b688d5 100644
--- a/version3/js/pair.js
+++ b/version3/js/pair.js
@@ -444,7 +444,11 @@ var PAIR = function(ctx) {
             r.frob(f);
             r.frob(f);
             r.mul(lv);
-
+			if (r.isunity())
+			{
+				r.zero();
+				return r;
+			}
             /* Hard part of final exp */
             if (ctx.ECP.CURVE_PAIRING_TYPE == ctx.ECP.BN) {
                 lv.copy(r);
diff --git a/version3/js/pair192.js b/version3/js/pair192.js
index f915991..1b1e7a4 100644
--- a/version3/js/pair192.js
+++ b/version3/js/pair192.js
@@ -335,7 +335,11 @@ var PAIR192 = function(ctx) {
             lv.copy(r);
             r.frob(f,4);
             r.mul(lv);
-
+			if (r.isunity())
+			{
+				r.zero();
+				return r;
+			}
             /* Hard part of final exp */
             // Ghamman & Fouotsa Method
             t7=new ctx.FP24(r); t7.usqr();
diff --git a/version3/js/pair256.js b/version3/js/pair256.js
index 9891a88..ffbce84 100644
--- a/version3/js/pair256.js
+++ b/version3/js/pair256.js
@@ -335,7 +335,11 @@ var PAIR256 = function(ctx) {
             lv.copy(r);
             r.frob(f,8);
             r.mul(lv);
-
+			if (r.isunity())
+			{
+				r.zero();
+				return r;
+			}
             /* Hard part of final exp */
             // Ghamman & Fouotsa Method
             t7=new ctx.FP48(r); t7.usqr();
diff --git a/version3/python/fp12.py b/version3/python/fp12.py
index dbc5cf3..b42d4a9 100644
--- a/version3/python/fp12.py
+++ b/version3/python/fp12.py
@@ -33,6 +33,10 @@ class Fp12:
     def one():
         return Fp12(Fp4(Fp2(Fp(1))))
 
+    def zero():
+        return Fp12(Fp4(Fp2(Fp(0))))
+
+
     def get(self):
         return(self.a, self.b, self.c)
 
diff --git a/version3/python/pair.py b/version3/python/pair.py
index 6ab1190..5602b99 100644
--- a/version3/python/pair.py
+++ b/version3/python/pair.py
@@ -126,7 +126,7 @@ def another(r,P1,Q1) :
         r[0] *= lv
 
 def e(P, Q):
-    r = miller(P, Q)
+    r = ate(P, Q)
     return fexp(r)
 
 
@@ -250,6 +250,9 @@ def fexp(r):
     r.powq()
     r.powq()
     r *= t0
+    if r.isone() :
+        r.zero()
+        return
 # final exp - hard part
     x = curve.x
 
diff --git a/version3/rust/src/aes.rs b/version3/rust/src/aes.rs
index 23d1c9e..eedea79 100644
--- a/version3/rust/src/aes.rs
+++ b/version3/rust/src/aes.rs
@@ -325,17 +325,37 @@ impl AES {
         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);
-            for i in 1..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/version3/rust/src/ecp8.rs b/version3/rust/src/ecp8.rs
index 9b9afc4..a6d32a4 100644
--- a/version3/rust/src/ecp8.rs
+++ b/version3/rust/src/ecp8.rs
@@ -832,37 +832,89 @@ impl ECP8 {
         T1[7].copy(&W);
         T1[7].add(&mut Q[3]); // Q[0]+Q[1]+Q[2]+Q[3]
 
-        // Use frobenius
-        let f = ECP8::frob_constants();
-        for i in 0..8 {
-            T2[i].copy(&T1[i]);
-            T2[i].frob(&f, 4);
-            T3[i].copy(&T2[i]);
-            T3[i].frob(&f, 4);
-            T4[i].copy(&T3[i]);
-            T4[i].frob(&f, 4);
-        }
+        T2[0].copy(&Q[4]);
+        W.copy(&T2[0]);
+        T2[1].copy(&W);
+        T2[1].add(&mut Q[5]); // Q[0]+Q[1]
+        T2[2].copy(&W);
+        T2[2].add(&mut Q[6]);
+        W.copy(&T2[1]); // Q[0]+Q[2]
+        T2[3].copy(&W);
+        T2[3].add(&mut Q[6]);
+        W.copy(&T2[0]); // Q[0]+Q[1]+Q[2]
+        T2[4].copy(&W);
+        T2[4].add(&mut Q[7]);
+        W.copy(&T2[1]); // Q[0]+Q[3]
+        T2[5].copy(&W);
+        T2[5].add(&mut Q[7]);
+        W.copy(&T2[2]); // Q[0]+Q[1]+Q[3]
+        T2[6].copy(&W);
+        T2[6].add(&mut Q[7]);
+        W.copy(&T2[3]); // Q[0]+Q[2]+Q[3]
+        T2[7].copy(&W);
+        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[1].add(&mut Q[9]); // Q[0]+Q[1]
+        T3[2].copy(&W);
+        T3[2].add(&mut Q[10]);
+        W.copy(&T3[1]); // Q[0]+Q[2]
+        T3[3].copy(&W);
+        T3[3].add(&mut Q[10]);
+        W.copy(&T3[0]); // Q[0]+Q[1]+Q[2]
+        T3[4].copy(&W);
+        T3[4].add(&mut Q[11]);
+        W.copy(&T3[1]); // Q[0]+Q[3]
+        T3[5].copy(&W);
+        T3[5].add(&mut Q[11]);
+        W.copy(&T3[2]); // Q[0]+Q[1]+Q[3]
+        T3[6].copy(&W);
+        T3[6].add(&mut Q[11]);
+        W.copy(&T3[3]); // Q[0]+Q[2]+Q[3]
+        T3[7].copy(&W);
+        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[1].add(&mut Q[13]); // Q[0]+Q[1]
+        T4[2].copy(&W);
+        T4[2].add(&mut Q[14]);
+        W.copy(&T4[1]); // Q[0]+Q[2]
+        T4[3].copy(&W);
+        T4[3].add(&mut Q[14]);
+        W.copy(&T4[0]); // Q[0]+Q[1]+Q[2]
+        T4[4].copy(&W);
+        T4[4].add(&mut Q[15]);
+        W.copy(&T4[1]); // Q[0]+Q[3]
+        T4[5].copy(&W);
+        T4[5].add(&mut Q[15]);
+        W.copy(&T4[2]); // Q[0]+Q[1]+Q[3]
+        T4[6].copy(&W);
+        T4[6].add(&mut Q[15]);
+        W.copy(&T4[3]); // Q[0]+Q[2]+Q[3]
+        T4[7].copy(&W);
+        T4[7].add(&mut Q[15]); // Q[0]+Q[1]+Q[2]+Q[3]
 
         // 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();
 
         let pb3 = 1 - t[8].parity();
         t[8].inc(pb3);
-        t[8].norm();
 
         let pb4 = 1 - t[12].parity();
         t[12].inc(pb4);
-        t[12].norm();
 
         // Number of bits
         mt.zero();
         for i in 0..16 {
+	    t[i].norm();
             mt.or(&t[i]);
         }
 
diff --git a/version3/rust/src/fp12.rs b/version3/rust/src/fp12.rs
index 4e5bfe5..9c06a3e 100644
--- a/version3/rust/src/fp12.rs
+++ b/version3/rust/src/fp12.rs
@@ -207,6 +207,14 @@ impl FP12 {
 	self.stype=ONE;
     }
 
+    /* set self=0 */
+    pub fn zero(&mut self) {
+        self.a.zero();
+        self.b.zero();
+        self.c.zero();
+	self.stype=ZERO;
+    }
+
     /* this=conj(this) */
     pub fn conj(&mut self) {
         self.a.conj();
diff --git a/version3/rust/src/fp24.rs b/version3/rust/src/fp24.rs
index 20149c8..5f154b3 100644
--- a/version3/rust/src/fp24.rs
+++ b/version3/rust/src/fp24.rs
@@ -201,6 +201,14 @@ impl FP24 {
 	self.stype=ONE;
     }
 
+    /* set self=0 */
+    pub fn zero(&mut self) {
+        self.a.zero();
+        self.b.zero();
+        self.c.zero();
+	self.stype=ZERO;
+    }
+
     /* this=conj(this) */
     pub fn conj(&mut self) {
         self.a.conj();
diff --git a/version3/rust/src/fp48.rs b/version3/rust/src/fp48.rs
index bda42e0..c72ee4c 100644
--- a/version3/rust/src/fp48.rs
+++ b/version3/rust/src/fp48.rs
@@ -202,6 +202,14 @@ impl FP48 {
 	self.stype=ONE;
     }
 
+    /* set self=0 */
+    pub fn zero(&mut self) {
+        self.a.zero();
+        self.b.zero();
+        self.c.zero();
+	self.stype=ZERO;
+    }
+
     /* this=conj(this) */
     pub fn conj(&mut self) {
         self.a.conj();
diff --git a/version3/rust/src/pair.rs b/version3/rust/src/pair.rs
index 876c385..0ff266b 100644
--- a/version3/rust/src/pair.rs
+++ b/version3/rust/src/pair.rs
@@ -439,6 +439,11 @@ pub fn fexp(m: &FP12) -> FP12 {
     r.frob(&f);
     r.frob(&f);
     r.mul(&lv);
+    if r.isunity() {
+	r.zero();
+	return r;
+    }
+
     /* Hard part of final exp */
     if ecp::CURVE_PAIRING_TYPE == CurvePairingType::BN {
         lv.copy(&r);
diff --git a/version3/rust/src/pair192.rs b/version3/rust/src/pair192.rs
index 4d2e769..6988f30 100644
--- a/version3/rust/src/pair192.rs
+++ b/version3/rust/src/pair192.rs
@@ -341,7 +341,10 @@ pub fn fexp(m: &FP24) -> FP24 {
     lv.copy(&r);
     r.frob(&f, 4);
     r.mul(&lv);
-
+    if r.isunity() {
+	r.zero();
+	return r;
+    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
diff --git a/version3/rust/src/pair256.rs b/version3/rust/src/pair256.rs
index bdf2e5b..635384a 100644
--- a/version3/rust/src/pair256.rs
+++ b/version3/rust/src/pair256.rs
@@ -339,7 +339,10 @@ pub fn fexp(m: &FP48) -> FP48 {
     lv.copy(&r);
     r.frob(&f, 8);
     r.mul(&lv);
-
+    if r.isunity() {
+	r.zero();
+	return r;
+    }
     /* Hard part of final exp */
     // Ghamman & Fouotsa Method
 
diff --git a/version3/swift/aes.swift b/version3/swift/aes.swift
index e79d479..f696fc5 100644
--- a/version3/swift/aes.swift
+++ b/version3/swift/aes.swift
@@ -27,9 +27,11 @@
 //
 
 public struct AES {
+    var Nk:Int=0
+    var Nr:Int=0
     var mode:Int=0;
-    private var fkey=[UInt32](repeating: 0,count: 44)
-    private var rkey=[UInt32](repeating: 0,count: 44)
+    private var fkey=[UInt32](repeating: 0,count: 60)
+    private var rkey=[UInt32](repeating: 0,count: 60)
     var f=[UInt8](repeating: 0,count: 16)
     
     public init() {}
@@ -49,9 +51,6 @@ public struct AES {
     static public let CTR4:Int=33 
     static public let CTR8:Int=37 
     static public let CTR16:Int=45
-
-    static let KS:Int=16; /* Key Size in bytes */
-    static let BS:Int=16; /* Block Size */
     
     private static let InCo:[UInt8] = [ 0xB,0xD,0x9,0xE]  /* Inverse Coefficients */
     
@@ -313,14 +312,20 @@ public struct AES {
             {for i in 0 ..< 16 {f[i]=iv![i]}} /*??*/
     }
     
-    public mutating func init_it(_ m:Int,_ key:[UInt8],_ iv:[UInt8]?)
+    @discardableResult public mutating func init_it(_ m:Int,_ nkey:Int, _ key:[UInt8],_ iv:[UInt8]?) -> Bool
     {   /* Key=16 bytes */
         /* Key Scheduler. Create expanded encryption key */
-        var CipherKey=[UInt32](repeating: 0,count: 4)
+        var CipherKey=[UInt32](repeating: 0,count: 8)
         var b=[UInt8](repeating: 0,count: 4)
-        let nk=4;
-        reset(m,iv);
-        let N=44;
+        let nk=nkey/4
+        if nk != 4 && nk != 6 && nk != 8 {
+            return false
+        }
+	let nr=6+nk
+	Nk=nk; Nr=nr;
+        
+	reset(m,iv);
+        let N=4*(nr+1)
         
         var j=0
         for  i in 0 ..< nk
@@ -335,12 +340,30 @@ public struct AES {
         while j<N
         {
             fkey[j]=fkey[j-nk]^AES.SubByte(AES.ROTL24(fkey[j-1]))^UInt32(AES.rco[k])
-            var i=1
-            while i<nk && (i+j)<N
-            {
-                fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1]
-                i+=1
-            }
+	    if nk <= 6 {
+                var i=1
+                while i<nk && (i+j)<N
+                {
+                    fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1]
+                    i+=1
+		}
+            } else {
+                var i=1
+                while i<4 && (i+j)<N
+                {
+                    fkey[i+j]=fkey[i+j-nk]^fkey[i+j-1]
+                    i+=1
+		}
+                if (j+4) < N {
+		    fkey[j + 4] = fkey[j + 4 - nk] ^ AES.SubByte(fkey[j + 3])
+		}
+		i=5
+                while i<nk && (i+j)<N 
+		{
+		    fkey[i + j] = fkey[i + j - nk] ^ fkey[i + j - 1]
+		    i+=1
+		}
+	    }
             j+=nk
             k+=1
         }
@@ -356,6 +379,7 @@ public struct AES {
             i+=4
         }
         for j in N-4 ..< N {rkey[j-N+4]=fkey[j]}
+	return true
     }
     
     func getreg() -> [UInt8]
@@ -384,7 +408,7 @@ public struct AES {
         var k=4;
     
     /* State alternates between p and q */
-        for _ in 1 ..< 10
+        for _ in 1 ..< Nr
         {
             q[0]=fkey[k]^AES.ftable[Int(p[0]&0xff)]^AES.ROTL8(AES.ftable[Int((p[1]>>8)&0xff)])^AES.ROTL16(AES.ftable[Int((p[2]>>16)&0xff)])^AES.ROTL24(AES.ftable[Int((p[3]>>24)&0xff)])
             
@@ -439,7 +463,7 @@ public struct AES {
         var k=4
     
     /* State alternates between p and q */
-        for _ in 1 ..< 10
+        for _ in 1 ..< Nr
         {
             
             q[0]=rkey[k]^AES.rtable[Int(p[0]&0xff)]^AES.ROTL8(AES.rtable[Int((p[3]>>8)&0xff)])^AES.ROTL16(AES.rtable[Int((p[2]>>16)&0xff)])^AES.ROTL24(AES.rtable[Int((p[1]>>24)&0xff)])
@@ -632,7 +656,7 @@ public struct AES {
     /* Clean up and delete left-overs */
     public mutating func end()
     { // clean up
-        for i in 0 ..< 44
+        for i in 0 ..< 4*(Nr+1)
             {fkey[i]=0; rkey[i]=0}
         for i in 0 ..< 16
             {f[i]=0}
diff --git a/version3/swift/ecdh.swift b/version3/swift/ecdh.swift
index 5042a29..575fe18 100644
--- a/version3/swift/ecdh.swift
+++ b/version3/swift/ecdh.swift
@@ -215,7 +215,7 @@ public struct ECDH
     
         var C=[UInt8](repeating: 0,count: clen)
     
-        a.init_it(AES.CBC,K,nil)
+        a.init_it(AES.CBC,K.count,K,nil)
     
         var ipt=0; var opt=0;
         var fin=false;
@@ -258,7 +258,7 @@ public struct ECDH
     
         var ipt=0; var opt=0;
     
-        a.init_it(AES.CBC,K,nil);
+        a.init_it(AES.CBC,K.count,K,nil);
     
         if C.count==0 {return [UInt8]()}
         var ch=C[ipt]; ipt+=1
diff --git a/version3/swift/ecp.swift b/version3/swift/ecp.swift
index 03845a1..a0be99d 100644
--- a/version3/swift/ecp.swift
+++ b/version3/swift/ecp.swift
@@ -33,12 +33,12 @@ public struct ECP {
    /* Constructor - set to O */
     init()
     {
-        x=FP(0)
+        x=FP()
         y=FP(1)
         if CONFIG_CURVE.CURVETYPE==CONFIG_CURVE.EDWARDS {
 	       z=FP(1)
 	   } else {
-	       z=FP(0)
+	       z=FP()
 	   }
     }
     
@@ -130,8 +130,8 @@ public struct ECP {
     /* Test P == Q */
     func equals(_ Q: ECP) -> Bool
     {
-        var a=FP(0)
-        var b=FP(0)
+        var a=FP()
+        var b=FP()
         a.copy(x); a.mul(Q.z)
         b.copy(Q.x); b.mul(z)
         if !a.equals(b) {return false}
@@ -192,7 +192,7 @@ public struct ECP {
         }
         if CONFIG_CURVE.CURVETYPE == CONFIG_CURVE.MONTGOMERY
         { // x^3+Ax^2+x
-            var x3=FP(0)
+            var x3=FP()
             x3.copy(r);
             x3.mul(x);
             r.imul(ROM.CURVE_A);
@@ -231,7 +231,7 @@ public struct ECP {
         x=FP(ix)
         x.norm()
         var rhs=ECP.RHS(x)
-        y=FP(0)
+        y=FP()
         z=FP(1)
 
         if rhs.jacobi()==1
@@ -249,7 +249,7 @@ public struct ECP {
         x=FP(ix)
         x.norm()
         var rhs=ECP.RHS(x)
-        y=FP(0)
+        y=FP()
         z=FP(1)
         if rhs.jacobi()==1
         {
@@ -416,9 +416,9 @@ public struct ECP {
                 var t2=FP(z)
                 var t3=FP(x)
                 var z3=FP(z)
-                var y3=FP(0)
-                var x3=FP(0)
-                var b=FP(0)
+                var y3=FP()
+                var x3=FP()
+                var b=FP()
 
                 if ROM.CURVE_B_I==0
                 {
@@ -489,7 +489,7 @@ public struct ECP {
             var C=FP(x)
             var D=FP(y)
             var H=FP(z)
-            var J=FP(0)
+            var J=FP()
     
             x.mul(y); x.add(x); x.norm()
             C.sqr()
@@ -509,9 +509,9 @@ public struct ECP {
         {
             var A=FP(x)
             var B=FP(x);
-            var AA=FP(0);
-            var BB=FP(0);
-            var C=FP(0);
+            var AA=FP();
+            var BB=FP();
+            var C=FP();
         
             A.add(z); A.norm()
             AA.copy(A); AA.sqr()
@@ -593,10 +593,10 @@ public struct ECP {
                     var t2=FP(z)
                     var t3=FP(x)
                     var t4=FP(Q.x)
-                    var z3=FP(0)
+                    var z3=FP()
                     var y3=FP(Q.x)
                     var x3=FP(Q.y)
-                    var b=FP(0)
+                    var b=FP()
 
                     if ROM.CURVE_B_I==0
                     {
@@ -681,12 +681,12 @@ public struct ECP {
         {
             let b=FP(BIG(ROM.CURVE_B))
             var A=FP(z)
-            var B=FP(0)
+            var B=FP()
             var C=FP(x)
             var D=FP(y)
-            var E=FP(0)
-            var F=FP(0)
-            var G=FP(0)
+            var E=FP()
+            var F=FP()
+            var G=FP()
     
             A.mul(Q.z)
             B.copy(A); B.sqr()
@@ -733,8 +733,8 @@ public struct ECP {
         var B=FP(x)
         var C=FP(Q.x)
         var D=FP(Q.x)
-        var DA=FP(0)
-        var CB=FP(0)
+        var DA=FP()
+        var CB=FP()
     
         A.add(z)
         B.sub(z)
diff --git a/version3/swift/ecp2.swift b/version3/swift/ecp2.swift
index 833f953..fc13bd9 100644
--- a/version3/swift/ecp2.swift
+++ b/version3/swift/ecp2.swift
@@ -33,9 +33,9 @@ public struct ECP2 {
     /* Constructor - set self=O */
     init()
     {
-        x=FP2(0)
+        x=FP2()
         y=FP2(1)
-        z=FP2(0)
+        z=FP2()
     }
     /* Test self=O? */
     public func is_infinity() -> Bool
diff --git a/version3/swift/ecp4.swift b/version3/swift/ecp4.swift
index e7f8f79..54b96e0 100644
--- a/version3/swift/ecp4.swift
+++ b/version3/swift/ecp4.swift
@@ -33,9 +33,9 @@ public struct ECP4 {
     /* Constructor - set self=O */
     init()
     {
-        x=FP4(0)
+        x=FP4()
         y=FP4(1)
-        z=FP4(0)
+        z=FP4()
     }
     /* Test self=O? */
     public func is_infinity() -> Bool
diff --git a/version3/swift/ecp8.swift b/version3/swift/ecp8.swift
index 3218f9b..91a2bf2 100644
--- a/version3/swift/ecp8.swift
+++ b/version3/swift/ecp8.swift
@@ -33,9 +33,9 @@ public struct ECP8 {
     /* Constructor - set self=O */
     init()
     {
-        x=FP8(0)
+        x=FP8()
         y=FP8(1)
-        z=FP8(0)
+        z=FP8()
     }
     /* Test self=O? */
     public func is_infinity() -> Bool
diff --git a/version3/swift/fp.swift b/version3/swift/fp.swift
index 7853018..e037768 100644
--- a/version3/swift/fp.swift
+++ b/version3/swift/fp.swift
@@ -419,7 +419,7 @@ public struct FP {
         var bw=0; var w=1; while w<c {w*=2; bw+=1}
         var k=w-c
 
-        var i=10; var key=FP(0)
+        var i=10; var key=FP()
 
         if k != 0 {
             while ac[i]>k {i-=1}
@@ -440,7 +440,7 @@ public struct FP {
 
         var j=3; var m=8
         let nw=n-bw
-        var t=FP(0)
+        var t=FP()
 
         while 2*m<nw {
             t.copy(xp[j]); j+=1
diff --git a/version3/swift/fp12.swift b/version3/swift/fp12.swift
index 88a24ed..2c5137c 100644
--- a/version3/swift/fp12.swift
+++ b/version3/swift/fp12.swift
@@ -69,16 +69,24 @@ public struct FP12
     init(_ d:FP4)
     {
         a=FP4(d)
-        b=FP4(0)
-        c=FP4(0)
+        b=FP4()
+        c=FP4()
         stype=FP12.SPARSER
     }
     
+    init()
+    {
+        a=FP4()
+        b=FP4()
+        c=FP4()
+        stype=FP12.ZERO
+    }
+
     init(_ d:Int)
     {
         a=FP4(d)
-        b=FP4(0)
-        c=FP4(0)
+        b=FP4()
+        c=FP4()
         if (d==1) {stype=FP12.ONE}
         else {stype=FP12.SPARSER}
     }
@@ -185,6 +193,16 @@ public struct FP12
         c.zero()
         stype=FP12.ONE
     }
+
+    /* set self=0 */
+    mutating func zero()
+    {
+        a.zero()
+        b.zero()
+        c.zero()
+        stype=FP12.ZERO
+    }
+
     /* self=conj(self) */
     mutating func conj()
     {
@@ -198,7 +216,7 @@ public struct FP12
         var A=FP4(a)
         var B=FP4(c)
         var C=FP4(b)
-        var D=FP4(0)
+        var D=FP4()
     
         a.sqr()
         D.copy(a); D.add(a)
@@ -280,9 +298,9 @@ public struct FP12
     mutating func mul(_ y:FP12)
     {
         var z0=FP4(a)
-        var z1=FP4(0)
+        var z1=FP4()
         var z2=FP4(b)
-        var z3=FP4(0)
+        var z3=FP4()
         var t0=FP4(a)
         var t1=FP4(y.a)
     
@@ -349,15 +367,15 @@ public struct FP12
         }
         if y.stype>=FP12.SPARSE {
             var z0=FP4(a)
-            var z1=FP4(0)
-            var z2=FP4(0)
-            var z3=FP4(0)
+            var z1=FP4()
+            var z2=FP4()
+            var z3=FP4()
             z0.mul(y.a)
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {  
                 if y.stype==FP12.SPARSE || stype==FP12.SPARSE {
-                    var ga=FP2(0)
-                    var gb=FP2(0)
+                    var ga=FP2()
+                    var gb=FP2()
 
                     gb.copy(b.getb())
                     gb.mul(y.b.getb())
@@ -408,8 +426,8 @@ public struct FP12
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {  
                 if y.stype==FP12.SPARSE || stype==FP12.SPARSE {
-                    var ga=FP2(0)
-                    var gb=FP2(0)
+                    var ga=FP2()
+                    var gb=FP2()
 
                     ga.copy(c.geta())
                     ga.mul(y.c.geta())
@@ -449,7 +467,7 @@ public struct FP12
                 var z0=FP4(a)
                 var z2=FP4(b)
                 var z3=FP4(b)
-                var t0=FP4(0)
+                var t0=FP4()
                 var t1=FP4(y.a)
                 z0.mul(y.a)
                 z2.pmul(y.b.real())
@@ -482,11 +500,11 @@ public struct FP12
             }
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {
                 var z0=FP4(a)
-                var z1=FP4(0)
-                var z2=FP4(0)
-                var z3=FP4(0)
+                var z1=FP4()
+                var z2=FP4()
+                var z3=FP4()
                 var t0=FP4(a)
-                var t1=FP4(0)
+                var t1=FP4()
         
                 z0.mul(y.a)
                 t0.add(b); t0.norm()
@@ -640,7 +658,7 @@ public struct FP12
         var f0=FP4(a)
         var f1=FP4(b)
         var f2=FP4(a)
-        var f3=FP4(0)
+        var f3=FP4()
     
         norm()
         f0.sqr()
@@ -693,7 +711,7 @@ public struct FP12
     /* trace function */
     func trace() -> FP4
     {
-        var t=FP4(0)
+        var t=FP4()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -885,10 +903,10 @@ public struct FP12
     {
         var g=[FP12]();
         
-        for _ in 0 ..< 8 {g.append(FP12(0))}
+        for _ in 0 ..< 8 {g.append(FP12())}
         
-        var r=FP12(0)
-        var p=FP12(0)
+        var r=FP12()
+        var p=FP12()
         
         var t=[BIG]()
         for i in 0 ..< 4 {
diff --git a/version3/swift/fp16.swift b/version3/swift/fp16.swift
index 196f7c5..bb2130e 100644
--- a/version3/swift/fp16.swift
+++ b/version3/swift/fp16.swift
@@ -33,10 +33,16 @@ public struct FP16 {
     private var b:FP8
 
     /* constructors */
+    init()
+    {
+        a=FP8()
+        b=FP8()
+    }
+
     init(_ c:Int)
     {
         a=FP8(c)
-        b=FP8(0)
+        b=FP8()
     }
     
     init(_ x:FP16)
@@ -54,7 +60,7 @@ public struct FP16 {
     init(_ c:FP8)
     {
         a=FP8(c)
-        b=FP8(0)
+        b=FP8()
     }
     /* reduce all components of this mod Modulus */
     mutating func reduce()
@@ -152,7 +158,7 @@ public struct FP16 {
     {
         norm()
         var m=FP8(a)
-        var t=FP8(0)
+        var t=FP8()
         m.add(b)
         m.neg()
         t.copy(m); t.add(b)
@@ -253,7 +259,7 @@ public struct FP16 {
     {
         var t1=FP8(a)
         var t2=FP8(b)
-        var t3=FP8(0)
+        var t3=FP8()
         var t4=FP8(b)
     
         t1.mul(y.a)
@@ -395,8 +401,8 @@ public struct FP16 {
         var b=FP16(sf)
         var c=FP16(b)
         c.xtr_D()
-        var t=FP16(0)
-        var r=FP16(0)
+        var t=FP16()
+        var r=FP16()
     
         let par=n.parity()
         var v=BIG(n); v.norm(); v.fshr(1)
@@ -446,8 +452,8 @@ public struct FP16 {
         var cv=FP16(self)
         var cumv=FP16(ckml)
         var cum2v=FP16(ckm2l)
-        var r=FP16(0)
-        var t=FP16(0)
+        var r=FP16()
+        var t=FP16()
     
         var f2:Int=0
         while d.parity()==0 && e.parity()==0
diff --git a/version3/swift/fp2.swift b/version3/swift/fp2.swift
index 4463e72..091824e 100644
--- a/version3/swift/fp2.swift
+++ b/version3/swift/fp2.swift
@@ -35,10 +35,16 @@ public struct FP2
     private var b:FP
 
     /* Constructors */
+    init()
+    {
+        a=FP()
+        b=FP()
+    }
+
     init(_ c: Int)
     {
         a=FP(c)
-        b=FP(0)
+        b=FP()
     }
     
     init(_ x:FP2)
@@ -62,13 +68,13 @@ public struct FP2
     init(_ c:FP)
     {
         a=FP(c)
-        b=FP(0)
+        b=FP()
     }
     
     init(_ c:BIG)
     {
         a=FP(c)
-        b=FP(0)
+        b=FP()
     }
 
     /* test this=0 ? */
@@ -148,7 +154,7 @@ public struct FP2
     mutating func neg()
     {
         var m=FP(a)
-        var t=FP(0)
+        var t=FP()
     
         m.add(b)
         m.neg()
@@ -334,7 +340,7 @@ public struct FP2
     /* w/=(1+sqrt(-1)) */
     mutating func div_ip()
     {
-        var t=FP2(0)
+        var t=FP2()
         norm()
         t.a.copy(a); t.a.add(b)
         t.b.copy(b); t.b.sub(a)
@@ -344,7 +350,7 @@ public struct FP2
     
     mutating func div_ip2()
     {
-        var t=FP2(0)
+        var t=FP2()
         norm()
         t.a.copy(a); t.a.add(b)
         t.b.copy(b); t.b.sub(a)
diff --git a/version3/swift/fp24.swift b/version3/swift/fp24.swift
index f780cf2..fe5c57d 100644
--- a/version3/swift/fp24.swift
+++ b/version3/swift/fp24.swift
@@ -69,16 +69,24 @@ public struct FP24
     init(_ d:FP8)
     {
         a=FP8(d)
-        b=FP8(0)
-        c=FP8(0)
+        b=FP8()
+        c=FP8()
         stype=FP24.SPARSER        
     }
     
+    init()
+    {
+        a=FP8()
+        b=FP8()
+        c=FP8()
+        stype=FP24.ZERO      
+    }
+
     init(_ d:Int)
     {
         a=FP8(d)
-        b=FP8(0)
-        c=FP8(0)
+        b=FP8()
+        c=FP8()
         if (d==1) {stype=FP24.ONE}
         else {stype=FP24.SPARSER}        
     }
@@ -185,6 +193,16 @@ public struct FP24
         c.zero()
        stype=FP24.ONE        
     }
+
+    /* set self=0 */
+    mutating func zero()
+    {
+        a.zero()
+        b.zero()
+        c.zero()
+        stype=FP24.ZERO
+    }
+
     /* self=conj(self) */
     mutating func conj()
     {
@@ -199,7 +217,7 @@ public struct FP24
         var A=FP8(a)
         var B=FP8(c)
         var C=FP8(b)
-        var D=FP8(0)
+        var D=FP8()
     
         a.sqr()
         D.copy(a); D.add(a)
@@ -282,9 +300,9 @@ public struct FP24
     mutating func mul(_ y:FP24)
     {
         var z0=FP8(a)
-        var z1=FP8(0)
+        var z1=FP8()
         var z2=FP8(b)
-        var z3=FP8(0)
+        var z3=FP8()
         var t0=FP8(a)
         var t1=FP8(y.a)
     
@@ -351,15 +369,15 @@ public struct FP24
         }
         if y.stype>=FP24.SPARSE {
             var z0=FP8(a)
-            var z1=FP8(0)
-            var z2=FP8(0)
-            var z3=FP8(0)
+            var z1=FP8()
+            var z2=FP8()
+            var z3=FP8()
             z0.mul(y.a)
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {  
                 if y.stype==FP24.SPARSE || stype==FP24.SPARSE {
-                    var ga=FP4(0)
-                    var gb=FP4(0)
+                    var ga=FP4()
+                    var gb=FP4()
 
                     gb.copy(b.getb())
                     gb.mul(y.b.getb())
@@ -410,8 +428,8 @@ public struct FP24
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {  
                 if y.stype==FP24.SPARSE || stype==FP24.SPARSE {
-                    var ga=FP4(0)
-                    var gb=FP4(0)
+                    var ga=FP4()
+                    var gb=FP4()
 
                     ga.copy(c.geta())
                     ga.mul(y.c.geta())
@@ -451,7 +469,7 @@ public struct FP24
                 var z0=FP8(a)
                 var z2=FP8(b)
                 var z3=FP8(b)
-                var t0=FP8(0)
+                var t0=FP8()
                 var t1=FP8(y.a)
                 z0.mul(y.a)
                 z2.pmul(y.b.real())
@@ -484,11 +502,11 @@ public struct FP24
             }
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {
                 var z0=FP8(a)
-                var z1=FP8(0)
-                var z2=FP8(0)
-                var z3=FP8(0)
+                var z1=FP8()
+                var z2=FP8()
+                var z3=FP8()
                 var t0=FP8(a)
-                var t1=FP8(0)
+                var t1=FP8()
         
                 z0.mul(y.a)
                 t0.add(b); t0.norm()
@@ -643,7 +661,7 @@ public struct FP24
         var f0=FP8(a)
         var f1=FP8(b)
         var f2=FP8(a)
-        var f3=FP8(0)
+        var f3=FP8()
     
         //norm()
         f0.sqr()
@@ -700,7 +718,7 @@ public struct FP24
     /* trace function */
     func trace() -> FP8
     {
-        var t=FP8(0)
+        var t=FP8()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -978,12 +996,12 @@ public struct FP24
         var g2=[FP24]()        
         
         for _ in 0 ..< 8 {
-            g1.append(FP24(0))
-            g2.append(FP24(0))            
+            g1.append(FP24())
+            g2.append(FP24())            
         }
         
-        var r=FP24(0)
-        var p=FP24(0)
+        var r=FP24()
+        var p=FP24()
         
         var t=[BIG]()
         for i in 0 ..< 8 {
diff --git a/version3/swift/fp4.swift b/version3/swift/fp4.swift
index 90132a6..6bc552f 100644
--- a/version3/swift/fp4.swift
+++ b/version3/swift/fp4.swift
@@ -33,10 +33,16 @@ public struct FP4 {
     private var b:FP2
 
     /* constructors */
+    init()
+    {
+        a=FP2()
+        b=FP2()
+    }
+
     init(_ c:Int)
     {
         a=FP2(c)
-        b=FP2(0)
+        b=FP2()
     }
     
     init(_ x:FP4)
@@ -54,7 +60,7 @@ public struct FP4 {
     init(_ c:FP2)
     {
         a=FP2(c)
-        b=FP2(0)
+        b=FP2()
     }
     /* reduce all components of this mod Modulus */
     mutating func reduce()
@@ -150,7 +156,7 @@ public struct FP4 {
     {
         norm()
         var m=FP2(a)
-        var t=FP2(0)
+        var t=FP2()
         m.add(b)
         m.neg()
         t.copy(m); t.add(b)
@@ -249,7 +255,7 @@ public struct FP4 {
     {
         var t1=FP2(a)
         var t2=FP2(b)
-        var t3=FP2(0)
+        var t3=FP2()
         var t4=FP2(b)
     
         t1.mul(y.a)
@@ -377,8 +383,8 @@ public struct FP4 {
         var b=FP4(self)
         var c=FP4(b)
         c.xtr_D()
-        var t=FP4(0)
-        var r=FP4(0)
+        var t=FP4()
+        var r=FP4()
         var sf=FP4(self)
     
         let par=n.parity()
@@ -429,8 +435,8 @@ public struct FP4 {
         var cv=FP4(self)
         var cumv=FP4(ckml)
         var cum2v=FP4(ckm2l)
-        var r=FP4(0)
-        var t=FP4(0)
+        var r=FP4()
+        var t=FP4()
     
         var f2:Int=0
         while d.parity()==0 && e.parity()==0
diff --git a/version3/swift/fp48.swift b/version3/swift/fp48.swift
index 4ac17de..2d6fef4 100644
--- a/version3/swift/fp48.swift
+++ b/version3/swift/fp48.swift
@@ -69,16 +69,24 @@ public struct FP48
     init(_ d:FP16)
     {
         a=FP16(d)
-        b=FP16(0)
-        c=FP16(0)
+        b=FP16()
+        c=FP16()
         stype=FP48.SPARSER        
     }
     
+    init()
+    {
+        a=FP16()
+        b=FP16()
+        c=FP16()
+        stype=FP48.ZERO      
+    }
+
     init(_ d:Int)
     {
         a=FP16(d)
-        b=FP16(0)
-        c=FP16(0)
+        b=FP16()
+        c=FP16()
         if (d==1) {stype=FP48.ONE}
         else {stype=FP48.SPARSER}        
     }
@@ -186,6 +194,16 @@ public struct FP48
         c.zero()
         stype=FP48.ONE        
     }
+
+    /* set self=0 */
+    mutating func zero()
+    {
+        a.zero()
+        b.zero()
+        c.zero()
+        stype=FP48.ZERO
+    }
+
     /* self=conj(self) */
     mutating func conj()
     {
@@ -200,7 +218,7 @@ public struct FP48
         var A=FP16(a)
         var B=FP16(c)
         var C=FP16(b)
-        var D=FP16(0)
+        var D=FP16()
     
         a.sqr()
         D.copy(a); D.add(a)
@@ -282,9 +300,9 @@ public struct FP48
     mutating func mul(_ y:FP48)
     {
         var z0=FP16(a)
-        var z1=FP16(0)
+        var z1=FP16()
         var z2=FP16(b)
-        var z3=FP16(0)
+        var z3=FP16()
         var t0=FP16(a)
         var t1=FP16(y.a)
     
@@ -351,15 +369,15 @@ public struct FP48
         }
         if y.stype>=FP48.SPARSE {
             var z0=FP16(a)
-            var z1=FP16(0)
-            var z2=FP16(0)
-            var z3=FP16(0)
+            var z1=FP16()
+            var z2=FP16()
+            var z3=FP16()
             z0.mul(y.a)
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {  
                 if y.stype==FP48.SPARSE || stype==FP48.SPARSE {
-                    var ga=FP8(0)
-                    var gb=FP8(0)
+                    var ga=FP8()
+                    var gb=FP8()
 
                     gb.copy(b.getb())
                     gb.mul(y.b.getb())
@@ -410,8 +428,8 @@ public struct FP48
 
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {  
                 if y.stype==FP48.SPARSE || stype==FP48.SPARSE {
-                    var ga=FP8(0)
-                    var gb=FP8(0)
+                    var ga=FP8()
+                    var gb=FP8()
 
                     ga.copy(c.geta())
                     ga.mul(y.c.geta())
@@ -451,7 +469,7 @@ public struct FP48
                 var z0=FP16(a)
                 var z2=FP16(b)
                 var z3=FP16(b)
-                var t0=FP16(0)
+                var t0=FP16()
                 var t1=FP16(y.a)
                 z0.mul(y.a)
                 z2.pmul(y.b.real())
@@ -484,11 +502,11 @@ public struct FP48
             }
             if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.M_TYPE {
                 var z0=FP16(a)
-                var z1=FP16(0)
-                var z2=FP16(0)
-                var z3=FP16(0)
+                var z1=FP16()
+                var z2=FP16()
+                var z3=FP16()
                 var t0=FP16(a)
-                var t1=FP16(0)
+                var t1=FP16()
         
                 z0.mul(y.a)
                 t0.add(b); t0.norm()
@@ -644,7 +662,7 @@ public struct FP48
         var f0=FP16(a)
         var f1=FP16(b)
         var f2=FP16(a)
-        var f3=FP16(0)
+        var f3=FP16()
     
         //norm()
         f0.sqr()
@@ -703,7 +721,7 @@ public struct FP48
     /* trace function */
     func trace() -> FP16
     {
-        var t=FP16(0)
+        var t=FP16()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -1137,14 +1155,14 @@ public struct FP48
 
         
         for _ in 0 ..< 8 {
-            g1.append(FP48(0))
-            g2.append(FP48(0))       
-            g3.append(FP48(0))
-            g4.append(FP48(0))                    
+            g1.append(FP48())
+            g2.append(FP48())       
+            g3.append(FP48())
+            g4.append(FP48())                    
         }
         
-        var r=FP48(0)
-        var p=FP48(0)
+        var r=FP48()
+        var p=FP48()
         
         var t=[BIG]()
         for i in 0 ..< 16 {
diff --git a/version3/swift/fp8.swift b/version3/swift/fp8.swift
index 7f64073..fd89dc1 100644
--- a/version3/swift/fp8.swift
+++ b/version3/swift/fp8.swift
@@ -33,10 +33,16 @@ public struct FP8 {
     private var b:FP4
 
     /* constructors */
+    init()
+    {
+        a=FP4()
+        b=FP4()
+    }
+
     init(_ c:Int)
     {
         a=FP4(c)
-        b=FP4(0)
+        b=FP4()
     }
     
     init(_ x:FP8)
@@ -54,7 +60,7 @@ public struct FP8 {
     init(_ c:FP4)
     {
         a=FP4(c)
-        b=FP4(0)
+        b=FP4()
     }
     /* reduce all components of this mod Modulus */
     mutating func reduce()
@@ -152,7 +158,7 @@ public struct FP8 {
     {
         norm()
         var m=FP4(a)
-        var t=FP4(0)
+        var t=FP4()
         m.add(b)
         m.neg()
         t.copy(m); t.add(b)
@@ -258,7 +264,7 @@ public struct FP8 {
     {
         var t1=FP4(a)
         var t2=FP4(b)
-        var t3=FP4(0)
+        var t3=FP4()
         var t4=FP4(b)
     
         t1.mul(y.a)
@@ -396,8 +402,8 @@ public struct FP8 {
         var b=FP8(self)
         var c=FP8(b)
         c.xtr_D()
-        var t=FP8(0)
-        var r=FP8(0)
+        var t=FP8()
+        var r=FP8()
         var sf=FP8(self)
     
         let par=n.parity()
@@ -450,8 +456,8 @@ public struct FP8 {
         var cv=FP8(self)
         var cumv=FP8(ckml)
         var cum2v=FP8(ckm2l)
-        var r=FP8(0)
-        var t=FP8(0)
+        var r=FP8()
+        var t=FP8()
     
         var f2:Int=0
         while d.parity()==0 && e.parity()==0
diff --git a/version3/swift/gcm.swift b/version3/swift/gcm.swift
index e29001d..cedf984 100644
--- a/version3/swift/gcm.swift
+++ b/version3/swift/gcm.swift
@@ -165,13 +165,13 @@ struct GCM {
     }
     
     /* Initialize GCM mode */
-    mutating func init_it(_ key: [UInt8],_ niv: Int,_ iv: [UInt8])
+    mutating func init_it(_ nk: Int,_ key: [UInt8],_ niv: Int,_ iv: [UInt8])
     { /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */
         var H=[UInt8](repeating: 0,count: 16)
         
         for i in 0 ..< 16 {H[i]=0; stateX[i]=0}
         
-        a.init_it(AES.ECB,key,iv)
+        a.init_it(AES.ECB,nk,key,iv)
         a.ecb_encrypt(&H);    /* E(K,0) */
         precompute(H)
         
diff --git a/version3/swift/pair.swift b/version3/swift/pair.swift
index 06044e7..5cad02b 100644
--- a/version3/swift/pair.swift
+++ b/version3/swift/pair.swift
@@ -71,9 +71,9 @@ public struct PAIR {
         a=FP4(YZ,ZZ)          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {             
             b=FP4(XX)            // L(0,1) | L(0,0) | L(1,0)
-            c=FP4(0)
+            c=FP4()
         } else { 
-            b=FP4(0)
+            b=FP4()
             c=FP4(XX); c.times_i()
         }        
         A.dbl()
@@ -118,9 +118,9 @@ public struct PAIR {
         a=FP4(X1,T2)       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {              
             b=FP4(Y1)
-            c=FP4(0)
+            c=FP4()
         } else {
-            b=FP4(0)
+            b=FP4()
             c=FP4(Y1); c.times_i()
          }  
         A.add(B)
@@ -423,7 +423,10 @@ public struct PAIR {
         r.frob(f)
         r.frob(f)
         r.mul(lv)
-        
+        if r.isunity() {
+		r.zero()
+		return r
+	}        
     // Hard part of final exp
 	if CONFIG_CURVE.CURVE_PAIRING_TYPE == CONFIG_CURVE.BN {
 		lv.copy(r)
@@ -737,11 +740,11 @@ public struct PAIR {
             var t=BIG(0)
         
             var u=gs(e)
-            g.append(FP12(0))
+            g.append(FP12())
             g[0].copy(d);
             for i in 1 ..< 4
             {
-                g.append(FP12(0)); g[i].copy(g[i-1])
+                g.append(FP12()); g[i].copy(g[i-1])
 				g[i].frob(f)
             }
             for i in 0 ..< 4
diff --git a/version3/swift/pair192.swift b/version3/swift/pair192.swift
index d066198..3ab7872 100644
--- a/version3/swift/pair192.swift
+++ b/version3/swift/pair192.swift
@@ -69,9 +69,9 @@ public struct PAIR192 {
         a=FP8(YZ,ZZ)          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {             
             b=FP8(XX)            // L(0,1) | L(0,0) | L(1,0)
-            c=FP8(0)
+            c=FP8()
         } else { 
-            b=FP8(0)
+            b=FP8()
             c=FP8(XX); c.times_i()
         }        
         A.dbl()
@@ -113,9 +113,9 @@ public struct PAIR192 {
         a=FP8(X1,T2)       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {              
             b=FP8(Y1)
-            c=FP8(0)
+            c=FP8()
         } else {
-            b=FP8(0)
+            b=FP8()
             c=FP8(Y1); c.times_i()
         }  
         A.add(B)
@@ -324,7 +324,10 @@ public struct PAIR192 {
         lv.copy(r)
         r.frob(f,4)
         r.mul(lv)
-        
+        if r.isunity() {
+		r.zero()
+		return r
+	}        
     // Hard part of final exp
 
         var t7=FP24(r); t7.usqr()
@@ -538,11 +541,11 @@ public struct PAIR192 {
             var t=BIG(0)
         
             var u=gs(e)
-            g.append(FP24(0))
+            g.append(FP24())
             g[0].copy(d);
             for i in 1 ..< 8
             {
-                g.append(FP24(0)); g[i].copy(g[i-1])
+                g.append(FP24()); g[i].copy(g[i-1])
                 g[i].frob(f,1)
             }
             for i in 0 ..< 8
diff --git a/version3/swift/pair256.swift b/version3/swift/pair256.swift
index 1289e94..22376fc 100644
--- a/version3/swift/pair256.swift
+++ b/version3/swift/pair256.swift
@@ -69,9 +69,9 @@ public struct PAIR256 {
         a=FP16(YZ,ZZ)          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {             
             b=FP16(XX)            // L(0,1) | L(0,0) | L(1,0)
-            c=FP16(0)
+            c=FP16()
         } else { 
-            b=FP16(0)
+            b=FP16()
             c=FP16(XX); c.times_i()
         }        
         A.dbl()
@@ -113,9 +113,9 @@ public struct PAIR256 {
         a=FP16(X1,T2)       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
         if CONFIG_CURVE.SEXTIC_TWIST == CONFIG_CURVE.D_TYPE {              
             b=FP16(Y1)
-            c=FP16(0)
+            c=FP16()
         } else {
-            b=FP16(0)
+            b=FP16()
             c=FP16(Y1); c.times_i()
         }  
         A.add(B)
@@ -321,7 +321,10 @@ public struct PAIR256 {
         lv.copy(r)
         r.frob(f,8)
         r.mul(lv)
-        
+        if r.isunity() {
+		r.zero()
+		return r
+	}        
     // Hard part of final exp
 
         var t7=FP48(r); t7.usqr()
@@ -611,11 +614,11 @@ public struct PAIR256 {
             var t=BIG(0)
         
             var u=gs(e)
-            g.append(FP48(0))
+            g.append(FP48())
             g[0].copy(d);
             for i in 1 ..< 16
             {
-                g.append(FP48(0)); g[i].copy(g[i-1])
+                g.append(FP48()); g[i].copy(g[i-1])
                 g[i].frob(f,1)
             }
             for i in 0 ..< 16
diff --git a/version3/swift/readme.txt b/version3/swift/readme.txt
index f7765cd..7cc82da 100644
--- a/version3/swift/readme.txt
+++ b/version3/swift/readme.txt
@@ -48,3 +48,19 @@ swift -I. -L. -lamcl -led25519 -lnist256 -lgoldilocks -lbn254 -lbls383 -lbls24 -
 Also
 
 swift -I. -L. -lamcl TestNHS.swift
+
+(Alternatively compile using swiftc rather than swift. However to run the 
+programs the individual libraries need to be moved to /usr/lib (or somewhere 
+OS specific). Note that the regular swiftc compiler seems to be more robust 
+than the JIT swift compiler (there is a known bug in swift 5.0)
+
+So for example
+
+swiftc -I. -L. -lamcl -lbn254 -lbls383 -lbls24 -lbls48 TestBLS.swift 
+
+// sudo cp lib*.so /usr/lib/.
+
+./TestBLS
+
+)
+
diff --git a/version3/wasm/config.py b/version3/wasm/config.py
index 13c5caa..c63668c 100644
--- a/version3/wasm/config.py
+++ b/version3/wasm/config.py
@@ -75,7 +75,7 @@ def rsaset(tb,tff,nb,base,ml) :
 	replace(fnameh,"XXX",bd)
 	os.system("emcc -O2 "+fnamec+" -o "+fnamebc)
 
-def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
+def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,ab,cs) :
 	bd=tb+"_"+base
 
 	fnameh="config_big_"+bd+".h"
@@ -115,6 +115,7 @@ def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
 	replace(fnameh,"@ST@",stw)
 	replace(fnameh,"@SX@",sx)
 	replace(fnameh,"@CS@",cs)
+	replace(fnameh,"@AB@",ab)
 
 	fnamec="big_"+bd+".c"
 	fnamebc="big_"+bd+".bc"
@@ -211,8 +212,10 @@ def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
 			os.system(copytext+" fp12.h "+fnameh)
 			replace(fnamec,"YYY",tf)
 			replace(fnamec,"XXX",bd)
+			replace(fnamec,"ZZZ",tc)
 			replace(fnameh,"YYY",tf)
 			replace(fnameh,"XXX",bd)
+			replace(fnameh,"ZZZ",tc)
 			os.system("emcc -O2 "+fnamec+" -o "+fnamebc)
 
 			fnamec="ecp2_"+tc+".c"
@@ -296,8 +299,10 @@ def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
 			os.system(copytext+" fp24.h "+fnameh)
 			replace(fnamec,"YYY",tf)
 			replace(fnamec,"XXX",bd)
+			replace(fnamec,"ZZZ",tc)
 			replace(fnameh,"YYY",tf)
 			replace(fnameh,"XXX",bd)
+			replace(fnameh,"ZZZ",tc)
 			os.system("emcc -O2 "+fnamec+" -o "+fnamebc)
 
 			fnamec="ecp4_"+tc+".c"
@@ -412,8 +417,10 @@ def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
 			os.system(copytext+" fp48.h "+fnameh)
 			replace(fnamec,"YYY",tf)
 			replace(fnamec,"XXX",bd)
+			replace(fnamec,"ZZZ",tc)
 			replace(fnameh,"YYY",tf)
 			replace(fnameh,"XXX",bd)
+			replace(fnameh,"ZZZ",tc)
 			os.system("emcc -O2 "+fnamec+" -o "+fnamebc)
 
 
@@ -519,7 +526,7 @@ while ptr<max:
 	selection.append(x)
 	ptr=ptr+1
 
-# curveset(big,field,curve,big_length_bytes,bits_in_base,modulus_bits,modulus_mod_8,modulus_type,curve_type,pairing_friendly,sextic twist,sign of x,curve security)
+# curveset(big,field,curve,big_length_bytes,bits_in_base,modulus_bits,modulus_mod_8,modulus_type,curve_type,pairing_friendly,sextic twist,sign of x,ate bits,curve security)
 # for each curve give names for big, field and curve. In many cases the latter two will be the same. 
 # Typically "big" is the size in bits, always a multiple of 8, "field" describes the modulus, and "curve" is the common name for the elliptic curve   
 # big_length_bytes is "big" divided by 8
@@ -530,96 +537,97 @@ while ptr<max:
 # curve_type is WEIERSTRASS, EDWARDS or MONTGOMERY
 # pairing_friendly is BN, BLS or NOT (if not pairing friendly)
 # if pairing friendly. M or D type twist, and sign of the family parameter x
+# ate bits is number of bits in Ate parameter (from romgen program)
 # curve security is AES equiavlent, rounded up.
 
 	if x==1:
-		curveset("256","25519","ED25519","32","29","255","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+		curveset("256","25519","ED25519","32","29","255","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","","128")
 		curve_selected=True
 	if x==2:
-		curveset("256","25519","C25519","32","29","255","5","PSEUDO_MERSENNE","MONTGOMERY","NOT","","","128")
+		curveset("256","25519","C25519","32","29","255","5","PSEUDO_MERSENNE","MONTGOMERY","NOT","","","","128")
 		curve_selected=True
 	if x==3:
-		curveset("256","NIST256","NIST256","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+		curveset("256","NIST256","NIST256","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","","128")
 		curve_selected=True
 	if x==4:
-		curveset("256","BRAINPOOL","BRAINPOOL","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+		curveset("256","BRAINPOOL","BRAINPOOL","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","","128")
 		curve_selected=True
 	if x==5:
-		curveset("256","ANSSI","ANSSI","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+		curveset("256","ANSSI","ANSSI","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","","128")
 		curve_selected=True
 
 	if x==6:
-		curveset("336","HIFIVE","HIFIVE","42","29","336","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","192")
+		curveset("336","HIFIVE","HIFIVE","42","29","336","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","","192")
 		curve_selected=True
 	if x==7:
-		curveset("448","GOLDILOCKS","GOLDILOCKS","56","29","448","7","GENERALISED_MERSENNE","EDWARDS","NOT","","","256")
+		curveset("448","GOLDILOCKS","GOLDILOCKS","56","29","448","7","GENERALISED_MERSENNE","EDWARDS","NOT","","","","256")
 		curve_selected=True
 	if x==8:
-		curveset("384","NIST384","NIST384","48","29","384","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","192")
+		curveset("384","NIST384","NIST384","48","29","384","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","","192")
 		curve_selected=True
 	if x==9:
-		curveset("416","C41417","C41417","52","29","414","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","256")
+		curveset("416","C41417","C41417","52","29","414","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","","256")
 		curve_selected=True
 	if x==10:
-		curveset("528","NIST521","NIST521","66","28","521","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","256")
+		curveset("528","NIST521","NIST521","66","28","521","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","","256")
 		curve_selected=True
 
 	if x==11:
-		curveset("256","256PMW","NUMS256W","32","28","256","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+		curveset("256","256PMW","NUMS256W","32","28","256","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","","128")
 		curve_selected=True
 	if x==12:
-		curveset("256","256PME","NUMS256E","32","29","256","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+		curveset("256","256PME","NUMS256E","32","29","256","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","","128")
 		curve_selected=True
 	if x==13:
-		curveset("384","384PM","NUMS384W","48","29","284","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","192")
+		curveset("384","384PM","NUMS384W","48","29","284","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","","192")
 		curve_selected=True
 	if x==14:
-		curveset("384","384PM","NUMS384E","48","29","384","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","192")
+		curveset("384","384PM","NUMS384E","48","29","384","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","","192")
 		curve_selected=True
 	if x==15:
-		curveset("512","512PM","NUMS512W","64","29","512","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","256")
+		curveset("512","512PM","NUMS512W","64","29","512","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","","256")
 		curve_selected=True
 	if x==16:
-		curveset("512","512PM","NUMS512E","64","29","512","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","256")
+		curveset("512","512PM","NUMS512E","64","29","512","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","","256")
 		curve_selected=True
 
 	if x==17:
-		curveset("256","SECP256K1","SECP256K1","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+		curveset("256","SECP256K1","SECP256K1","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","","128")
 		curve_selected=True
 
 
 	if x==18:
-		curveset("256","BN254","BN254","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+		curveset("256","BN254","BN254","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","66","128")
 		pfcurve_selected=True
 	if x==19:
-		curveset("256","BN254CX","BN254CX","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+		curveset("256","BN254CX","BN254CX","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","66","128")
 		pfcurve_selected=True
 	if x==20:
-		curveset("384","BLS383","BLS383","48","29","383","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","128")
+		curveset("384","BLS383","BLS383","48","29","383","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","65","128")
 		pfcurve_selected=True
 
 	if x==21:
-		curveset("384","BLS381","BLS381","48","29","381","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+		curveset("384","BLS381","BLS381","48","29","381","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","65","128")
 		pfcurve_selected=True
 
 	if x==22:
-		curveset("256","FP256BN","FP256BN","32","28","256","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","NEGATIVEX","128")
+		curveset("256","FP256BN","FP256BN","32","28","256","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","NEGATIVEX","66","128")
 		pfcurve_selected=True
 	if x==23:
-		curveset("512","FP512BN","FP512BN","64","29","512","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","POSITIVEX","128")
+		curveset("512","FP512BN","FP512BN","64","29","512","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","POSITIVEX","130","128")
 		pfcurve_selected=True
 # https://eprint.iacr.org/2017/334.pdf
 	if x==24:
-		curveset("464","BLS461","BLS461","58","28","461","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+		curveset("464","BLS461","BLS461","58","28","461","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","78","128")
 		pfcurve_selected=True
 
 	if x==25:
-		curveset("480","BLS24","BLS24","60","29","479","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","192")
+		curveset("480","BLS24","BLS24","60","29","479","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","49","192")
 		pfcurve_selected=True
 
 
 	if x==26:
-		curveset("560","BLS48","BLS48","70","29","556","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","256")
+		curveset("560","BLS48","BLS48","70","29","556","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","32","256")
 		pfcurve_selected=True