You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by km...@apache.org on 2019/06/26 13:43:31 UTC

[incubator-milagro-crypto-js] 02/03: moved examples to BLS381 curve

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

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

commit 36004222bd841fd345bd7b6d7acac7350464a771
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Wed Jun 26 14:37:18 2019 +0100

    moved examples to BLS381 curve
---
 examples/browser/example_BLS.html                  |    2 +-
 ...ple_DVS_BLS383.html => example_DVS_BLS381.html} |    2 +-
 ...IST521.html => example_ECC_BLS381_NIST521.html} |    4 +-
 ...e_MPIN_BLS383.html => example_MPIN_BLS381.html} |    2 +-
 ...L_BLS383.html => example_MPIN_FULL_BLS381.html} |    2 +-
 ...S383.html => example_MPIN_ONE_PASS_BLS381.html} |    2 +-
 ..._TP_BLS383.html => example_MPIN_TP_BLS381.html} |    2 +-
 examples/browser/example_all.html                  | 1276 ++++++++++++++++++++
 ...example_DVS_BLS383.js => example_DVS_BLS381.js} |    2 +-
 ...83_NIST521.js => example_ECC_BLS381_NIST521.js} |    4 +-
 ...ample_MPIN_BLS383.js => example_MPIN_BLS381.js} |    2 +-
 ..._FULL_BLS383.js => example_MPIN_FULL_BLS381.js} |    2 +-
 ...S_BLS383.js => example_MPIN_ONE_PASS_BLS381.js} |    2 +-
 13 files changed, 1290 insertions(+), 14 deletions(-)

diff --git a/examples/browser/example_BLS.html b/examples/browser/example_BLS.html
index 67418e3..ab8cbf4 100644
--- a/examples/browser/example_BLS.html
+++ b/examples/browser/example_BLS.html
@@ -46,7 +46,7 @@
 
 
 <p><a id="myLink4" href="#" onclick="location.reload(false);bn254();">BN254 254-bit k=12 Pairing-Friendly BN Curve Boneh-Lynn-Shacham</a></p>
-<p><a id="myLink5" href="#" onclick="location.reload(false);bls383();">BLS381 381-bit k=12 Pairing-Friendly BLS Curve Boneh-Lynn-Shacham</a></p>
+<p><a id="myLink5" href="#" onclick="location.reload(false);bls381();">BLS381 381-bit k=12 Pairing-Friendly BLS Curve Boneh-Lynn-Shacham</a></p>
 <p><a id="myLink6" href="#" onclick="location.reload(false);bls24();">BLS24 479-bit k=24 Pairing-Friendly BLS Curve Boneh-Lynn-Shacham</a></p>
 <p><a id="myLink7" href="#" onclick="location.reload(false);bls48();">BLS48 556-bit k=48 Pairing-Friendly BLS Curve Boneh-Lynn-Shacham</a></p>
 
diff --git a/examples/browser/example_DVS_BLS383.html b/examples/browser/example_DVS_BLS381.html
similarity index 99%
rename from examples/browser/example_DVS_BLS383.html
rename to examples/browser/example_DVS_BLS381.html
index d5c0183..ad11117 100644
--- a/examples/browser/example_DVS_BLS383.html
+++ b/examples/browser/example_DVS_BLS381.html
@@ -55,7 +55,7 @@ under the License.
 /* Test DVS - test driver and function exerciser for Designated Verifier Signature API Functions */
 
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 var RAW = [];
 var rng = new ctx.RAND();
