Merge pull request #6 from apache/bug-fix

bug fixes / updates
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 @@
 	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 @@
 	@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 @@
 	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 @@
 	@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 @@
 	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 @@
 	@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 @@
     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 @@
 
     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 @@
 
     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 @@
 	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 @@
 	@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_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 @@
 	@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 @@
 	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 @@
 	@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 @@
     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 @@
 
     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 @@
 
     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 @@
 	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 @@
 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 @@
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 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 @@
 /* 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 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 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 @@
 
 /* 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 @@
 		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 @@
 			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 @@
 		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 @@
 	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 @@
 			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 @@
 	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 @@
 	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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 //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 @@
 
 //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 @@
 }
 
 /* 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 @@
 	k := w - c
 
 	i := 10
-	key := NewFPint(0)
+	key := NewFP()
 
 	if k != 0 {
 		for ac[i] > k {
@@ -426,7 +433,7 @@
 	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 @@
 }
 
 /* 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 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 @@
 	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 @@
 	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 @@
 /* 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 @@
 	}
 	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 @@
 			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 @@
 		}
 		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 @@
 	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 @@
 
 /* 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 @@
 	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 @@
 }
 
 /* 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 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) 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) 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 @@
 	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 @@
 	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 @@
 }
 
 /* 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 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 @@
 /* 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) div_ip2() {
-	t := NewFP2int(0)
+	t := NewFP2()
 	F.norm()
 	t.a.copy(F.a)
 	t.a.add(F.b)
@@ -347,7 +354,7 @@
 
 /* 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 @@
 }
 
 /* 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 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 @@
 	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 @@
 	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 @@
 /* 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 @@
 	}
 	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 @@
 			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 @@
 		}
 		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 @@
 	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 @@
 
 /* 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 @@
 	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 @@
 }
 
 /* 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 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) 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) 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 @@
 	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 @@
 	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 @@
 }
 
 /* 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 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 @@
 	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 @@
 	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 @@
 /* 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 @@
 	}
 	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 @@
 			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 @@
 		}
 		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 @@
 	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 @@
 
 /* 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 @@
 	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 @@
 }
 
 /* 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 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) 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) 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 @@
 	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 @@
 	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 @@
 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 @@
 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 @@
 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 @@
 		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 @@
 		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 @@
 	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 @@
 
 		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 @@
 		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 @@
 		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 @@
 	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 @@
 
 		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 @@
 		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 @@
 		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 @@
 	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 @@
 
 		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 @@
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 
 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 @@
 			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 @@
 
 /* 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 @@
 		}
 		else
 		{
-			z=new FP(0);
+			z=new FP();
 		}
 	}
 
@@ -113,8 +113,8 @@
 /* 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 @@
 		}
 		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 @@
 		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 @@
 		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 @@
 				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 @@
 			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 @@
 		{
 			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 @@
 				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 @@
 		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 @@
 		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 @@
 
 /* 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 @@
 
 /* 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 @@
 
 /* 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 @@
 		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 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 @@
 		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 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 @@
 		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 @@
 				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 @@
 			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 @@
 			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 @@
 		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 @@
 		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 @@
 /* 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 @@
 		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 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 @@
 	{
 		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 @@
 	{
 		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 @@
 		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 @@
 		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 @@
 	}
 
 /* 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 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 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 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 @@
 /* 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 @@
 		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 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 @@
 		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 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 @@
 		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 @@
 				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 @@
 			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 @@
 		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 @@
 /* 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 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 @@
 		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 @@
 	{
 		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 @@
 		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 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 @@
 	{
 		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 @@
 	{
 		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 @@
 		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 @@
 		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 @@
 		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 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 @@
 		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 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 @@
 		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 @@
 				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 @@
 			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 @@
 		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 @@
 /* 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 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 @@
 		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 @@
 	{
 		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 @@
 		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 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 @@
 	{
 		norm();
 		FP4 m=new FP4(a);
-		FP4 t=new FP4(0);
+		FP4 t=new FP4();
 		m.add(b);
 
 		m.neg();
@@ -233,7 +239,7 @@
 	{
 		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 @@
 		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 @@
 		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 @@
 /* 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 @@
 		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 @@
 		}
 		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 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 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 @@
 				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 @@
 			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 @@
 		{
 			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 @@
 				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 @@
 		{
 //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 @@
 		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 @@
 /* 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 @@
 			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 @@
 			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 @@
 		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 @@
 			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 @@
 			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 @@
 		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 @@
 			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 @@
 			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 @@
 			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 @@
 		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 @@
 			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 @@
 
             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 @@
             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 @@
                 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 @@
 			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 @@
 			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 @@
 			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 @@
             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 @@
             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 @@
             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 @@
     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 @@
         r[0] *= lv
 
 def e(P, Q):
-    r = miller(P, Q)
+    r = ate(P, Q)
     return fexp(r)
 
 
@@ -250,6 +250,9 @@
     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 @@
         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 @@
         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 @@
 	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 @@
 	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 @@
 	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 @@
     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 @@
     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 @@
     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 @@
     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 @@
             {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 @@
         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 @@
             i+=4
         }
         for j in N-4 ..< N {rkey[j-N+4]=fkey[j]}
+	return true
     }
     
     func getreg() -> [UInt8]
@@ -384,7 +408,7 @@
         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 @@
         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 @@
     /* 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 @@
     
         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 @@
     
         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 @@
    /* 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 @@
     /* 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 @@
         }
         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 @@
         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 @@
         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 @@
                 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 @@
             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 @@
         {
             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 @@
                     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 @@
         {
             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 @@
         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 @@
     /* 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 @@
     /* 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 @@
     /* 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 @@
         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 @@
 
         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 @@
     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 @@
         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 @@
         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 @@
     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 @@
         }
         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 @@
 
             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 @@
                 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 @@
             }
             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 @@
         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 @@
     /* trace function */
     func trace() -> FP4
     {
-        var t=FP4(0)
+        var t=FP4()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -885,10 +903,10 @@
     {
         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 @@
     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 @@
     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 @@
     {
         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 @@
     {
         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 @@
         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 @@
         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 @@
     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 @@
     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 @@
     mutating func neg()
     {
         var m=FP(a)
-        var t=FP(0)
+        var t=FP()
     
         m.add(b)
         m.neg()
@@ -334,7 +340,7 @@
     /* 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 @@
     
     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 @@
     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 @@
         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 @@
         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 @@
     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 @@
         }
         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 @@
 
             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 @@
                 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 @@
             }
             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 @@
         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 @@
     /* trace function */
     func trace() -> FP8
     {
-        var t=FP8(0)
+        var t=FP8()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -978,12 +996,12 @@
         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 @@
     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 @@
     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 @@
     {
         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 @@
     {
         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 @@
         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 @@
         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 @@
     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 @@
         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 @@
         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 @@
     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 @@
         }
         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 @@
 
             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 @@
                 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 @@
             }
             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 @@
         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 @@
     /* trace function */
     func trace() -> FP16
     {
-        var t=FP16(0)
+        var t=FP16()
         t.copy(a)
         t.imul(3)
         t.reduce()
@@ -1137,14 +1155,14 @@
 
         
         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 @@
     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 @@
     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 @@
     {
         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 @@
     {
         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 @@
         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 @@
         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 @@
     }
     
     /* 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 @@
         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 @@
         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 @@
         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 @@
             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 @@
         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 @@
         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 @@
         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 @@
             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 @@
         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 @@
         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 @@
         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 @@
             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 @@
 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 @@
 	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 @@
 	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 @@
 			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 @@
 			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 @@
 			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 @@
 	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 @@
 # 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