diff --git a/examples/browser/example_ECC_BLS383_NIST521.html b/examples/browser/example_ECC_BLS381_NIST521.html
similarity index 98%
rename from examples/browser/example_ECC_BLS383_NIST521.html
rename to examples/browser/example_ECC_BLS381_NIST521.html
index ea61f8e..43a4057 100644
--- a/examples/browser/example_ECC_BLS383_NIST521.html
+++ b/examples/browser/example_ECC_BLS381_NIST521.html
@@ -56,10 +56,10 @@ under the License.
 /* Test ECC - test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
 
 
-var ctx1 = new CTX("BLS383");
+var ctx1 = new CTX("BLS381");
 var ctx2 = new CTX("NIST521");
 
-console.log("Start testing BLS383");
+console.log("Start testing BLS381");
 
 var pp = "M0ng00se",
     res,
diff --git a/examples/browser/example_MPIN_BLS383.html b/examples/browser/example_MPIN_BLS381.html
similarity index 99%
rename from examples/browser/example_MPIN_BLS383.html
rename to examples/browser/example_MPIN_BLS381.html
index 6ca6b73..08d54cd 100644
--- a/examples/browser/example_MPIN_BLS383.html
+++ b/examples/browser/example_MPIN_BLS381.html
@@ -55,7 +55,7 @@ under the License.
 /* Test MPIN - test driver and function exerciser for MPIN API Functions */
 
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/browser/example_MPIN_FULL_BLS383.html b/examples/browser/example_MPIN_FULL_BLS381.html
similarity index 99%
rename from examples/browser/example_MPIN_FULL_BLS383.html
rename to examples/browser/example_MPIN_FULL_BLS381.html
index 9a572bb..d95979f 100644
--- a/examples/browser/example_MPIN_FULL_BLS383.html
+++ b/examples/browser/example_MPIN_FULL_BLS381.html
@@ -55,7 +55,7 @@ under the License.
 /* Test MPIN - test driver and function exerciser for MPIN API Functions */
 
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/browser/example_MPIN_ONE_PASS_BLS383.html b/examples/browser/example_MPIN_ONE_PASS_BLS381.html
similarity index 99%
rename from examples/browser/example_MPIN_ONE_PASS_BLS383.html
rename to examples/browser/example_MPIN_ONE_PASS_BLS381.html
index a798a31..9d43ab6 100644
--- a/examples/browser/example_MPIN_ONE_PASS_BLS383.html
+++ b/examples/browser/example_MPIN_ONE_PASS_BLS381.html
@@ -55,7 +55,7 @@ under the License.
 /* Test MPIN - test driver and function exerciser for MPIN API Functions */
 
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/browser/example_MPIN_TP_BLS383.html b/examples/browser/example_MPIN_TP_BLS381.html
similarity index 99%
rename from examples/browser/example_MPIN_TP_BLS383.html
rename to examples/browser/example_MPIN_TP_BLS381.html
index 8f8c1d2..c29c250 100644
--- a/examples/browser/example_MPIN_TP_BLS383.html
+++ b/examples/browser/example_MPIN_TP_BLS381.html
@@ -55,7 +55,7 @@ under the License.
 /* Test MPIN - test driver and function exerciser for MPIN API Functions */
 
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/browser/example_all.html b/examples/browser/example_all.html
new file mode 100644
index 0000000..9c96ad9
--- /dev/null
+++ b/examples/browser/example_all.html
@@ -0,0 +1,1276 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>JavaScript Test ALL</title>
+</head>
+<body>
+<h1>JavaScript Test All Examples</h1>
+<script src="src/rand.js"></script>
+<script src="src/rom_curve.js"></script>
+<script src="src/rom_field.js"></script>
+<script src="src/uint64.js"></script>
+<script src="src/aes.js"></script>
+<script src="src/big.js"></script>
+<script src="src/gcm.js"></script>
+<script src="src/hash256.js"></script>
+<script src="src/hash384.js"></script>
+<script src="src/hash512.js"></script>
+<script src="src/sha3.js"></script>
+<script src="src/nhs.js"></script>
+<script src="src/fp.js"></script>
+<script src="src/fp2.js"></script>
+<script src="src/fp4.js"></script>
+<script src="src/fp12.js"></script>
+<script src="src/ff.js"></script>
+<script src="src/rsa.js"></script>
+<script src="src/ecp.js"></script>
+<script src="src/ecp2.js"></script>
+<script src="src/ecdh.js"></script>
+<script src="src/pair.js"></script>
+<script src="src/bls.js"></script>
+<script src="src/mpin.js"></script>
+<script src="src/ctx.js"></script>
+
+<script src="src/fp8.js"></script>
+<script src="src/fp16.js"></script>
+<script src="src/fp24.js"></script>
+<script src="src/fp48.js"></script>
+<script src="src/ecp4.js"></script>
+<script src="src/ecp8.js"></script>
+<script src="src/pair192.js"></script>
+<script src="src/pair256.js"></script>
+<script src="src/mpin192.js"></script>
+<script src="src/mpin256.js"></script>
+<script src="src/bls192.js"></script>
+<script src="src/bls256.js"></script>
+
+
+<p><a id="myLink1" href="#" onclick="location.reload(false);ed25519();">ED25519 255-bit Edwards Elliptic Curve ECDH/ECIES/ECDSA</a></p>
+<p><a id="myLink2" href="#" onclick="location.reload(false);nist256();">NIST256 256-bit Weierstrass Elliptic Curve ECDH/ECIES/ECDSA</a></p>
+<p><a id="myLink3" href="#" onclick="location.reload(false);goldilocks();">GOLDILOCKS 448-bit Edwards Elliptic Curve ECDH/ECIES/ECDSA</a></p>
+<p><a id="myLink5" href="#" onclick="location.reload(false);bls381();">BLS381 381-bit k=12 Pairing-Friendly BLS Curve MPIN</a></p>
+<p><a id="myLink6" href="#" onclick="location.reload(false);bls24();">BLS24 479-bit k=24 Pairing-Friendly BLS Curve MPIN</a></p>
+<p><a id="myLink7" href="#" onclick="location.reload(false);bls48();">BLS48 556-bit k=48 Pairing-Friendly BLS Curve MPIN</a></p>
+<p><a id="myLink8" href="#" onclick="location.reload(false);rsa2048();">RSA2048 2048-bit RSA Key generation/Encryption/Decryption</a></p>
+
+
+<script>
+
+/* Test ECC */
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+// ED25519 context
+function ed25519() {
+	var ctx = new CTX('ED25519');
+
+	mywindow=window.open();
+
+	mywindow.document.write("<br> ED25519 Curve "+  "<br>");
+
+	var i,j=0,res;
+	var result;
+	var pp="M0ng00se";
+
+	var EGS=ctx.ECDH.EGS;
+	var EFS=ctx.ECDH.EFS;
+	var EAS=ctx.ECP.AESKEY;
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var S1=[];
+	var W0=[];
+	var W1=[];
+	var Z0=[];
+	var Z1=[];
+	var RAW=[];
+	var SALT=[];
+	var P1=[];
+	var P2=[];
+	var V=[];
+	var M=[];
+	var T=new Array(12);  // must specify required length
+	var CS=[];
+	var DS=[];
+
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+	for (i=0;i<8;i++) SALT[i]=(i+1);  // set Salt
+
+	mywindow.document.write("Alice's Passphrase= " + pp + "<br>");
+
+	var PW=ctx.ECDH.stringtobytes(pp);
+/* private key S0 of size EGS bytes derived from Password and Salt */
+	var S0=ctx.ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+	mywindow.document.write("Alice's private key= 0x"+ctx.ECDH.bytestostring(S0)+ "<br>");
+/* Generate Key pair S/W */
+	ctx.ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+	mywindow.document.write("Alice's public key= 0x"+ctx.ECDH.bytestostring(W0)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W0);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+/* Random private key for other party */
+	ctx.ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+	mywindow.document.write("Servers private key= 0x"+ctx.ECDH.bytestostring(S1)+ "<br>");
+	mywindow.document.write("Servers public key= 0x"+ctx.ECDH.bytestostring(W1)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W1);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+			
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+	ctx.ECDH.ECPSVDP_DH(S0,W1,Z0);
+	ctx.ECDH.ECPSVDP_DH(S1,W0,Z1);
+
+	var same=true;
+	for (i=0;i<ctx.ECDH.EFS;i++)
+		if (Z0[i]!=Z1[i]) same=false;
+
+	if (!same)
+		alert("*** ECPSVDP-DH Failed");
+
+	var KEY=ctx.ECDH.KDF2(sha,Z0,null,ctx.ECP.AESKEY);
+
+	mywindow.document.write("Alice's ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+	mywindow.document.write("Servers ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+
+	if (ctx.ECP.CURVETYPE!=ctx.ECP.MONTGOMERY)
+	{
+		mywindow.document.write("Testing ECIES"+ "<br>");
+
+		P1[0]=0x0; P1[1]=0x1; P1[2]=0x2; 
+		P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3; 
+
+		for (i=0;i<=16;i++) M[i]=i; 
+
+		var C=ctx.ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+		mywindow.document.write("Ciphertext= "+ "<br>");
+		mywindow.document.write("V= 0x"+ctx.ECDH.bytestostring(V)+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(C)+ "<br>");
+		mywindow.document.write("T= 0x"+ctx.ECDH.bytestostring(T)+ "<br>");
+
+
+		M=ctx.ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+		if (M.length==0)
+			alert("*** ECIES Decryption Failed ");
+		else mywindow.document.write("Decryption succeeded"+ "<br>");
+
+		mywindow.document.write("Message is 0x"+ctx.ECDH.bytestostring(M)+ "<br>");
+
+		mywindow.document.write("Testing ECDSA"+ "<br>");
+
+		if (ctx.ECDH.ECPSP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			alert("***ECDSA Signature Failed");
+		
+		mywindow.document.write("Signature= "+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(CS)+ "<br>");
+		mywindow.document.write("D= 0x"+ctx.ECDH.bytestostring(DS)+ "<br>");
+
+		if (ctx.ECDH.ECPVP_DSA(sha,W0,M,CS,DS)!=0)
+			alert("***ECDSA Verification Failed");
+		else mywindow.document.write("ECDSA Signature/Verification succeeded "+  "<br>");
+	}
+
+}
+// NIST256 context
+
+function nist256() {
+	var ctx = new CTX('NIST256');
+	mywindow=window.open();
+
+	mywindow.document.write("<br> NIST256 Curve "+  "<br>");
+	var i,j=0,res;
+	var result;
+	var pp="M0ng00se";
+
+	var EGS=ctx.ECDH.EGS;
+	var EFS=ctx.ECDH.EFS;
+	var EAS=ctx.ECP.AESKEY;
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var S1=[];
+	var W0=[];
+	var W1=[];
+	var Z0=[];
+	var Z1=[];
+	var RAW=[];
+	var SALT=[];
+	var P1=[];
+	var P2=[];
+	var V=[];
+	var M=[];
+	var T=new Array(12);  // must specify required length
+	var CS=[];
+	var DS=[];
+
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+
+	for (i=0;i<8;i++) SALT[i]=(i+1);  // set Salt
+
+	mywindow.document.write("Alice's Passphrase= " + pp + "<br>");
+
+	var PW=ctx.ECDH.stringtobytes(pp);
+/* private key S0 of size EGS bytes derived from Password and Salt */
+	var S0=ctx.ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+	mywindow.document.write("Alice's private key= 0x"+ctx.ECDH.bytestostring(S0)+ "<br>");
+/* Generate Key pair S/W */
+	ctx.ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+	mywindow.document.write("Alice's public key= 0x"+ctx.ECDH.bytestostring(W0)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W0);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+/* Random private key for other party */
+	ctx.ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+	mywindow.document.write("Servers private key= 0x"+ctx.ECDH.bytestostring(S1)+ "<br>");
+	mywindow.document.write("Servers public key= 0x"+ctx.ECDH.bytestostring(W1)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W1);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+			
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+	ctx.ECDH.ECPSVDP_DH(S0,W1,Z0);
+	ctx.ECDH.ECPSVDP_DH(S1,W0,Z1);
+
+	var same=true;
+	for (i=0;i<ctx.ECDH.EFS;i++)
+		if (Z0[i]!=Z1[i]) same=false;
+
+	if (!same)
+		alert("*** ECPSVDP-DH Failed");
+
+	var KEY=ctx.ECDH.KDF2(sha,Z0,null,ctx.ECP.AESKEY);
+
+	mywindow.document.write("Alice's ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+	mywindow.document.write("Servers ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+
+	if (ctx.ECP.CURVETYPE!=ctx.ECP.MONTGOMERY)
+	{
+		mywindow.document.write("Testing ECIES"+ "<br>");
+
+		P1[0]=0x0; P1[1]=0x1; P1[2]=0x2; 
+		P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3; 
+
+		for (i=0;i<=16;i++) M[i]=i; 
+
+		var C=ctx.ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+		mywindow.document.write("Ciphertext= "+ "<br>");
+		mywindow.document.write("V= 0x"+ctx.ECDH.bytestostring(V)+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(C)+ "<br>");
+		mywindow.document.write("T= 0x"+ctx.ECDH.bytestostring(T)+ "<br>");
+
+
+		M=ctx.ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+		if (M.length==0)
+			alert("*** ECIES Decryption Failed ");
+		else mywindow.document.write("Decryption succeeded"+ "<br>");
+
+		mywindow.document.write("Message is 0x"+ctx.ECDH.bytestostring(M)+ "<br>");
+
+		mywindow.document.write("Testing ECDSA"+ "<br>");
+
+		if (ctx.ECDH.ECPSP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			alert("***ECDSA Signature Failed");
+		
+		mywindow.document.write("Signature= "+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(CS)+ "<br>");
+		mywindow.document.write("D= 0x"+ctx.ECDH.bytestostring(DS)+ "<br>");
+
+		if (ctx.ECDH.ECPVP_DSA(sha,W0,M,CS,DS)!=0)
+			alert("***ECDSA Verification Failed");
+		else mywindow.document.write("ECDSA Signature/Verification succeeded "+  "<br>");
+	}
+
+}
+
+
+// GOLDILOCKS context
+function goldilocks() {
+	var ctx = new CTX('GOLDILOCKS');
+	mywindow=window.open();
+
+	mywindow.document.write("<br> GOLDILOCKS Curve "+  "<br>");
+
+	var i,j=0,res;
+	var result;
+	var pp="M0ng00se";
+
+	var EGS=ctx.ECDH.EGS;
+	var EFS=ctx.ECDH.EFS;
+	var EAS=ctx.ECP.AESKEY;
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var S1=[];
+	var W0=[];
+	var W1=[];
+	var Z0=[];
+	var Z1=[];
+	
+	var SALT=[];
+	var P1=[];
+	var P2=[];
+	var V=[];
+	var M=[];
+	var T=new Array(12);  // must specify required length
+	var CS=[];
+	var DS=[];
+
+	var RAW=[];
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+
+	for (i=0;i<8;i++) SALT[i]=(i+1);  // set Salt
+
+	mywindow.document.write("Alice's Passphrase= " + pp + "<br>");
+
+	var PW=ctx.ECDH.stringtobytes(pp);
+/* private key S0 of size EGS bytes derived from Password and Salt */
+	var S0=ctx.ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+	mywindow.document.write("Alice's private key= 0x"+ctx.ECDH.bytestostring(S0)+ "<br>");
+/* Generate Key pair S/W */
+	ctx.ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+	mywindow.document.write("Alice's public key= 0x"+ctx.ECDH.bytestostring(W0)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W0);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+/* Random private key for other party */
+	ctx.ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+	mywindow.document.write("Servers private key= 0x"+ctx.ECDH.bytestostring(S1)+ "<br>");
+	mywindow.document.write("Servers public key= 0x"+ctx.ECDH.bytestostring(W1)+ "<br>");
+
+	res=ctx.ECDH.PUBLIC_KEY_VALIDATE(W1);
+	if (res!=0)
+		alert("ECP Public Key is invalid!");
+			
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+	ctx.ECDH.ECPSVDP_DH(S0,W1,Z0);
+	ctx.ECDH.ECPSVDP_DH(S1,W0,Z1);
+
+	var same=true;
+	for (i=0;i<ctx.ECDH.EFS;i++)
+		if (Z0[i]!=Z1[i]) same=false;
+
+	if (!same)
+		alert("*** ECPSVDP-DH Failed");
+
+	var KEY=ctx.ECDH.KDF2(sha,Z0,null,ctx.ECP.AESKEY);
+
+	mywindow.document.write("Alice's ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+	mywindow.document.write("Servers ECDH Key=  0x"+ctx.ECDH.bytestostring(KEY)+ "<br>");
+
+	if (ctx.ECP.CURVETYPE!=ctx.ECP.MONTGOMERY)
+	{
+		mywindow.document.write("Testing ECIES"+ "<br>");
+
+		P1[0]=0x0; P1[1]=0x1; P1[2]=0x2; 
+		P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3; 
+
+		for (i=0;i<=16;i++) M[i]=i; 
+
+		var C=ctx.ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+		mywindow.document.write("Ciphertext= "+ "<br>");
+		mywindow.document.write("V= 0x"+ctx.ECDH.bytestostring(V)+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(C)+ "<br>");
+		mywindow.document.write("T= 0x"+ctx.ECDH.bytestostring(T)+ "<br>");
+
+
+		M=ctx.ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+		if (M.length==0)
+			alert("*** ECIES Decryption Failed ");
+		else mywindow.document.write("Decryption succeeded"+ "<br>");
+
+		mywindow.document.write("Message is 0x"+ctx.ECDH.bytestostring(M)+ "<br>");
+
+		mywindow.document.write("Testing ECDSA"+ "<br>");
+
+		if (ctx.ECDH.ECPSP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			alert("***ECDSA Signature Failed");
+		
+		mywindow.document.write("Signature= "+ "<br>");
+		mywindow.document.write("C= 0x"+ctx.ECDH.bytestostring(CS)+ "<br>");
+		mywindow.document.write("D= 0x"+ctx.ECDH.bytestostring(DS)+ "<br>");
+
+		if (ctx.ECDH.ECPVP_DSA(sha,W0,M,CS,DS)!=0)
+			alert("***ECDSA Verification Failed");
+		else mywindow.document.write("ECDSA Signature/Verification succeeded "+  "<br>");
+	}
+}
+
+
+/* Test RSA */
+/* test driver and function exerciser for RSA API Functions */
+
+
+// RSA2048 context
+function rsa2048() {
+	var ctx = new CTX('RSA2048');
+
+	var i,j=0,res;
+	var result;
+
+	var sha=ctx.RSA.HASH_TYPE;
+
+	var message="Hello World\n";
+
+	var pub=new ctx.rsa_public_key(ctx.FF.FFLEN);
+	var priv=new ctx.rsa_private_key(ctx.FF.HFLEN);
+
+	var ML=[];
+	var C=[];
+	var S=[];
+	
+	var RAW=[];
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+	mywindow=window.open();
+
+	var start,end,time;
+	start=new Date().getTime();
+	mywindow.document.write("<br> Generating RSA public/private key pair (slow!)  <br>");
+	ctx.RSA.KEY_PAIR(rng,65537,priv,pub);
+	end=new Date().getTime();
+	time=end-start;
+	mywindow.document.write("Time in ms= "+time+"<br>");
+
+	var M=ctx.RSA.stringtobytes(message);  
+	mywindow.document.write("Encrypting test string <br>");
+
+	var E=ctx.RSA.OAEP_ENCODE(sha,M,rng,null); /* OAEP encode message m to e  */
+	mywindow.document.write("Encoding= 0x" + ctx.RSA.bytestohex(E) + "<br>");  
+
+	mywindow.document.write("Public key= 0x"+pub.n.toString() + "<br>"); 
+
+	start=new Date().getTime();	
+	ctx.RSA.ENCRYPT(pub,E,C);     /* encrypt encoded message */
+	end=new Date().getTime();	
+	time=end-start;
+	mywindow.document.write("Time in ms= "+time+"<br>");
+
+	mywindow.document.write("Ciphertext= 0x" + ctx.RSA.bytestohex(C) + "<br>");  
+
+	mywindow.document.write("Decrypting test string <br>");
+	start=new Date().getTime();	
+	ctx.RSA.DECRYPT(priv,C,ML); 
+	end=new Date().getTime();
+	time=end-start;
+	mywindow.document.write("Time in ms= "+time+"<br>");
+
+	var cmp=true;
+	if (E.length!=ML.length) cmp=false;
+	else
+	{
+		for (var j=0;j<E.length;j++)
+			if (E[j]!=ML[j]) cmp=false;
+	}
+	if (cmp) mywindow.document.write("Decryption is OK <br>");
+	else mywindow.document.write("Decryption Failed <br>");
+
+	var MS=ctx.RSA.OAEP_DECODE(sha,null,ML); /* OAEP decode message  */
+	mywindow.document.write("Decoding= 0x" + ctx.RSA.bytestohex(MS) + "<br>");  
+
+	mywindow.document.write("message= "+ctx.RSA.bytestostring(MS) + "<br>");  
+
+
+	mywindow.document.write("Signing message <br>");
+	ctx.RSA.PKCS15(sha,M,C);
+
+	ctx.RSA.DECRYPT(priv,C,S); /* create signature in S */ 
+
+	mywindow.document.write("Signature= 0x" + ctx.RSA.bytestohex(S) + "<br>");  
+
+	ctx.RSA.ENCRYPT(pub,S,ML); 
+
+	cmp=true;
+	if (C.length!=ML.length) cmp=false;
+	else
+	{
+		for (var j=0;j<C.length;j++)
+			if (C[j]!=ML[j]) cmp=false;
+	}
+	if (cmp) mywindow.document.write("Signature is valid <br>");
+	else mywindow.document.write("Signature is INVALID <br>");
+
+	ctx.RSA.PRIVATE_KEY_KILL(priv);
+
+
+}
+
+/* Test M-Pin */
+
+// BLS381 context
+function bls381() {
+	var ctx = new CTX('BLS381');
+	mywindow=window.open();
+
+	mywindow.document.write("<br> BLS381 Pairing-Friendly Curve "+  "<br>");
+
+	var i,res;
+	var result;
+
+	var EGS=ctx.MPIN.EGS;
+	var EFS=ctx.MPIN.EFS;
+	var EAS=ctx.ECP.AESKEY;
+
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var G1S=2*EFS+1; /* Group 1 Size */
+	var G2S=4*EFS; /* Group 2 Size */
+
+	var S=[];
+	var SST=[];
+	var TOKEN = [];
+	var PERMIT = [];
+	var SEC = [];
+	var xID = [];
+	var xCID = [];
+	var X= [];
+	var Y= [];
+	var E=[];
+	var F=[];
+	var HCID=[];
+	var HID=[];
+	var HTID=[];
+
+	var G1=[];
+	var G2=[];
+	var R=[];
+	var Z=[];
+	var W=[];
+	var T=[];
+	var CK=[];
+	var SK=[];
+
+	var HSID=[];
+
+/* Set configuration */
+	var PERMITS=true;
+	var PINERROR=true;
+	var FULL=true;
+    var ONE_PASS=false;
+
+	var RAW=[];
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+
+/* Trusted Authority set-up */
+	ctx.MPIN.RANDOM_GENERATE(rng,S);
+	mywindow.document.write("M-Pin Master Secret s: 0x"+ctx.MPIN.bytestostring(S) + "<br>");
+ 
+ /* Create Client Identity */
+ 	var IDstr = "testUser@miracl.com";
+	var CLIENT_ID = ctx.MPIN.stringtobytes(IDstr);  
+	HCID=ctx.MPIN.HASH_ID(sha,CLIENT_ID);  /* Either Client or TA calculates Hash(ID) - you decide! */
+		
+	mywindow.document.write("Client ID= "+ctx.MPIN.bytestostring(CLIENT_ID) + "<br>");
+
+/* Client and Server are issued secrets by DTA */
+	ctx.MPIN.GET_SERVER_SECRET(S,SST);
+	mywindow.document.write("Server Secret SS: 0x"+ctx.MPIN.bytestostring(SST) + "<br>");
+
+	ctx.MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+	mywindow.document.write("Client Secret CS: 0x"+ctx.MPIN.bytestostring(TOKEN) + "<br>");     
+	
+/* Client extracts PIN from secret to create Token */
+	var pin=1234;
+	mywindow.document.write("Client extracts PIN= "+pin + "<br>"); 
+	var rtn=ctx.MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+	if (rtn != 0)
+		mywindow.document.write("Failed to extract PIN " + "<br>");  
+
+	mywindow.document.write("Client Token TK: 0x"+ctx.MPIN.bytestostring(TOKEN) + "<br>");        
+
+	if (FULL)
+	{
+		ctx.MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+	}
+
+	var date;
+	if (PERMITS)
+	{
+		date=ctx.MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 	
+		ctx.MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+		mywindow.document.write("Time Permit TP: 0x"+ctx.MPIN.bytestostring(PERMIT) + "<br>");   
+
+/* This encoding makes Time permit look random - Elligator squared */
+		ctx.MPIN.ENCODING(rng,PERMIT);
+		mywindow.document.write("Encoded Time Permit TP: 0x"+ctx.MPIN.bytestostring(PERMIT) + "<br>");   
+		ctx.MPIN.DECODING(PERMIT);
+		mywindow.document.write("Decoded Time Permit TP: 0x"+ctx.MPIN.bytestostring(PERMIT) + "<br>");   
+	}
+	else date=0;
+
+	pin=parseInt(mywindow.prompt("Enter PIN= "));
+
+/* Set date=0 and PERMIT=null if time permits not in use
+
+Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC
+If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H_T(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+If Time Permits OFF set xCID = null, HTID=null and use xID and HID only
+If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required
+If Time permits are ON, AND pin error detection is NOT required, set xID=null, HID=null and use xCID and HTID only.
+
+
+*/
+	var pxID=xID;
+	var pxCID=xCID;
+	var pHID=HID;
+	var pHTID=HTID;
+	var pE=E;
+	var pF=F;
+	var pPERMIT=PERMIT;
+	var prHID;
+
+	if (date!=0)
+	{
+		prHID=pHTID;
+		if (!PINERROR)
+		{
+			pxID=null;
+			//	pHID=null;
+		}
+	}
+	else
+	{
+		prHID=pHID;
+		pPERMIT=null;
+		pxCID=null;
+		pHTID=null;
+	}
+	if (!PINERROR)
+	{
+		pE=null;
+		pF=null;
+	}
+
+	if (ONE_PASS)
+	{
+		mywindow.document.write("MPIN Single Pass " + "<br>");   
+		timeValue = ctx.MPIN.GET_TIME();
+		mywindow.document.write("Epoch " + timeValue + "<br>");   
+
+		rtn=ctx.MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+
+		if (rtn != 0)
+		mywindow.document.write("FAILURE: CLIENT rtn: " + rtn + "<br>");   
+
+		if (FULL)
+		{
+			HCID=ctx.MPIN.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+		}
+
+		rtn=ctx.MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER rtn: " + rtn+ "<br>");  
+
+		if (FULL)
+		{
+			HSID=ctx.MPIN.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+		}
+	}
+	else 
+	{
+		mywindow.document.write("MPIN Multi Pass " + "<br>");   
+		rtn=ctx.MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_1 rtn: " + rtn + "<br>");   
+  
+		if (FULL)
+		{
+			HCID=ctx.MPIN.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+		}
+    
+  /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
+		ctx.MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+    
+  /* Server generates Random number Y and sends it to Client */
+		ctx.MPIN.RANDOM_GENERATE(rng,Y);
+    
+		if (FULL)
+		{
+			HSID=ctx.MPIN.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+		}
+    
+  /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+		rtn=ctx.MPIN.CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_2 rtn: " + rtn + "<br>");  
+  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+  /* If PIN error not required, set E and F = NULL */
+		rtn=ctx.MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+    
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER_2 rtn: " + rtn+ "<br>");  
+    
+	}
+    		  
+
+	if (rtn == ctx.MPIN.BAD_PIN)
+	{
+		mywindow.document.write("Server says - Bad Pin. I don't know you. Feck off." + "<br>"); 
+		if (PINERROR)
+		{
+			var err=ctx.MPIN.KANGAROO(E,F);
+			if (err!=0) mywindow.document.write("(Client PIN is out by "+err + ")<br>");
+		}
+	}
+	else 
+	{
+		mywindow.document.write("Server says - PIN is good! You really are "+IDstr + "<br>"); 
+		if (FULL)
+		{
+			H=ctx.MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			
+			mywindow.document.write("Client Key =  0x"+ctx.MPIN.bytestostring(CK) + "<br>");    
+			H=ctx.MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			mywindow.document.write("Server Key =  0x"+ctx.MPIN.bytestostring(SK) + "<br>");    
+		}
+	}
+
+}
+
+
+
+// BLS24 context
+function bls24() {
+	var ctx = new CTX('BLS24');
+	mywindow=window.open();
+
+	mywindow.document.write("<br> BLS24 Pairing-Friendly Curve "+  "<br>");
+
+	var i,res;
+	var result;
+
+	var EGS=ctx.MPIN192.EGS;
+	var EFS=ctx.MPIN192.EFS;
+	var EAS=ctx.ECP.AESKEY;
+
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var G1S=2*EFS+1; /* Group 1 Size */
+	var G2S=8*EFS; /* Group 2 Size */   /**/
+
+	var S=[];
+	var SST=[];
+	var TOKEN = [];
+	var PERMIT = [];
+	var SEC = [];
+	var xID = [];
+	var xCID = [];
+	var X= [];
+	var Y= [];
+	var E=[];
+	var F=[];
+	var HCID=[];
+	var HID=[];
+	var HTID=[];
+
+	var G1=[];
+	var G2=[];
+	var R=[];
+	var Z=[];
+	var W=[];
+	var T=[];
+	var CK=[];
+	var SK=[];
+
+	var HSID=[];
+
+/* Set configuration */
+	var PERMITS=true;
+	var PINERROR=true;
+	var FULL=true;
+    var ONE_PASS=false;
+
+	var RAW=[];
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+/* Trusted Authority set-up */
+	ctx.MPIN192.RANDOM_GENERATE(rng,S);
+	mywindow.document.write("M-Pin Master Secret s: 0x"+ctx.MPIN192.bytestostring(S) + "<br>");
+ 
+ /* Create Client Identity */
+ 	var IDstr = "testUser@miracl.com";
+	var CLIENT_ID = ctx.MPIN192.stringtobytes(IDstr);  
+	HCID=ctx.MPIN192.HASH_ID(sha,CLIENT_ID);  /* Either Client or TA calculates Hash(ID) - you decide! */
+		
+	mywindow.document.write("Client ID= "+ctx.MPIN192.bytestostring(CLIENT_ID) + "<br>");
+
+/* Client and Server are issued secrets by DTA */
+	ctx.MPIN192.GET_SERVER_SECRET(S,SST);
+	mywindow.document.write("Server Secret SS: 0x"+ctx.MPIN192.bytestostring(SST) + "<br>");
+
+	ctx.MPIN192.GET_CLIENT_SECRET(S,HCID,TOKEN);
+	mywindow.document.write("Client Secret CS: 0x"+ctx.MPIN192.bytestostring(TOKEN) + "<br>");     
+	
+/* Client extracts PIN from secret to create Token */
+	var pin=1234;
+	mywindow.document.write("Client extracts PIN= "+pin + "<br>"); 
+	var rtn=ctx.MPIN192.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+	if (rtn != 0)
+		mywindow.document.write("Failed to extract PIN " + "<br>");  
+
+	mywindow.document.write("Client Token TK: 0x"+ctx.MPIN192.bytestostring(TOKEN) + "<br>");        
+
+	if (FULL)
+	{
+		ctx.MPIN192.PRECOMPUTE(TOKEN,HCID,G1,G2);
+	}
+
+	var date;
+	if (PERMITS)
+	{
+		date=ctx.MPIN192.today();
+/* Client gets "Time Token" permit from DTA */ 	
+		ctx.MPIN192.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+		mywindow.document.write("Time Permit TP: 0x"+ctx.MPIN192.bytestostring(PERMIT) + "<br>");   
+
+/* This encoding makes Time permit look random - Elligator squared */
+		ctx.MPIN192.ENCODING(rng,PERMIT);
+		mywindow.document.write("Encoded Time Permit TP: 0x"+ctx.MPIN192.bytestostring(PERMIT) + "<br>");   
+		ctx.MPIN192.DECODING(PERMIT);
+		mywindow.document.write("Decoded Time Permit TP: 0x"+ctx.MPIN192.bytestostring(PERMIT) + "<br>");   
+	}
+	else date=0;
+
+	pin=parseInt(mywindow.prompt("Enter PIN= "));
+
+/* Set date=0 and PERMIT=null if time permits not in use
+
+Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC
+If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H_T(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+If Time Permits OFF set xCID = null, HTID=null and use xID and HID only
+If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required
+If Time permits are ON, AND pin error detection is NOT required, set xID=null, HID=null and use xCID and HTID only.
+
+
+*/
+	var pxID=xID;
+	var pxCID=xCID;
+	var pHID=HID;
+	var pHTID=HTID;
+	var pE=E;
+	var pF=F;
+	var pPERMIT=PERMIT;
+	var prHID;
+
+	if (date!=0)
+	{
+		prHID=pHTID;
+		if (!PINERROR)
+		{
+			pxID=null;
+			//	pHID=null;
+		}
+	}
+	else
+	{
+		prHID=pHID;
+		pPERMIT=null;
+		pxCID=null;
+		pHTID=null;
+	}
+	if (!PINERROR)
+	{
+		pE=null;
+		pF=null;
+	}
+
+	if (ONE_PASS)
+	{
+		mywindow.document.write("MPIN Single Pass " + "<br>");   
+		timeValue = ctx.MPIN192.GET_TIME();
+		mywindow.document.write("Epoch " + timeValue + "<br>");   
+
+		rtn=ctx.MPIN192.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+
+		if (rtn != 0)
+		mywindow.document.write("FAILURE: CLIENT rtn: " + rtn + "<br>");   
+
+		if (FULL)
+		{
+			HCID=ctx.MPIN192.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN192.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+		}
+
+		rtn=ctx.MPIN192.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER rtn: " + rtn+ "<br>");  
+
+		if (FULL)
+		{
+			HSID=ctx.MPIN192.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN192.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+		}
+	}
+	else 
+	{
+		mywindow.document.write("MPIN Multi Pass " + "<br>");   
+		rtn=ctx.MPIN192.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_1 rtn: " + rtn + "<br>");   
+  
+		if (FULL)
+		{
+			HCID=ctx.MPIN192.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN192.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+		}
+    
+  /* Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. */
+		ctx.MPIN192.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+    
+  /* Server generates Random number Y and sends it to Client */
+		ctx.MPIN192.RANDOM_GENERATE(rng,Y);
+    
+		if (FULL)
+		{
+			HSID=ctx.MPIN192.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN192.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+		}
+    
+  /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */
+		rtn=ctx.MPIN192.CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_2 rtn: " + rtn + "<br>");  
+  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+  /* If PIN error not required, set E and F = NULL */
+		rtn=ctx.MPIN192.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+    
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER_2 rtn: " + rtn+ "<br>");  
+    
+	}
+    		  
+
+	if (rtn == ctx.MPIN192.BAD_PIN)
+	{
+		mywindow.document.write("Server says - Bad Pin. I don't know you. Feck off." + "<br>"); 
+		if (PINERROR)
+		{
+			var err=ctx.MPIN192.KANGAROO(E,F);
+			if (err!=0) mywindow.document.write("(Client PIN is out by "+err + ")<br>");
+		}
+	}
+	else 
+	{
+		mywindow.document.write("Server says - PIN is good! You really are "+IDstr + "<br>"); 
+		if (FULL)
+		{
+			H=ctx.MPIN192.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN192.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			
+			mywindow.document.write("Client Key =  0x"+ctx.MPIN192.bytestostring(CK) + "<br>");    
+			H=ctx.MPIN192.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN192.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			mywindow.document.write("Server Key =  0x"+ctx.MPIN192.bytestostring(SK) + "<br>");    
+		}
+	}
+
+} 
+
+// BLS48 context
+function bls48() {
+	var ctx = new CTX('BLS48');
+	mywindow=window.open();
+
+	mywindow.document.write("<br> BLS48 Pairing-Friendly Curve "+  "<br>");
+
+	var i,res;
+	var result;
+
+	var EGS=ctx.MPIN256.EGS;
+	var EFS=ctx.MPIN256.EFS;
+	var EAS=ctx.ECP.AESKEY;
+
+	var sha=ctx.ECP.HASH_TYPE;
+
+	var G1S=2*EFS+1; // Group 1 Size 
+	var G2S=16*EFS; // Group 2 Size    **
+
+	var S=[];
+	var SST=[];
+	var TOKEN = [];
+	var PERMIT = [];
+	var SEC = [];
+	var xID = [];
+	var xCID = [];
+	var X= [];
+	var Y= [];
+	var E=[];
+	var F=[];
+	var HCID=[];
+	var HID=[];
+	var HTID=[];
+
+	var G1=[];
+	var G2=[];
+	var R=[];
+	var Z=[];
+	var W=[];
+	var T=[];
+	var CK=[];
+	var SK=[];
+
+	var HSID=[];
+
+// Set configuration 
+	var PERMITS=true;
+	var PINERROR=true;
+	var FULL=true;
+    var ONE_PASS=false;
+
+	var RAW=[];
+	var rng=new ctx.RAND();
+
+	rng.clean();
+	for (i=0;i<100;i++) RAW[i]=i;
+
+	rng.seed(100,RAW);
+
+// Trusted Authority set-up 
+	ctx.MPIN256.RANDOM_GENERATE(rng,S);
+
+	mywindow.document.write("M-Pin Master Secret s: 0x"+ctx.MPIN256.bytestostring(S) + "<br>");
+ // Create Client Identity 
+ 	var IDstr = "testUser@miracl.com";
+	var CLIENT_ID = ctx.MPIN256.stringtobytes(IDstr);  
+	HCID=ctx.MPIN256.HASH_ID(sha,CLIENT_ID);  // Either Client or TA calculates Hash(ID) - you decide! 
+		
+	mywindow.document.write("Client ID= "+ctx.MPIN256.bytestostring(CLIENT_ID) + "<br>");
+
+// Client and Server are issued secrets by DTA 
+	ctx.MPIN256.GET_SERVER_SECRET(S,SST);
+	mywindow.document.write("Server Secret SS: 0x"+ctx.MPIN256.bytestostring(SST) + "<br>");
+
+	ctx.MPIN256.GET_CLIENT_SECRET(S,HCID,TOKEN);
+	mywindow.document.write("Client Secret CS: 0x"+ctx.MPIN256.bytestostring(TOKEN) + "<br>");     
+	
+// Client extracts PIN from secret to create Token 
+	var pin=1234;
+	mywindow.document.write("Client extracts PIN= "+pin + "<br>"); 
+	var rtn=ctx.MPIN256.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+	if (rtn != 0)
+		mywindow.document.write("Failed to extract PIN " + "<br>");  
+
+	mywindow.document.write("Client Token TK: 0x"+ctx.MPIN256.bytestostring(TOKEN) + "<br>");        
+
+	if (FULL)
+	{
+		ctx.MPIN256.PRECOMPUTE(TOKEN,HCID,G1,G2);
+	}
+
+	var date;
+	if (PERMITS)
+	{
+		date=ctx.MPIN256.today();
+// Client gets "Time Token" permit from DTA  	
+		ctx.MPIN256.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+		mywindow.document.write("Time Permit TP: 0x"+ctx.MPIN256.bytestostring(PERMIT) + "<br>");   
+
+// This encoding makes Time permit look random - Elligator squared 
+		ctx.MPIN256.ENCODING(rng,PERMIT);
+		mywindow.document.write("Encoded Time Permit TP: 0x"+ctx.MPIN256.bytestostring(PERMIT) + "<br>");   
+		ctx.MPIN256.DECODING(PERMIT);
+		mywindow.document.write("Decoded Time Permit TP: 0x"+ctx.MPIN256.bytestostring(PERMIT) + "<br>");   
+	}
+	else date=0;
+
+	pin=parseInt(mywindow.prompt("Enter PIN= "));
+
+// Set date=0 and PERMIT=null if time permits not in use
+
+//Client First pass: Inputs CLIENT_ID, optional RNG, pin, TOKEN and PERMIT. Output xID = x.H(CLIENT_ID) and re-combined secret SEC
+//If PERMITS are is use, then date!=0 and PERMIT is added to secret and xCID = x.(H(CLIENT_ID)+H_T(date|H(CLIENT_ID)))
+//Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+//If Time Permits OFF set xCID = null, HTID=null and use xID and HID only
+//If Time permits are ON, AND pin error detection is required then all of xID, xCID, HID and HTID are required
+//If Time permits are ON, AND pin error detection is NOT required, set xID=null, HID=null and use xCID and HTID only.
+
+
+	var pxID=xID;
+	var pxCID=xCID;
+	var pHID=HID;
+	var pHTID=HTID;
+	var pE=E;
+	var pF=F;
+	var pPERMIT=PERMIT;
+	var prHID;
+
+	if (date!=0)
+	{
+		prHID=pHTID;
+		if (!PINERROR)
+		{
+			pxID=null;
+			//	pHID=null;
+		}
+	}
+	else
+	{
+		prHID=pHID;
+		pPERMIT=null;
+		pxCID=null;
+		pHTID=null;
+	}
+	if (!PINERROR)
+	{
+		pE=null;
+		pF=null;
+	}
+
+	if (ONE_PASS)
+	{
+		mywindow.document.write("MPIN Single Pass " + "<br>");   
+		timeValue = ctx.MPIN256.GET_TIME();
+		mywindow.document.write("Epoch " + timeValue + "<br>");   
+
+		rtn=ctx.MPIN256.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+
+		if (rtn != 0)
+		mywindow.document.write("FAILURE: CLIENT rtn: " + rtn + "<br>");   
+
+		if (FULL)
+		{
+			HCID=ctx.MPIN256.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN256.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  // Also Send Z=r.ID to Server, remember random r 
+		}
+
+		rtn=ctx.MPIN256.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER rtn: " + rtn+ "<br>");  
+
+		if (FULL)
+		{
+			HSID=ctx.MPIN256.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN256.GET_G1_MULTIPLE(rng,0,W,prHID,T);  // Also send T=w.ID to client, remember random w  
+		}
+	}
+	else 
+	{
+		mywindow.document.write("MPIN Multi Pass " + "<br>");   
+		rtn=ctx.MPIN256.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_1 rtn: " + rtn + "<br>");   
+  
+		if (FULL)
+		{
+			HCID=ctx.MPIN256.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN256.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  // Also Send Z=r.ID to Server, remember random r 
+		}
+    
+  // Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), and maps them to points on the curve HID and HTID resp. 
+		ctx.MPIN256.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+    
+  // Server generates Random number Y and sends it to Client 
+		ctx.MPIN256.RANDOM_GENERATE(rng,Y);
+    
+		if (FULL)
+		{
+			HSID=ctx.MPIN256.HASH_ID(sha,CLIENT_ID);
+			ctx.MPIN256.GET_G1_MULTIPLE(rng,0,W,prHID,T);  // Also send T=w.ID to client, remember random w  
+		}
+    
+  // Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC 
+		rtn=ctx.MPIN256.CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: CLIENT_2 rtn: " + rtn + "<br>");  
+  // Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. 
+  // If PIN error not required, set E and F = NULL 
+		rtn=ctx.MPIN256.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+    
+		if (rtn != 0)
+			mywindow.document.write("FAILURE: SERVER_2 rtn: " + rtn+ "<br>");  
+    
+	}
+    		  
+
+	if (rtn == ctx.MPIN256.BAD_PIN)
+	{
+		mywindow.document.write("Server says - Bad Pin. I don't know you. Feck off." + "<br>"); 
+		if (PINERROR)
+		{
+			var err=ctx.MPIN256.KANGAROO(E,F);
+			if (err!=0) mywindow.document.write("(Client PIN is out by "+err + ")<br>");
+		}
+	}
+	else 
+	{
+		mywindow.document.write("Server says - PIN is good! You really are "+IDstr + "<br>"); 
+		if (FULL)
+		{
+			H=ctx.MPIN256.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN256.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			
+			mywindow.document.write("Client Key =  0x"+ctx.MPIN256.bytestostring(CK) + "<br>");    
+			H=ctx.MPIN256.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T);
+			ctx.MPIN256.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			mywindow.document.write("Server Key =  0x"+ctx.MPIN256.bytestostring(SK) + "<br>");    
+		}
+	}
+
+}
+
+</script>
+</body>
+</html>
diff --git a/examples/node/example_DVS_BLS383.js b/examples/node/example_DVS_BLS381.js
similarity index 99%
rename from examples/node/example_DVS_BLS383.js
rename to examples/node/example_DVS_BLS381.js
index d407427..416892c 100644
--- a/examples/node/example_DVS_BLS383.js
+++ b/examples/node/example_DVS_BLS381.js
@@ -21,7 +21,7 @@ under the License.
 
 var CTX = require("../../index");
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 var RAW = [];
 var rng = new ctx.RAND();
diff --git a/examples/node/example_ECC_BLS383_NIST521.js b/examples/node/example_ECC_BLS381_NIST521.js
similarity index 98%
rename from examples/node/example_ECC_BLS383_NIST521.js
rename to examples/node/example_ECC_BLS381_NIST521.js
index 6a5e82f..9849b78 100644
--- a/examples/node/example_ECC_BLS383_NIST521.js
+++ b/examples/node/example_ECC_BLS381_NIST521.js
@@ -22,10 +22,10 @@ under the License.
 
 var CTX = require("../../index");
 
-var ctx1 = new CTX("BLS383");
+var ctx1 = new CTX("BLS381");
 var ctx2 = new CTX("NIST521");
 
-console.log("Start testing BLS383");
+console.log("Start testing BLS381");
 
 var pp = "M0ng00se",
     res,
diff --git a/examples/node/example_MPIN_BLS383.js b/examples/node/example_MPIN_BLS381.js
similarity index 99%
rename from examples/node/example_MPIN_BLS383.js
rename to examples/node/example_MPIN_BLS381.js
index 14d7fe5..11e2b78 100644
--- a/examples/node/example_MPIN_BLS383.js
+++ b/examples/node/example_MPIN_BLS381.js
@@ -21,7 +21,7 @@ under the License.
 
 var CTX = require("../../index");
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/node/example_MPIN_FULL_BLS383.js b/examples/node/example_MPIN_FULL_BLS381.js
similarity index 99%
rename from examples/node/example_MPIN_FULL_BLS383.js
rename to examples/node/example_MPIN_FULL_BLS381.js
index c7f37df..0e9f9a3 100644
--- a/examples/node/example_MPIN_FULL_BLS383.js
+++ b/examples/node/example_MPIN_FULL_BLS381.js
@@ -21,7 +21,7 @@ under the License.
 
 var CTX = require("../../index");
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */
 
diff --git a/examples/node/example_MPIN_ONE_PASS_BLS383.js b/examples/node/example_MPIN_ONE_PASS_BLS381.js
similarity index 99%
rename from examples/node/example_MPIN_ONE_PASS_BLS383.js
rename to examples/node/example_MPIN_ONE_PASS_BLS381.js
index 112b868..9de9ba6 100644
--- a/examples/node/example_MPIN_ONE_PASS_BLS383.js
+++ b/examples/node/example_MPIN_ONE_PASS_BLS381.js
@@ -21,7 +21,7 @@ under the License.
 
 var CTX = require("../../index");
 
-var ctx = new CTX("BLS383");
+var ctx = new CTX("BLS381");
 
 /* Test M-Pin */