diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e66e791
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.war
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
+# Ignore gradle build
+build/
+.gradle
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f51ea63
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: java
+
+jdk:
+  - oraclejdk8
+
+script:
+  - ./gradlew clean build test --stacktrace --info
+
+after_success:
+  - if [ "$TRAVIS_JDK_VERSION" = "oraclejdk8" ]; then ./gradlew jacocoTestReport coveralls; fi;
diff --git a/AMCL.pdf b/AMCL.pdf
new file mode 100644
index 0000000..e4fa685
--- /dev/null
+++ b/AMCL.pdf
Binary files differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f9a77cd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2018 MIRACL UK Ltd
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..803fab8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,74 @@
+# MCJL - *Milagro Crypto Java Library*
+
+[![Master Branch](https://img.shields.io/badge/-master:-gray.svg)](https://github.com/milagro-crypto/milagro-crypto-java/tree/master)
+[![Master Build Status](https://secure.travis-ci.org/milagro-crypto/milagro-crypto-java.png?branch=master)](https://travis-ci.org/milagro-crypto/milagro-crypto-java?branch=master)
+[![Master Coverage Status](https://coveralls.io/repos/github/milagro-crypto/milagro-crypto-java/badge.svg?branch=master)](https://coveralls.io/github/milagro-crypto/milagro-crypto-java?branch=master)
+
+* **category**:    Library
+* **copyright**:   2018 The Apache Software Foundation
+* **license**:     ASL 2.0 ([Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0))
+* **link**:        https://github.com/milagro-crypto/milagro-crypto-java
+* **introduction**: [AMCL.pdf](AMCL.pdf)
+
+
+## Description
+
+*MCJL - Milagro Crypto Java Library*
+
+* MCJL is a standards compliant JavaScript cryptographic library with no external dependencies except for the random seed source.
+
+* MCJL is a refactor of the *Java* code of [AMCL](https://github.com/milagro-crypto/amcl). For a detailed explanation about this library please read: [AMCL.pdf](AMCL.pdf). 
+
+* MCJL supports the standards for RSA, ECDH, ECIES, ECDSA and M-PIN, AES-GCM encryption/decryption, SHA256, SHA384, SHA512 and SHA3 hash functions and a cryptographically secure random number generator. Furthermore we recently added New Hope, a post-quantum key exchange.
+
+This library is created from the Java code in this directory 
+[ACML](https://github.com/milagro-crypto/amcl/tree/master/version3/java) 
+project. The config64.py script has been run in this AMCL directory and all 
+the curves and RSA security level were selected for a 64-bit build; the output
+Java files from this process are used in this project. If you require a 
+smaller JAR file please follow the instructions in the AMCL project.
+
+## Software Dependencies
+
+In order to build this library, the following packages are required:
+
+* [gradle](https://gradle.org/)
+
+## Setup
+This library is avaiable on Maven Central.
+
+Replace `VERSION` below with required version.
+
+To use `MCJL` with Maven project, use:
+```
+<dependency>
+  <groupId>org.miracl.milagro.amcl</groupId>
+  <artifactId>milagro-crypto-java</artifactId>
+  <version>VERSION</version>
+</dependency>
+```
+
+For Gradle project:
+```
+dependencies {
+   compile 'org.miracl.milagro.amcl:milagro-crypto-java:VERSION'
+}
+```
+
+Fill the `gradle.properties` file if you want to upload on Maven Central.
+
+`MCJL` needs Java 8.
+
+## Local Installation
+
+Use this command to compile library and install it as artifact to local Maven 
+repository.
+
+    ./gradlew clean build publishToMavenLocal --stacktrace --info
+
+## Contributions
+
+Contributions are very welcome. Please make pull requests to the develop 
+branch. You can run this command to build and test the code.
+
+    ./gradlew build
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..1d0ba9e
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+0.4.0
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..31bf75b
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,104 @@
+buildscript {
+    repositories {
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1'
+    }
+}
+
+plugins {
+    id 'java-library'
+    id 'jacoco'
+    id 'com.github.kt3k.coveralls' version '2.6.3'
+    id 'io.codearte.nexus-staging' version '0.11.0'
+}
+
+apply plugin: 'java'
+apply plugin: 'maven-publish'
+apply plugin: 'com.bmuschko.nexus'
+
+nexusStaging {
+    packageGroup = "org.miracl"
+}
+
+publishing {
+    publications {
+        mavenJava(MavenPublication) {
+            artifactId 'milagro-crypto-java'
+            groupId 'org.miracl.milagro.amcl'
+            version '0.4.0'
+            from components.java
+        }
+    }
+
+    repositories {
+        maven {
+            // change to point to your repo, e.g. http://my.org/repo
+            url "$buildDir/repo"
+        }
+    }
+}
+
+
+dependencies {
+    // This dependency is exported to consumers, that is to say found on their compile classpath.
+    api 'org.apache.commons:commons-math3:3.6.1'
+
+    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
+    implementation 'com.google.guava:guava:23.0'
+
+    // Use JUnit test framework
+    testImplementation 'junit:junit:4.12'
+}
+
+// In this section you declare where to find the dependencies of your project
+repositories {
+    jcenter()
+}
+
+jacocoTestReport {
+    reports {
+        xml.enabled = true
+        html.enabled = true
+    }
+}
+
+archivesBaseName = 'milagro-crypto-java'
+group = "org.miracl.milagro.amcl"
+version = "0.4.0"
+modifyPom {
+    project {
+        name 'milagro-crypto-java'
+        description 'MCJL - Milagro Crypto Java Library'
+        url 'https://github.com/milagro-crypto/milagro-crypto-java'
+        inceptionYear '2018'
+        scm {
+            url 'https://bitbucket.org/objdict/objjson'
+            connection 'scm:https://github.com/milagro-crypto/milagro-crypto-java.git'
+            developerConnection 'scm:git://github.com/milagro-crypto/milagro-crypto-java.git'
+        }
+        licenses {
+            license {
+                name 'The Apache Software License, Version 2.0'
+                url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
+                distribution 'repo'
+            }
+        }
+        developers {
+            developer {
+                email 'support@miracl.com'
+            }
+        }
+    }
+}
+extraArchive {
+    sources = true
+    tests = true
+    javadoc = true
+}
+nexus {
+    sign = true
+    repositoryUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
+    snapshotRepositoryUrl = 'https://oss.sonatype.org/content/repositories/snapshots/'
+}
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..a666450
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,11 @@
+# Examples
+
+These are two examples programs that require the library to be built before 
+they can be run. These are adapted from the tests for the BN254CX curve.
+Replace `VERSION` below with required version.
+
+    javac -classpath .:../build/libs/milagro-crypto-java-VERSION.jar  TestMPIN.java
+    java -classpath .:../build/libs/milagro-crypto-java-VERSION.jar  TestMPIN
+
+    javac -classpath .:../build/libs/milagro-crypto-java-VERSION.jar  TestECC.java
+    java -classpath .:../build/libs/milagro-crypto-java-VERSION.jar  TestECC
diff --git a/examples/TestECC.java b/examples/TestECC.java
new file mode 100644
index 0000000..100c086
--- /dev/null
+++ b/examples/TestECC.java
@@ -0,0 +1,174 @@
+﻿/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* ECDH/ECIES/ECDSA example for BN254CX curve */
+
+import org.apache.milagro.amcl.BN254CX.*;
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECC {
+    private static void printBinary(byte[] array) {
+        int i;
+        for (i = 0; i < array.length; i++) {
+            System.out.printf("%02x", array[i]);
+        }
+        System.out.println();
+    }
+
+    public static void main(String[] args) {
+        byte[] RAW = new byte[100];
+        RAND rng = new RAND();
+        int i, j = 0, res;
+        int result;
+        String pp = new String("M0ng00se");
+
+        rng.clean();
+        for (i = 0; i < 100; i++) RAW[i] = (byte)(i);
+        rng.seed(100, RAW);
+
+        int EGS = ECDH.EGS;
+        int EFS = ECDH.EFS;
+        int EAS = AES.KS;
+        int sha = ECDH.HASH_TYPE;
+
+        byte[] S1 = new byte[EGS];
+        byte[] W0 = new byte[2 * EFS + 1];
+        byte[] W1 = new byte[2 * EFS + 1];
+        byte[] Z0 = new byte[EFS];
+        byte[] Z1 = new byte[EFS];
+
+        byte[] SALT = new byte[8];
+        byte[] P1 = new byte[3];
+        byte[] P2 = new byte[4];
+        byte[] V = new byte[2 * EFS + 1];
+        byte[] M = new byte[17];
+        byte[] T = new byte[12];
+        byte[] CS = new byte[EGS];
+        byte[] DS = new byte[EGS];
+
+        for (i = 0; i < 8; i++) SALT[i] = (byte)(i + 1); // set Salt
+
+        System.out.println("Testing ECDH code");
+        System.out.println("Alice's Passphrase= " + pp);
+        byte[] PW = pp.getBytes();
+
+        /* private key S0 of size EGS bytes derived from Password and Salt */
+
+        byte[] S0 = ECDH.PBKDF2(sha, PW, SALT, 1000, EGS);
+
+        System.out.print("Alice's private key= 0x");
+        printBinary(S0);
+
+        /* Generate Key pair S/W */
+        ECDH.KEY_PAIR_GENERATE(null, S0, W0);
+
+        System.out.print("Alice's public key= 0x");
+        printBinary(W0);
+
+        res = ECDH.PUBLIC_KEY_VALIDATE(W0);
+        if (res != 0) {
+            System.out.println("ECP Public Key is invalid!");
+        }
+        /* Random private key for other party */
+        ECDH.KEY_PAIR_GENERATE(rng, S1, W1);
+
+        System.out.print("Servers private key= 0x");
+        printBinary(S1);
+
+        System.out.print("Servers public key= 0x");
+        printBinary(W1);
+
+
+        res = ECDH.PUBLIC_KEY_VALIDATE(W1);
+        if (res != 0) {
+            System.out.println("ECP Public Key is invalid!");
+        }
+
+        /* Calculate common key using DH - IEEE 1363 method */
+
+        ECDH.SVDP_DH(S0, W1, Z0);
+        ECDH.SVDP_DH(S1, W0, Z1);
+
+        boolean same = true;
+        for (i = 0; i < EFS; i++)
+            if (Z0[i] != Z1[i]) same = false;
+
+        if (!same) {
+            System.out.println("*** ECPSVDP-DH Failed");
+        }
+
+        byte[] KEY = ECDH.KDF2(sha, Z0, null, EAS);
+
+        System.out.print("Alice's DH Key=  0x");
+        printBinary(KEY);
+        System.out.print("Servers DH Key=  0x");
+        printBinary(KEY);
+
+        if (ECP.CURVETYPE != ECP.MONTGOMERY) {
+            System.out.println("Testing ECIES");
+
+            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] = (byte) i;
+
+            byte[] C = ECDH.ECIES_ENCRYPT(sha, P1, P2, rng, W1, M, V, T);
+
+            System.out.println("Ciphertext= ");
+            System.out.print("V= 0x");
+            printBinary(V);
+            System.out.print("C= 0x");
+            printBinary(C);
+            System.out.print("T= 0x");
+            printBinary(T);
+
+
+            M = ECDH.ECIES_DECRYPT(sha, P1, P2, V, C, T, S1);
+            if (M.length == 0) {
+                System.out.println("*** ECIES Decryption Failed");
+            } else System.out.println("Decryption succeeded");
+
+            System.out.print("Message is 0x");
+            printBinary(M);
+
+            System.out.println("Testing ECDSA");
+
+            if (ECDH.SP_DSA(sha, rng, S0, M, CS, DS) != 0) {
+                System.out.println("***ECDSA Signature Failed");
+            }
+            System.out.println("Signature= ");
+            System.out.print("C= 0x");
+            printBinary(CS);
+            System.out.print("D= 0x");
+            printBinary(DS);
+
+            if (ECDH.VP_DSA(sha, W0, M, CS, DS) != 0) {
+                System.out.println("***ECDSA Verification Failed");
+            } else System.out.println("ECDSA Signature/Verification succeeded " + j);
+            System.out.println("");
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/examples/TestMPIN.java b/examples/TestMPIN.java
new file mode 100644
index 0000000..e5d7afc
--- /dev/null
+++ b/examples/TestMPIN.java
@@ -0,0 +1,267 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN example for BN254CX curve */
+import org.apache.milagro.amcl.BN254CX.*;
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN {
+
+    static boolean PERMITS = true;
+    static boolean PINERROR = true;
+    static boolean FULL = true;
+    static boolean SINGLE_PASS = false;
+
+    static void printBinary(byte[] array) {
+        int i;
+        for (i = 0; i < array.length; i++) {
+            System.out.printf("%02x", array[i]);
+        }
+        System.out.println();
+    }
+
+
+    public static void main(String[] args) {
+        RAND rng = new RAND();
+        int EGS = MPIN.EGS;
+        int EFS = MPIN.EFS;
+        int G1S = 2 * EFS + 1; /* Group 1 Size */
+        int G2S = 4 * EFS; /* Group 2 Size */
+        int EAS = 16;
+
+        int sha = MPIN.HASH_TYPE;
+
+        byte[] S = new byte[EGS];
+        byte[] SST = new byte[G2S];
+        byte[] TOKEN = new byte[G1S];
+        byte[] PERMIT = new byte[G1S];
+        byte[] SEC = new byte[G1S];
+        byte[] xID = new byte[G1S];
+        byte[] xCID = new byte[G1S];
+        byte[] X = new byte[EGS];
+        byte[] Y = new byte[EGS];
+        byte[] E = new byte[12 * EFS];
+        byte[] F = new byte[12 * EFS];
+        byte[] HID = new byte[G1S];
+        byte[] HTID = new byte[G1S];
+
+        byte[] G1 = new byte[12 * EFS];
+        byte[] G2 = new byte[12 * EFS];
+        byte[] R = new byte[EGS];
+        byte[] Z = new byte[G1S];
+        byte[] W = new byte[EGS];
+        byte[] T = new byte[G1S];
+        byte[] CK = new byte[EAS];
+        byte[] SK = new byte[EAS];
+
+        byte[] HSID = null;
+        byte[] RAW = new byte[100];
+
+        rng.clean();
+        for (int i = 0; i < 100; i++) RAW[i] = (byte)(i);
+        rng.seed(100, RAW);
+
+        System.out.println("Testing MPIN code");
+
+        /* Trusted Authority set-up */
+
+        MPIN.RANDOM_GENERATE(rng, S);
+        System.out.print("Master Secret s: 0x");
+        printBinary(S);
+
+        /* Create Client Identity */
+        String IDstr = "testUser@miracl.com";
+        byte[] CLIENT_ID = IDstr.getBytes();
+
+        byte[] HCID = MPIN.HASH_ID(sha, CLIENT_ID, EFS); /* Either Client or TA calculates Hash(ID) - you decide! */
+
+        System.out.print("Client ID Hash= ");
+        printBinary(HCID);
+        System.out.print("Client ID= ");
+        printBinary(CLIENT_ID);
+
+        /* Client and Server are issued secrets by DTA */
+
+        MPIN.GET_CLIENT_SECRET(S, HCID, TOKEN);
+        System.out.print("Client Secret CS: 0x");
+        printBinary(TOKEN);
+
+        MPIN.GET_SERVER_SECRET(S, SST);
+        System.out.print("Server Secret SS: 0x");
+        printBinary(SST);
+
+
+        /* Client extracts PIN from secret to create Token */
+        int pin = 1234;
+        System.out.println("Client extracts PIN= " + pin);
+        int rtn = MPIN.EXTRACT_PIN(sha, CLIENT_ID, pin, TOKEN);
+        if (rtn != 0)
+            System.out.println("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+        System.out.print("Client Token TK: 0x");
+        printBinary(TOKEN);
+
+        if (FULL) {
+            MPIN.PRECOMPUTE(TOKEN, HCID, G1, G2);
+        }
+        int date;
+        if (PERMITS) {
+            date = MPIN.today();
+            /* Client gets "Time Token" permit from DTA */
+            MPIN.GET_CLIENT_PERMIT(sha, date, S, HCID, PERMIT);
+            System.out.print("Time Permit TP: 0x");
+            printBinary(PERMIT);
+
+            /* This encoding makes Time permit look random - Elligator squared */
+            MPIN.ENCODING(rng, PERMIT);
+            System.out.print("Encoded Time Permit TP: 0x");
+            printBinary(PERMIT);
+            MPIN.DECODING(PERMIT);
+            System.out.print("Decoded Time Permit TP: 0x");
+            printBinary(PERMIT);
+        } else date = 0;
+
+        //		System.out.print("\nPIN= ");
+        //		Scanner scan=new Scanner(System.in);
+        //		pin=scan.nextInt();
+
+        pin = 1234;
+
+        /* 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(date|H(CLIENT_ID)))
+        Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+        IMPORTANT: To save space and time..
+        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.
+
+
+        */
+
+        byte[] pxID = xID;
+        byte[] pxCID = xCID;
+        byte[] pHID = HID;
+        byte[] pHTID = HTID;
+        byte[] pE = E;
+        byte[] pF = F;
+        byte[] pPERMIT = PERMIT;
+        byte[] prHID;
+
+        if (date != 0) {
+
+            prHID = pHTID;
+            if (!PINERROR) {
+                pxID = null;
+                //		pHID=null;  // new
+            }
+        } else {
+            prHID = pHID;
+            pPERMIT = null;
+            pxCID = null;
+            pHTID = null;
+        }
+        if (!PINERROR) {
+            pE = null;
+            pF = null;
+        }
+
+        if (SINGLE_PASS) {
+            System.out.println("MPIN Single Pass");
+            int timeValue = MPIN.GET_TIME();
+            rtn = MPIN.CLIENT(sha, date, CLIENT_ID, rng, X, pin, TOKEN, SEC, pxID, pxCID, pPERMIT, timeValue, Y);
+            if (rtn != 0)
+                System.out.println("FAILURE: CLIENT rtn: " + rtn);
+
+            if (FULL) {
+                HCID = MPIN.HASH_ID(sha, CLIENT_ID, EFS);
+                MPIN.GET_G1_MULTIPLE(rng, 1, R, HCID, Z); /* Also Send Z=r.ID to Server, remember random r */
+            }
+
+            rtn = MPIN.SERVER(sha, date, pHID, pHTID, Y, SST, pxID, pxCID, SEC, pE, pF, CLIENT_ID, timeValue);
+            if (rtn != 0)
+                System.out.println("FAILURE: SERVER rtn: " + rtn);
+
+            if (FULL) {
+                HSID = MPIN.HASH_ID(sha, CLIENT_ID, EFS);
+                MPIN.GET_G1_MULTIPLE(rng, 0, W, prHID, T); /* Also send T=w.ID to client, remember random w  */
+            }
+        } else {
+            System.out.println("MPIN Multi Pass");
+            /* Send U=x.ID to server, and recreate secret from token and pin */
+            rtn = MPIN.CLIENT_1(sha, date, CLIENT_ID, rng, X, pin, TOKEN, SEC, pxID, pxCID, pPERMIT);
+            if (rtn != 0)
+                System.out.println("FAILURE: CLIENT_1 rtn: " + rtn);
+
+            if (FULL) {
+                HCID = MPIN.HASH_ID(sha, CLIENT_ID, EFS);
+                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. */
+            MPIN.SERVER_1(sha, date, CLIENT_ID, pHID, pHTID);
+
+            /* Server generates Random number Y and sends it to Client */
+            MPIN.RANDOM_GENERATE(rng, Y);
+
+            if (FULL) {
+                HSID = MPIN.HASH_ID(sha, CLIENT_ID, EFS);
+                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 = MPIN.CLIENT_2(X, Y, SEC);
+            if (rtn != 0)
+                System.out.println("FAILURE: CLIENT_2 rtn: " + rtn);
+
+            /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+            /* If PIN error not required, set E and F = null */
+
+            rtn = MPIN.SERVER_2(date, pHID, pHTID, Y, SST, pxID, pxCID, SEC, pE, pF);
+
+            if (rtn != 0)
+                System.out.println("FAILURE: SERVER_2 rtn: " + rtn);
+        }
+
+        if (rtn == MPIN.BAD_PIN) {
+            if (PINERROR) {
+                int err = MPIN.KANGAROO(E, F);
+                if (err != 0) System.out.println("Client PIN is out by " + err);
+                else System.out.println("Server says - Bad Pin. I don't know you");
+            } else System.out.println("Server says - Bad Pin. I don't know you");
+
+        } else System.out.println("Server says - PIN is good! You really are " + IDstr);
+
+
+        if (FULL) {
+            byte[] H = MPIN.HASH_ALL(sha, HCID, pxID, pxCID, SEC, Y, Z, T, EFS);
+            MPIN.CLIENT_KEY(sha, G1, G2, pin, R, X, H, T, CK);
+            System.out.print("Client Key =  0x");
+            printBinary(CK);
+
+            H = MPIN.HASH_ALL(sha, HSID, pxID, pxCID, SEC, Y, Z, T, EFS);
+            MPIN.SERVER_KEY(sha, Z, SST, W, H, pHID, pxID, pxCID, SK);
+            System.out.print("Server Key =  0x");
+            printBinary(SK);
+        }
+        System.out.println("");
+    }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..60aa7da
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,6 @@
+#remove '#' and fill following fields:
+#nexusUsername=YOUR_SONATYPE_USER_NAME
+#nexusPassword=YOUR_SONATYPE_USER_PASSWORD
+#signing.keyId=KEY_ID
+#signing.password=KEY_PASSWORD
+#signing.secretKeyRingFile=/PATH/TO/SECRET/RING/FILE
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..a5fe1cb
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..be280be
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..f84f2cf
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,18 @@
+/*
+ * This settings file was generated by the Gradle 'init' task.
+ *
+ * The settings file is used to specify which projects to include in your build.
+ * In a single project build this file can be empty or even removed.
+ *
+ * Detailed information about configuring a multi-project build in Gradle can be found
+ * in the user guide at https://docs.gradle.org/3.3/userguide/multi_project_builds.html
+ */
+
+/*
+// To declare projects as part of a multi-project build use the 'include' method
+include 'shared'
+include 'api'
+include 'services:webservice'
+*/
+
+rootProject.name = 'milagro-crypto-java'
diff --git a/src/main/java/org/apache/milagro/amcl/AES.java b/src/main/java/org/apache/milagro/amcl/AES.java
new file mode 100644
index 0000000..35d04dc
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/AES.java
@@ -0,0 +1,695 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+
+/* AES Encryption */ 
+package org.apache.milagro.amcl;
+
+public class AES {
+	int Nk,Nr;
+	int mode;
+	private int[] fkey=new int[60];
+	private int[] rkey=new int[60];
+	public byte[] f=new byte[16];
+
+
+	public static final int ECB=0;
+	public static final int CBC=1;
+	public static final int CFB1=2;
+	public static final int CFB2=3;
+	public static final int CFB4=5;
+	public static final int OFB1=14;
+	public static final int OFB2=15;
+	public static final int OFB4=17;
+	public static final int OFB8=21;
+	public static final int OFB16=29;
+	public static final int CTR1=30;
+	public static final int CTR2=31;
+	public static final int CTR4=33; 
+	public static final int CTR8=37; 
+	public static final int CTR16=45; 
+
+	private static final byte[] InCo={(byte)0xB,(byte)0xD,(byte)0x9,(byte)0xE};  /* Inverse Coefficients */
+
+	public static final int KS=16; /* Key Size in bytes */
+	public static final int BS=16; /* Block Size */
+
+	private static final byte[] ptab=
+	{(byte)1,(byte)3,(byte)5,(byte)15,(byte)17,(byte)51,(byte)85,(byte)255,(byte)26,(byte)46,(byte)114,(byte)150,(byte)161,(byte)248,(byte)19,(byte)53,
+	(byte)95,(byte)225,(byte)56,(byte)72,(byte)216,(byte)115,(byte)149,(byte)164,(byte)247,(byte)2,(byte)6,(byte)10,(byte)30,(byte)34,(byte)102,(byte)170,
+	(byte)229,(byte)52,(byte)92,(byte)228,(byte)55,(byte)89,(byte)235,(byte)38,(byte)106,(byte)190,(byte)217,(byte)112,(byte)144,(byte)171,(byte)230,(byte)49,
+	(byte)83,(byte)245,(byte)4,(byte)12,(byte)20,(byte)60,(byte)68,(byte)204,(byte)79,(byte)209,(byte)104,(byte)184,(byte)211,(byte)110,(byte)178,(byte)205,
+	(byte)76,(byte)212,(byte)103,(byte)169,(byte)224,(byte)59,(byte)77,(byte)215,(byte)98,(byte)166,(byte)241,(byte)8,(byte)24,(byte)40,(byte)120,(byte)136,
+	(byte)131,(byte)158,(byte)185,(byte)208,(byte)107,(byte)189,(byte)220,(byte)127,(byte)129,(byte)152,(byte)179,(byte)206,(byte)73,(byte)219,(byte)118,(byte)154,
+	(byte)181,(byte)196,(byte)87,(byte)249,(byte)16,(byte)48,(byte)80,(byte)240,(byte)11,(byte)29,(byte)39,(byte)105,(byte)187,(byte)214,(byte)97,(byte)163,
+	(byte)254,(byte)25,(byte)43,(byte)125,(byte)135,(byte)146,(byte)173,(byte)236,(byte)47,(byte)113,(byte)147,(byte)174,(byte)233,(byte)32,(byte)96,(byte)160,
+	(byte)251,(byte)22,(byte)58,(byte)78,(byte)210,(byte)109,(byte)183,(byte)194,(byte)93,(byte)231,(byte)50,(byte)86,(byte)250,(byte)21,(byte)63,(byte)65,
+	(byte)195,(byte)94,(byte)226,(byte)61,(byte)71,(byte)201,(byte)64,(byte)192,(byte)91,(byte)237,(byte)44,(byte)116,(byte)156,(byte)191,(byte)218,(byte)117,
+	(byte)159,(byte)186,(byte)213,(byte)100,(byte)172,(byte)239,(byte)42,(byte)126,(byte)130,(byte)157,(byte)188,(byte)223,(byte)122,(byte)142,(byte)137,(byte)128,
+	(byte)155,(byte)182,(byte)193,(byte)88,(byte)232,(byte)35,(byte)101,(byte)175,(byte)234,(byte)37,(byte)111,(byte)177,(byte)200,(byte)67,(byte)197,(byte)84,
+	(byte)252,(byte)31,(byte)33,(byte)99,(byte)165,(byte)244,(byte)7,(byte)9,(byte)27,(byte)45,(byte)119,(byte)153,(byte)176,(byte)203,(byte)70,(byte)202,
+	(byte)69,(byte)207,(byte)74,(byte)222,(byte)121,(byte)139,(byte)134,(byte)145,(byte)168,(byte)227,(byte)62,(byte)66,(byte)198,(byte)81,(byte)243,(byte)14,
+	(byte)18,(byte)54,(byte)90,(byte)238,(byte)41,(byte)123,(byte)141,(byte)140,(byte)143,(byte)138,(byte)133,(byte)148,(byte)167,(byte)242,(byte)13,(byte)23,
+	(byte)57,(byte)75,(byte)221,(byte)124,(byte)132,(byte)151,(byte)162,(byte)253,(byte)28,(byte)36,(byte)108,(byte)180,(byte)199,(byte)82,(byte)246,(byte)1};
+
+	private static final byte[] ltab=
+	{(byte)0,(byte)255,(byte)25,(byte)1,(byte)50,(byte)2,(byte)26,(byte)198,(byte)75,(byte)199,(byte)27,(byte)104,(byte)51,(byte)238,(byte)223,(byte)3,
+	(byte)100,(byte)4,(byte)224,(byte)14,(byte)52,(byte)141,(byte)129,(byte)239,(byte)76,(byte)113,(byte)8,(byte)200,(byte)248,(byte)105,(byte)28,(byte)193,
+	(byte)125,(byte)194,(byte)29,(byte)181,(byte)249,(byte)185,(byte)39,(byte)106,(byte)77,(byte)228,(byte)166,(byte)114,(byte)154,(byte)201,(byte)9,(byte)120,
+	(byte)101,(byte)47,(byte)138,(byte)5,(byte)33,(byte)15,(byte)225,(byte)36,(byte)18,(byte)240,(byte)130,(byte)69,(byte)53,(byte)147,(byte)218,(byte)142,
+	(byte)150,(byte)143,(byte)219,(byte)189,(byte)54,(byte)208,(byte)206,(byte)148,(byte)19,(byte)92,(byte)210,(byte)241,(byte)64,(byte)70,(byte)131,(byte)56,
+	(byte)102,(byte)221,(byte)253,(byte)48,(byte)191,(byte)6,(byte)139,(byte)98,(byte)179,(byte)37,(byte)226,(byte)152,(byte)34,(byte)136,(byte)145,(byte)16,
+	(byte)126,(byte)110,(byte)72,(byte)195,(byte)163,(byte)182,(byte)30,(byte)66,(byte)58,(byte)107,(byte)40,(byte)84,(byte)250,(byte)133,(byte)61,(byte)186,
+	(byte)43,(byte)121,(byte)10,(byte)21,(byte)155,(byte)159,(byte)94,(byte)202,(byte)78,(byte)212,(byte)172,(byte)229,(byte)243,(byte)115,(byte)167,(byte)87,
+	(byte)175,(byte)88,(byte)168,(byte)80,(byte)244,(byte)234,(byte)214,(byte)116,(byte)79,(byte)174,(byte)233,(byte)213,(byte)231,(byte)230,(byte)173,(byte)232,
+	(byte)44,(byte)215,(byte)117,(byte)122,(byte)235,(byte)22,(byte)11,(byte)245,(byte)89,(byte)203,(byte)95,(byte)176,(byte)156,(byte)169,(byte)81,(byte)160,
+	(byte)127,(byte)12,(byte)246,(byte)111,(byte)23,(byte)196,(byte)73,(byte)236,(byte)216,(byte)67,(byte)31,(byte)45,(byte)164,(byte)118,(byte)123,(byte)183,
+	(byte)204,(byte)187,(byte)62,(byte)90,(byte)251,(byte)96,(byte)177,(byte)134,(byte)59,(byte)82,(byte)161,(byte)108,(byte)170,(byte)85,(byte)41,(byte)157,
+	(byte)151,(byte)178,(byte)135,(byte)144,(byte)97,(byte)190,(byte)220,(byte)252,(byte)188,(byte)149,(byte)207,(byte)205,(byte)55,(byte)63,(byte)91,(byte)209,
+	(byte)83,(byte)57,(byte)132,(byte)60,(byte)65,(byte)162,(byte)109,(byte)71,(byte)20,(byte)42,(byte)158,(byte)93,(byte)86,(byte)242,(byte)211,(byte)171,
+	(byte)68,(byte)17,(byte)146,(byte)217,(byte)35,(byte)32,(byte)46,(byte)137,(byte)180,(byte)124,(byte)184,(byte)38,(byte)119,(byte)153,(byte)227,(byte)165,
+	(byte)103,(byte)74,(byte)237,(byte)222,(byte)197,(byte)49,(byte)254,(byte)24,(byte)13,(byte)99,(byte)140,(byte)128,(byte)192,(byte)247,(byte)112,(byte)7};
+
+	private static final byte[] fbsub=
+	{(byte)99,(byte)124,(byte)119,(byte)123,(byte)242,(byte)107,(byte)111,(byte)197,(byte)48,(byte)1,(byte)103,(byte)43,(byte)254,(byte)215,(byte)171,(byte)118,
+	(byte)202,(byte)130,(byte)201,(byte)125,(byte)250,(byte)89,(byte)71,(byte)240,(byte)173,(byte)212,(byte)162,(byte)175,(byte)156,(byte)164,(byte)114,(byte)192,
+	(byte)183,(byte)253,(byte)147,(byte)38,(byte)54,(byte)63,(byte)247,(byte)204,(byte)52,(byte)165,(byte)229,(byte)241,(byte)113,(byte)216,(byte)49,(byte)21,
+	(byte)4,(byte)199,(byte)35,(byte)195,(byte)24,(byte)150,(byte)5,(byte)154,(byte)7,(byte)18,(byte)128,(byte)226,(byte)235,(byte)39,(byte)178,(byte)117,
+	(byte)9,(byte)131,(byte)44,(byte)26,(byte)27,(byte)110,(byte)90,(byte)160,(byte)82,(byte)59,(byte)214,(byte)179,(byte)41,(byte)227,(byte)47,(byte)132,
+	(byte)83,(byte)209,(byte)0,(byte)237,(byte)32,(byte)252,(byte)177,(byte)91,(byte)106,(byte)203,(byte)190,(byte)57,(byte)74,(byte)76,(byte)88,(byte)207,
+	(byte)208,(byte)239,(byte)170,(byte)251,(byte)67,(byte)77,(byte)51,(byte)133,(byte)69,(byte)249,(byte)2,(byte)127,(byte)80,(byte)60,(byte)159,(byte)168,
+	(byte)81,(byte)163,(byte)64,(byte)143,(byte)146,(byte)157,(byte)56,(byte)245,(byte)188,(byte)182,(byte)218,(byte)33,(byte)16,(byte)255,(byte)243,(byte)210,
+	(byte)205,(byte)12,(byte)19,(byte)236,(byte)95,(byte)151,(byte)68,(byte)23,(byte)196,(byte)167,(byte)126,(byte)61,(byte)100,(byte)93,(byte)25,(byte)115,
+	(byte)96,(byte)129,(byte)79,(byte)220,(byte)34,(byte)42,(byte)144,(byte)136,(byte)70,(byte)238,(byte)184,(byte)20,(byte)222,(byte)94,(byte)11,(byte)219,
+	(byte)224,(byte)50,(byte)58,(byte)10,(byte)73,(byte)6,(byte)36,(byte)92,(byte)194,(byte)211,(byte)172,(byte)98,(byte)145,(byte)149,(byte)228,(byte)121,
+	(byte)231,(byte)200,(byte)55,(byte)109,(byte)141,(byte)213,(byte)78,(byte)169,(byte)108,(byte)86,(byte)244,(byte)234,(byte)101,(byte)122,(byte)174,(byte)8,
+	(byte)186,(byte)120,(byte)37,(byte)46,(byte)28,(byte)166,(byte)180,(byte)198,(byte)232,(byte)221,(byte)116,(byte)31,(byte)75,(byte)189,(byte)139,(byte)138,
+	(byte)112,(byte)62,(byte)181,(byte)102,(byte)72,(byte)3,(byte)246,(byte)14,(byte)97,(byte)53,(byte)87,(byte)185,(byte)134,(byte)193,(byte)29,(byte)158,
+	(byte)225,(byte)248,(byte)152,(byte)17,(byte)105,(byte)217,(byte)142,(byte)148,(byte)155,(byte)30,(byte)135,(byte)233,(byte)206,(byte)85,(byte)40,(byte)223,
+	(byte)140,(byte)161,(byte)137,(byte)13,(byte)191,(byte)230,(byte)66,(byte)104,(byte)65,(byte)153,(byte)45,(byte)15,(byte)176,(byte)84,(byte)187,(byte)22};
+
+	private static final byte[] rbsub=
+	{(byte)82,(byte)9,(byte)106,(byte)213,(byte)48,(byte)54,(byte)165,(byte)56,(byte)191,(byte)64,(byte)163,(byte)158,(byte)129,(byte)243,(byte)215,(byte)251,
+	(byte)124,(byte)227,(byte)57,(byte)130,(byte)155,(byte)47,(byte)255,(byte)135,(byte)52,(byte)142,(byte)67,(byte)68,(byte)196,(byte)222,(byte)233,(byte)203,
+	(byte)84,(byte)123,(byte)148,(byte)50,(byte)166,(byte)194,(byte)35,(byte)61,(byte)238,(byte)76,(byte)149,(byte)11,(byte)66,(byte)250,(byte)195,(byte)78,
+	(byte)8,(byte)46,(byte)161,(byte)102,(byte)40,(byte)217,(byte)36,(byte)178,(byte)118,(byte)91,(byte)162,(byte)73,(byte)109,(byte)139,(byte)209,(byte)37,
+	(byte)114,(byte)248,(byte)246,(byte)100,(byte)134,(byte)104,(byte)152,(byte)22,(byte)212,(byte)164,(byte)92,(byte)204,(byte)93,(byte)101,(byte)182,(byte)146,
+	(byte)108,(byte)112,(byte)72,(byte)80,(byte)253,(byte)237,(byte)185,(byte)218,(byte)94,(byte)21,(byte)70,(byte)87,(byte)167,(byte)141,(byte)157,(byte)132,
+	(byte)144,(byte)216,(byte)171,(byte)0,(byte)140,(byte)188,(byte)211,(byte)10,(byte)247,(byte)228,(byte)88,(byte)5,(byte)184,(byte)179,(byte)69,(byte)6,
+	(byte)208,(byte)44,(byte)30,(byte)143,(byte)202,(byte)63,(byte)15,(byte)2,(byte)193,(byte)175,(byte)189,(byte)3,(byte)1,(byte)19,(byte)138,(byte)107,
+	(byte)58,(byte)145,(byte)17,(byte)65,(byte)79,(byte)103,(byte)220,(byte)234,(byte)151,(byte)242,(byte)207,(byte)206,(byte)240,(byte)180,(byte)230,(byte)115,
+	(byte)150,(byte)172,(byte)116,(byte)34,(byte)231,(byte)173,(byte)53,(byte)133,(byte)226,(byte)249,(byte)55,(byte)232,(byte)28,(byte)117,(byte)223,(byte)110,
+	(byte)71,(byte)241,(byte)26,(byte)113,(byte)29,(byte)41,(byte)197,(byte)137,(byte)111,(byte)183,(byte)98,(byte)14,(byte)170,(byte)24,(byte)190,(byte)27,
+	(byte)252,(byte)86,(byte)62,(byte)75,(byte)198,(byte)210,(byte)121,(byte)32,(byte)154,(byte)219,(byte)192,(byte)254,(byte)120,(byte)205,(byte)90,(byte)244,
+	(byte)31,(byte)221,(byte)168,(byte)51,(byte)136,(byte)7,(byte)199,(byte)49,(byte)177,(byte)18,(byte)16,(byte)89,(byte)39,(byte)128,(byte)236,(byte)95,
+	(byte)96,(byte)81,(byte)127,(byte)169,(byte)25,(byte)181,(byte)74,(byte)13,(byte)45,(byte)229,(byte)122,(byte)159,(byte)147,(byte)201,(byte)156,(byte)239,
+	(byte)160,(byte)224,(byte)59,(byte)77,(byte)174,(byte)42,(byte)245,(byte)176,(byte)200,(byte)235,(byte)187,(byte)60,(byte)131,(byte)83,(byte)153,(byte)97,
+	(byte)23,(byte)43,(byte)4,(byte)126,(byte)186,(byte)119,(byte)214,(byte)38,(byte)225,(byte)105,(byte)20,(byte)99,(byte)85,(byte)33,(byte)12,(byte)125};
+
+	private static final byte[] rco=
+	{(byte)1,(byte)2,(byte)4,(byte)8,(byte)16,(byte)32,(byte)64,(byte)128,(byte)27,(byte)54,(byte)108,(byte)216,(byte)171,(byte)77,(byte)154,(byte)47};
+
+	private static final int[] ftable=
+	{0xa56363c6,0x847c7cf8,0x997777ee,0x8d7b7bf6,0xdf2f2ff,0xbd6b6bd6,
+	0xb16f6fde,0x54c5c591,0x50303060,0x3010102,0xa96767ce,0x7d2b2b56,
+	0x19fefee7,0x62d7d7b5,0xe6abab4d,0x9a7676ec,0x45caca8f,0x9d82821f,
+	0x40c9c989,0x877d7dfa,0x15fafaef,0xeb5959b2,0xc947478e,0xbf0f0fb,
+	0xecadad41,0x67d4d4b3,0xfda2a25f,0xeaafaf45,0xbf9c9c23,0xf7a4a453,
+	0x967272e4,0x5bc0c09b,0xc2b7b775,0x1cfdfde1,0xae93933d,0x6a26264c,
+	0x5a36366c,0x413f3f7e,0x2f7f7f5,0x4fcccc83,0x5c343468,0xf4a5a551,
+	0x34e5e5d1,0x8f1f1f9,0x937171e2,0x73d8d8ab,0x53313162,0x3f15152a,
+	0xc040408,0x52c7c795,0x65232346,0x5ec3c39d,0x28181830,0xa1969637,
+	0xf05050a,0xb59a9a2f,0x907070e,0x36121224,0x9b80801b,0x3de2e2df,
+	0x26ebebcd,0x6927274e,0xcdb2b27f,0x9f7575ea,0x1b090912,0x9e83831d,
+	0x742c2c58,0x2e1a1a34,0x2d1b1b36,0xb26e6edc,0xee5a5ab4,0xfba0a05b,
+	0xf65252a4,0x4d3b3b76,0x61d6d6b7,0xceb3b37d,0x7b292952,0x3ee3e3dd,
+	0x712f2f5e,0x97848413,0xf55353a6,0x68d1d1b9,0x0,0x2cededc1,
+	0x60202040,0x1ffcfce3,0xc8b1b179,0xed5b5bb6,0xbe6a6ad4,0x46cbcb8d,
+	0xd9bebe67,0x4b393972,0xde4a4a94,0xd44c4c98,0xe85858b0,0x4acfcf85,
+	0x6bd0d0bb,0x2aefefc5,0xe5aaaa4f,0x16fbfbed,0xc5434386,0xd74d4d9a,
+	0x55333366,0x94858511,0xcf45458a,0x10f9f9e9,0x6020204,0x817f7ffe,
+	0xf05050a0,0x443c3c78,0xba9f9f25,0xe3a8a84b,0xf35151a2,0xfea3a35d,
+	0xc0404080,0x8a8f8f05,0xad92923f,0xbc9d9d21,0x48383870,0x4f5f5f1,
+	0xdfbcbc63,0xc1b6b677,0x75dadaaf,0x63212142,0x30101020,0x1affffe5,
+	0xef3f3fd,0x6dd2d2bf,0x4ccdcd81,0x140c0c18,0x35131326,0x2fececc3,
+	0xe15f5fbe,0xa2979735,0xcc444488,0x3917172e,0x57c4c493,0xf2a7a755,
+	0x827e7efc,0x473d3d7a,0xac6464c8,0xe75d5dba,0x2b191932,0x957373e6,
+	0xa06060c0,0x98818119,0xd14f4f9e,0x7fdcdca3,0x66222244,0x7e2a2a54,
+	0xab90903b,0x8388880b,0xca46468c,0x29eeeec7,0xd3b8b86b,0x3c141428,
+	0x79dedea7,0xe25e5ebc,0x1d0b0b16,0x76dbdbad,0x3be0e0db,0x56323264,
+	0x4e3a3a74,0x1e0a0a14,0xdb494992,0xa06060c,0x6c242448,0xe45c5cb8,
+	0x5dc2c29f,0x6ed3d3bd,0xefacac43,0xa66262c4,0xa8919139,0xa4959531,
+	0x37e4e4d3,0x8b7979f2,0x32e7e7d5,0x43c8c88b,0x5937376e,0xb76d6dda,
+	0x8c8d8d01,0x64d5d5b1,0xd24e4e9c,0xe0a9a949,0xb46c6cd8,0xfa5656ac,
+	0x7f4f4f3,0x25eaeacf,0xaf6565ca,0x8e7a7af4,0xe9aeae47,0x18080810,
+	0xd5baba6f,0x887878f0,0x6f25254a,0x722e2e5c,0x241c1c38,0xf1a6a657,
+	0xc7b4b473,0x51c6c697,0x23e8e8cb,0x7cdddda1,0x9c7474e8,0x211f1f3e,
+	0xdd4b4b96,0xdcbdbd61,0x868b8b0d,0x858a8a0f,0x907070e0,0x423e3e7c,
+	0xc4b5b571,0xaa6666cc,0xd8484890,0x5030306,0x1f6f6f7,0x120e0e1c,
+	0xa36161c2,0x5f35356a,0xf95757ae,0xd0b9b969,0x91868617,0x58c1c199,
+	0x271d1d3a,0xb99e9e27,0x38e1e1d9,0x13f8f8eb,0xb398982b,0x33111122,
+	0xbb6969d2,0x70d9d9a9,0x898e8e07,0xa7949433,0xb69b9b2d,0x221e1e3c,
+	0x92878715,0x20e9e9c9,0x49cece87,0xff5555aa,0x78282850,0x7adfdfa5,
+	0x8f8c8c03,0xf8a1a159,0x80898909,0x170d0d1a,0xdabfbf65,0x31e6e6d7,
+	0xc6424284,0xb86868d0,0xc3414182,0xb0999929,0x772d2d5a,0x110f0f1e,
+	0xcbb0b07b,0xfc5454a8,0xd6bbbb6d,0x3a16162c};
+
+	private static final int[] rtable=
+	{0x50a7f451,0x5365417e,0xc3a4171a,0x965e273a,0xcb6bab3b,0xf1459d1f,
+	0xab58faac,0x9303e34b,0x55fa3020,0xf66d76ad,0x9176cc88,0x254c02f5,
+	0xfcd7e54f,0xd7cb2ac5,0x80443526,0x8fa362b5,0x495ab1de,0x671bba25,
+	0x980eea45,0xe1c0fe5d,0x2752fc3,0x12f04c81,0xa397468d,0xc6f9d36b,
+	0xe75f8f03,0x959c9215,0xeb7a6dbf,0xda595295,0x2d83bed4,0xd3217458,
+	0x2969e049,0x44c8c98e,0x6a89c275,0x78798ef4,0x6b3e5899,0xdd71b927,
+	0xb64fe1be,0x17ad88f0,0x66ac20c9,0xb43ace7d,0x184adf63,0x82311ae5,
+	0x60335197,0x457f5362,0xe07764b1,0x84ae6bbb,0x1ca081fe,0x942b08f9,
+	0x58684870,0x19fd458f,0x876cde94,0xb7f87b52,0x23d373ab,0xe2024b72,
+	0x578f1fe3,0x2aab5566,0x728ebb2,0x3c2b52f,0x9a7bc586,0xa50837d3,
+	0xf2872830,0xb2a5bf23,0xba6a0302,0x5c8216ed,0x2b1ccf8a,0x92b479a7,
+	0xf0f207f3,0xa1e2694e,0xcdf4da65,0xd5be0506,0x1f6234d1,0x8afea6c4,
+	0x9d532e34,0xa055f3a2,0x32e18a05,0x75ebf6a4,0x39ec830b,0xaaef6040,
+	0x69f715e,0x51106ebd,0xf98a213e,0x3d06dd96,0xae053edd,0x46bde64d,
+	0xb58d5491,0x55dc471,0x6fd40604,0xff155060,0x24fb9819,0x97e9bdd6,
+	0xcc434089,0x779ed967,0xbd42e8b0,0x888b8907,0x385b19e7,0xdbeec879,
+	0x470a7ca1,0xe90f427c,0xc91e84f8,0x0,0x83868009,0x48ed2b32,
+	0xac70111e,0x4e725a6c,0xfbff0efd,0x5638850f,0x1ed5ae3d,0x27392d36,
+	0x64d90f0a,0x21a65c68,0xd1545b9b,0x3a2e3624,0xb1670a0c,0xfe75793,
+	0xd296eeb4,0x9e919b1b,0x4fc5c080,0xa220dc61,0x694b775a,0x161a121c,
+	0xaba93e2,0xe52aa0c0,0x43e0223c,0x1d171b12,0xb0d090e,0xadc78bf2,
+	0xb9a8b62d,0xc8a91e14,0x8519f157,0x4c0775af,0xbbdd99ee,0xfd607fa3,
+	0x9f2601f7,0xbcf5725c,0xc53b6644,0x347efb5b,0x7629438b,0xdcc623cb,
+	0x68fcedb6,0x63f1e4b8,0xcadc31d7,0x10856342,0x40229713,0x2011c684,
+	0x7d244a85,0xf83dbbd2,0x1132f9ae,0x6da129c7,0x4b2f9e1d,0xf330b2dc,
+	0xec52860d,0xd0e3c177,0x6c16b32b,0x99b970a9,0xfa489411,0x2264e947,
+	0xc48cfca8,0x1a3ff0a0,0xd82c7d56,0xef903322,0xc74e4987,0xc1d138d9,
+	0xfea2ca8c,0x360bd498,0xcf81f5a6,0x28de7aa5,0x268eb7da,0xa4bfad3f,
+	0xe49d3a2c,0xd927850,0x9bcc5f6a,0x62467e54,0xc2138df6,0xe8b8d890,
+	0x5ef7392e,0xf5afc382,0xbe805d9f,0x7c93d069,0xa92dd56f,0xb31225cf,
+	0x3b99acc8,0xa77d1810,0x6e639ce8,0x7bbb3bdb,0x97826cd,0xf418596e,
+	0x1b79aec,0xa89a4f83,0x656e95e6,0x7ee6ffaa,0x8cfbc21,0xe6e815ef,
+	0xd99be7ba,0xce366f4a,0xd4099fea,0xd67cb029,0xafb2a431,0x31233f2a,
+	0x3094a5c6,0xc066a235,0x37bc4e74,0xa6ca82fc,0xb0d090e0,0x15d8a733,
+	0x4a9804f1,0xf7daec41,0xe50cd7f,0x2ff69117,0x8dd64d76,0x4db0ef43,
+	0x544daacc,0xdf0496e4,0xe3b5d19e,0x1b886a4c,0xb81f2cc1,0x7f516546,
+	0x4ea5e9d,0x5d358c01,0x737487fa,0x2e410bfb,0x5a1d67b3,0x52d2db92,
+	0x335610e9,0x1347d66d,0x8c61d79a,0x7a0ca137,0x8e14f859,0x893c13eb,
+	0xee27a9ce,0x35c961b7,0xede51ce1,0x3cb1477a,0x59dfd29c,0x3f73f255,
+	0x79ce1418,0xbf37c773,0xeacdf753,0x5baafd5f,0x146f3ddf,0x86db4478,
+	0x81f3afca,0x3ec468b9,0x2c342438,0x5f40a3c2,0x72c31d16,0xc25e2bc,
+	0x8b493c28,0x41950dff,0x7101a839,0xdeb30c08,0x9ce4b4d8,0x90c15664,
+	0x6184cb7b,0x70b632d5,0x745c6c48,0x4257b8d0};
+
+
+/* Rotates 32-bit word left by 1, 2 or 3 byte  */
+
+	private static int ROTL8(int x)
+	{
+		return (((x)<<8)|((x)>>>24));
+	}
+
+	private static int ROTL16(int x)
+	{
+		return (((x)<<16)|((x)>>>16));
+	}
+
+	private static int ROTL24(int x)
+	{
+		return (((x)<<24)|((x)>>>8));
+	}
+
+	private static int pack(byte[] b)
+	{ /* pack bytes into a 32-bit Word */
+		return ((((int)b[3])&0xff)<<24)|(((int)b[2]&0xff)<<16)|(((int)b[1]&0xff)<<8)|((int)b[0]&0xff);
+	}
+
+	private static byte[] unpack(int a)
+	{ /* unpack bytes from a word */
+		byte [] b=new byte[4];
+		b[0]=(byte)(a);
+		b[1]=(byte)(a>>>8);
+		b[2]=(byte)(a>>>16);
+		b[3]=(byte)(a>>>24);
+		return b;
+	}
+
+	private static byte bmul(byte x,byte y)
+	{ /* x.y= AntiLog(Log(x) + Log(y)) */
+
+		int ix=((int)x)&0xff;
+		int iy=((int)y)&0xff;
+		int lx=((int)ltab[ix])&0xff;
+		int ly=((int)ltab[iy])&0xff;
+		if (x!=0 && y!=0) return ptab[(lx+ly)%255];
+		else return (byte)0;
+	}
+
+  //  if (x && y) 
+
+	private static int SubByte(int a)
+	{
+		byte [] b=unpack(a);
+		b[0]=fbsub[(int)b[0]&0xff];
+		b[1]=fbsub[(int)b[1]&0xff];
+		b[2]=fbsub[(int)b[2]&0xff];
+		b[3]=fbsub[(int)b[3]&0xff];
+		return pack(b);    
+	}
+
+	private static byte product(int x,int y)
+	{ /* dot product of two 4-byte arrays */
+		byte [] xb;//=new byte[4];
+		byte [] yb;//=new byte[4];
+		xb=unpack(x);
+		yb=unpack(y); 
+
+		return (byte)(bmul(xb[0],yb[0])^bmul(xb[1],yb[1])^bmul(xb[2],yb[2])^bmul(xb[3],yb[3]));
+	}
+
+	private static int InvMixCol(int x)
+	{ /* matrix Multiplication */
+		int y,m;
+		byte [] b=new byte[4];
+
+		m=pack(InCo);
+		b[3]=product(m,x);
+		m=ROTL24(m);
+		b[2]=product(m,x);
+		m=ROTL24(m);
+		b[1]=product(m,x);
+		m=ROTL24(m);
+		b[0]=product(m,x);
+		y=pack(b);
+		return y;
+	}
+
+	private static void increment(byte [] f)
+	{
+		int i;
+		for (i=0;i<16;i++)
+		{
+			f[i]++;
+			if (f[i]!=0) break;
+		}
+	}
+
+/* reset cipher */
+	public void reset(int m,byte[] iv)
+	{ /* reset mode, or reset iv */
+		mode=m;
+		for (int i=0;i<16;i++)
+			f[i]=0;
+		if (mode!=ECB && iv!=null)
+			for (int i=0;i<16;i++)
+				f[i]=iv[i];
+	}
+
+	public byte[] getreg()
+	{
+		byte [] ir=new byte[16];
+		for (int i=0;i<16;i++) ir[i]=f[i];
+		return ir;
+	}
+
+/* Initialise cipher */
+	public boolean init(int m,int nk,byte[] key,byte[] iv)
+	{	/* Key=16 bytes */
+		/* Key Scheduler. Create expanded encryption key */
+		int i,j,k,N,nr;
+		int [] CipherKey=new int[8];
+		byte [] b=new byte[4];
+		nk/=4;
+
+		if (nk!=4 && nk!=6 && nk!=8) return false;
+
+		nr=6+nk;
+
+		Nk=nk; Nr=nr;
+
+		reset(m,iv);
+		N=4*(nr+1);
+    
+		for (i=j=0;i<nk;i++,j+=4)
+		{
+			for (k=0;k<4;k++) b[k]=key[j+k];
+			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];
+		}
+
+ /* now for the expanded decrypt key in reverse order */
+
+		for (j=0;j<4;j++) rkey[j+N-4]=fkey[j]; 
+		for (i=4;i<N-4;i+=4)
+		{
+			k=N-4-i;
+			for (j=0;j<4;j++) rkey[k+j]=InvMixCol(fkey[i+j]);
+		}
+		for (j=N-4;j<N;j++) rkey[j-N+4]=fkey[j];
+		return true;
+	}
+
+/* Encrypt a single block */
+	public void ecb_encrypt(byte[] buff)
+	{
+		int i,j,k;
+		int t;
+    	byte [] b=new byte[4];
+    	int [] p=new int[4];
+    	int [] q=new int[4];
+
+		for (i=j=0;i<4;i++,j+=4)
+		{
+			for (k=0;k<4;k++) b[k]=buff[j+k];
+			p[i]=pack(b);
+			p[i]^=fkey[i];
+		}
+
+		k=4;
+
+/* State alternates between p and q */
+		for (i=1;i<Nr;i++)
+		{ 
+			q[0]=fkey[k]^ftable[p[0]&0xff]^
+				ROTL8(ftable[(p[1]>>>8)&0xff])^
+				ROTL16(ftable[(p[2]>>>16)&0xff])^
+				ROTL24(ftable[(p[3]>>>24)&0xff]);
+			q[1]=fkey[k+1]^ftable[p[1]&0xff]^
+				ROTL8(ftable[(p[2]>>>8)&0xff])^
+				ROTL16(ftable[(p[3]>>>16)&0xff])^
+				ROTL24(ftable[(p[0]>>>24)&0xff]);
+			q[2]=fkey[k+2]^ftable[p[2]&0xff]^
+				ROTL8(ftable[(p[3]>>>8)&0xff])^
+				ROTL16(ftable[(p[0]>>>16)&0xff])^
+				ROTL24(ftable[(p[1]>>>24)&0xff]);
+			q[3]=fkey[k+3]^ftable[p[3]&0xff]^
+				ROTL8(ftable[(p[0]>>>8)&0xff])^
+				ROTL16(ftable[(p[1]>>>16)&0xff])^
+				ROTL24(ftable[(p[2]>>>24)&0xff]);
+
+			k+=4;
+			for (j=0;j<4;j++)
+			{
+				t=p[j]; p[j]=q[j]; q[j]=t;
+			}
+		}
+
+/* Last Round */ 
+    
+		q[0]=fkey[k]^((int)fbsub[p[0]&0xff]&0xff)^
+			ROTL8((int)fbsub[(p[1]>>>8)&0xff]&0xff)^
+			ROTL16((int)fbsub[(p[2]>>>16)&0xff]&0xff)^
+			ROTL24((int)fbsub[(p[3]>>>24)&0xff]&0xff);
+
+		q[1]=fkey[k+1]^((int)fbsub[p[1]&0xff]&0xff)^
+			ROTL8((int)fbsub[(p[2]>>>8)&0xff]&0xff)^
+			ROTL16((int)fbsub[(p[3]>>>16)&0xff]&0xff)^
+			ROTL24((int)fbsub[(p[0]>>>24)&0xff]&0xff);
+
+		q[2]=fkey[k+2]^((int)fbsub[p[2]&0xff]&0xff)^
+			ROTL8((int)fbsub[(p[3]>>>8)&0xff]&0xff)^
+			ROTL16((int)fbsub[(p[0]>>>16)&0xff]&0xff)^
+			ROTL24((int)fbsub[(p[1]>>>24)&0xff]&0xff);
+
+		q[3]=fkey[k+3]^((int)fbsub[(p[3])&0xff]&0xff)^
+			ROTL8((int)fbsub[(p[0]>>>8)&0xff]&0xff)^
+			ROTL16((int)fbsub[(p[1]>>>16)&0xff]&0xff)^
+			ROTL24((int)fbsub[(p[2]>>>24)&0xff]&0xff);
+
+		for (i=j=0;i<4;i++,j+=4)
+		{
+			b=unpack(q[i]);
+			for (k=0;k<4;k++) buff[j+k]=b[k];
+		}
+	}
+
+/* Decrypt a single block */
+	public void ecb_decrypt(byte[] buff)
+	{
+		int i,j,k;
+		int t;
+    	byte [] b=new byte[4];
+    	int [] p=new int[4];
+    	int [] q=new int[4];
+
+		for (i=j=0;i<4;i++,j+=4)
+		{
+			for (k=0;k<4;k++) b[k]=buff[j+k];
+			p[i]=pack(b);
+			p[i]^=rkey[i];
+		}
+
+		k=4;
+
+/* State alternates between p and q */
+		for (i=1;i<Nr;i++)
+		{ 
+			q[0]=rkey[k]^rtable[p[0]&0xff]^
+				ROTL8(rtable[(p[3]>>>8)&0xff])^
+				ROTL16(rtable[(p[2]>>>16)&0xff])^
+				ROTL24(rtable[(p[1]>>>24)&0xff]);
+			q[1]=rkey[k+1]^rtable[p[1]&0xff]^
+				ROTL8(rtable[(p[0]>>>8)&0xff])^
+				ROTL16(rtable[(p[3]>>>16)&0xff])^
+				ROTL24(rtable[(p[2]>>>24)&0xff]);
+			q[2]=rkey[k+2]^rtable[p[2]&0xff]^
+				ROTL8(rtable[(p[1]>>>8)&0xff])^
+				ROTL16(rtable[(p[0]>>>16)&0xff])^
+				ROTL24(rtable[(p[3]>>>24)&0xff]);
+			q[3]=rkey[k+3]^rtable[p[3]&0xff]^
+				ROTL8(rtable[(p[2]>>>8)&0xff])^
+				ROTL16(rtable[(p[1]>>>16)&0xff])^
+				ROTL24(rtable[(p[0]>>>24)&0xff]);
+
+			k+=4;
+			for (j=0;j<4;j++)
+			{
+				t=p[j]; p[j]=q[j]; q[j]=t;
+			}
+		}
+
+/* Last Round */ 
+
+		q[0]=rkey[k]^((int)rbsub[p[0]&0xff]&0xff)^
+			ROTL8((int)rbsub[(p[3]>>>8)&0xff]&0xff)^
+			ROTL16((int)rbsub[(p[2]>>>16)&0xff]&0xff)^
+			ROTL24((int)rbsub[(p[1]>>>24)&0xff]&0xff);
+		q[1]=rkey[k+1]^((int)rbsub[p[1]&0xff]&0xff)^
+			ROTL8((int)rbsub[(p[0]>>>8)&0xff]&0xff)^
+			ROTL16((int)rbsub[(p[3]>>>16)&0xff]&0xff)^
+			ROTL24((int)rbsub[(p[2]>>>24)&0xff]&0xff);
+		q[2]=rkey[k+2]^((int)rbsub[p[2]&0xff]&0xff)^
+			ROTL8((int)rbsub[(p[1]>>>8)&0xff]&0xff)^
+			ROTL16((int)rbsub[(p[0]>>>16)&0xff]&0xff)^
+			ROTL24((int)rbsub[(p[3]>>>24)&0xff]&0xff);
+		q[3]=rkey[k+3]^((int)rbsub[p[3]&0xff]&0xff)^
+			ROTL8((int)rbsub[(p[2]>>>8)&0xff]&0xff)^
+			ROTL16((int)rbsub[(p[1]>>>16)&0xff]&0xff)^
+			ROTL24((int)rbsub[(p[0]>>>24)&0xff]&0xff);
+
+		for (i=j=0;i<4;i++,j+=4)
+		{
+			b=unpack(q[i]);
+			for (k=0;k<4;k++) buff[j+k]=b[k];
+		}
+
+	}
+
+/* Encrypt using selected mode of operation */
+	public int encrypt(byte[] buff)
+	{
+		int j,bytes;
+		byte[] st=new byte[16];
+		int fell_off;
+
+// Supported Modes of Operation 
+
+		fell_off=0;
+		switch (mode)
+		{
+		case ECB: 
+			ecb_encrypt(buff);
+			return 0;
+		case CBC:
+			for (j=0;j<16;j++) buff[j]^=f[j];
+			ecb_encrypt(buff);
+			for (j=0;j<16;j++) f[j]=buff[j];
+			return 0;
+
+		case CFB1:
+		case CFB2:
+		case CFB4:
+			bytes=mode-CFB1+1;
+			for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|f[j];
+			for (j=0;j<16;j++) st[j]=f[j];
+			for (j=bytes;j<16;j++) f[j-bytes]=f[j];
+			ecb_encrypt(st);
+			for (j=0;j<bytes;j++) 
+			{
+				buff[j]^=st[j];
+				f[16-bytes+j]=buff[j];
+			}
+			return fell_off;
+
+		case OFB1:
+		case OFB2:
+		case OFB4:
+		case OFB8:
+		case OFB16:
+
+			bytes=mode-OFB1+1;
+			ecb_encrypt(f);
+			for (j=0;j<bytes;j++) buff[j]^=f[j];
+			return 0;
+
+		case CTR1:
+		case CTR2:
+		case CTR4:
+		case CTR8:
+		case CTR16:
+
+			bytes=mode-CTR1+1;
+			for (j=0;j<16;j++) st[j]=f[j];
+			ecb_encrypt(st);
+			for (j=0;j<bytes;j++) buff[j]^=st[j];
+			increment(f);
+
+    default:
+			return 0;
+		}
+	}
+
+/* Decrypt using selected mode of operation */
+	public int decrypt(byte[] buff)
+	{
+		int j,bytes;
+		byte[] st=new byte[16];
+		int fell_off;
+
+   // Supported modes of operation 
+		fell_off=0;
+		switch (mode)
+		{
+		case ECB:
+			ecb_decrypt(buff);
+			return 0;
+		case CBC:
+			for (j=0;j<16;j++) 
+			{
+				st[j]=f[j];
+				f[j]=buff[j];
+			}
+			ecb_decrypt(buff);
+			for (j=0;j<16;j++)
+			{	 
+				buff[j]^=st[j];
+				st[j]=0;
+			}
+			return 0;
+		case CFB1:
+		case CFB2:
+		case CFB4:
+			bytes=mode-CFB1+1;
+			for (j=0;j<bytes;j++) fell_off=(fell_off<<8)|f[j];
+			for (j=0;j<16;j++) st[j]=f[j];
+			for (j=bytes;j<16;j++) f[j-bytes]=f[j];
+			ecb_encrypt(st);
+			for (j=0;j<bytes;j++)
+			{
+				f[16-bytes+j]=buff[j];
+				buff[j]^=st[j];
+			}
+			return fell_off;
+		case OFB1:
+		case OFB2:
+		case OFB4:
+		case OFB8:
+		case OFB16:
+			bytes=mode-OFB1+1;
+			ecb_encrypt(f);
+			for (j=0;j<bytes;j++) buff[j]^=f[j];
+			return 0;
+
+		case CTR1:
+		case CTR2:
+		case CTR4:
+		case CTR8:
+		case CTR16:
+
+			bytes=mode-CTR1+1;
+			for (j=0;j<16;j++) st[j]=f[j];
+			ecb_encrypt(st);
+			for (j=0;j<bytes;j++) buff[j]^=st[j];
+			increment(f);
+ 
+		default:
+			return 0;
+		}
+	}
+
+/* Clean up and delete left-overs */
+	public void end()
+	{ // clean up 
+		int i;
+		for (i=0;i<4*(Nr+1);i++)
+			fkey[i]=rkey[i]=0;
+		for (i=0;i<16;i++)
+			f[i]=0;
+	}
+
+	public static void main(String[] args) {
+		int i;
+
+		byte[] key=new byte[32];
+		byte[] block=new byte[16];
+		byte[] iv=new byte[16];
+
+		for (i=0;i<32;i++) key[i]=0;
+		key[0]=1;
+		for (i=0;i<16;i++) iv[i]=(byte)i;
+		for (i=0;i<16;i++) block[i]=(byte)i;
+
+		AES a=new AES();
+
+		a.init(CTR16,32,key,iv);
+		System.out.println("Plain= "); 
+		for (i=0;i<16;i++)  System.out.format("%02X ", block[i]&0xff);
+		System.out.println(""); 
+
+		a.encrypt(block);
+
+		System.out.println("Encrypt= "); 
+		for (i=0;i<16;i++)  System.out.format("%02X ", block[i]&0xff);
+		System.out.println(""); 
+
+		a.reset(CTR16,iv);
+		a.decrypt(block);
+
+		System.out.println("Decrypt= "); 
+		for (i=0;i<16;i++)  System.out.format("%02X ", block[i]&0xff);
+		System.out.println(""); 
+
+		a.end();
+
+	} 
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/BIG.java b/src/main/java/org/apache/milagro/amcl/ANSSI/BIG.java
new file mode 100644
index 0000000..ef3f9fa
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.ANSSI;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/DBIG.java b/src/main/java/org/apache/milagro/amcl/ANSSI/DBIG.java
new file mode 100644
index 0000000..4ca545a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.ANSSI;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/ECDH.java b/src/main/java/org/apache/milagro/amcl/ANSSI/ECDH.java
new file mode 100644
index 0000000..ec1311c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.ANSSI;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/ECP.java b/src/main/java/org/apache/milagro/amcl/ANSSI/ECP.java
new file mode 100644
index 0000000..694fbad
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.ANSSI;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/FP.java b/src/main/java/org/apache/milagro/amcl/ANSSI/FP.java
new file mode 100644
index 0000000..a28ab41
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.ANSSI;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ANSSI/ROM.java b/src/main/java/org/apache/milagro/amcl/ANSSI/ROM.java
new file mode 100644
index 0000000..5f0510f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ANSSI/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.ANSSI;
+
+public class ROM
+{
+
+// Base Bits= 56
+	public static final long[] Modulus= {0xFCF353D86E9C03L,0xADBCABC8CA6DE8L,0xE8CE42435B3961L,0xB3AD58F10126DL,0xF1FD178CL};
+	public static final long[] R2modp= {0x18D2374288CC9CL,0x4929E67646BD2BL,0x220E6C1D6F7F2DL,0x751B1FDABCE02EL,0xE7401B78L};
+	public static final long MConst= 0x97483A164E1155L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 0;
+	public static final long[] CURVE_B= {0x75ED967B7BB73FL,0xC9AE4B1A18030L,0x754A44C00FDFECL,0x5428A9300D4ABAL,0xEE353FCAL};
+	public static final long[] CURVE_Order= {0xFDD459C6D655E1L,0x67E140D2BF941FL,0xE8CE42435B53DCL,0xB3AD58F10126DL,0xF1FD178CL};
+	public static final long[] CURVE_Gx= {0xC97A2DD98F5CFFL,0xD2DCAF98B70164L,0x4749D423958C27L,0x56C139EB31183DL,0xB6B3D4C3L};
+	public static final long[] CURVE_Gy= {0x115A1554062CFBL,0xC307E8E4C9E183L,0xF0F3ECEF8C2701L,0xC8B204911F9271L,0x6142E0F7L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/BIG.java b/src/main/java/org/apache/milagro/amcl/BLS24/BIG.java
new file mode 100644
index 0000000..df34ec3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BLS24;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=60; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/DBIG.java b/src/main/java/org/apache/milagro/amcl/BLS24/DBIG.java
new file mode 100644
index 0000000..3e2c9f0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BLS24;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/ECDH.java b/src/main/java/org/apache/milagro/amcl/BLS24/ECDH.java
new file mode 100644
index 0000000..b0b19cd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BLS24;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/ECP.java b/src/main/java/org/apache/milagro/amcl/BLS24/ECP.java
new file mode 100644
index 0000000..b5b5839
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BLS;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=POSITIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=48;
+	public static final int AESKEY=24;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/ECP4.java b/src/main/java/org/apache/milagro/amcl/BLS24/ECP4.java
new file mode 100644
index 0000000..e0205cb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/ECP4.java
@@ -0,0 +1,768 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP4 */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class ECP4 {
+	private FP4 x;
+	private FP4 y;
+	private FP4 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP4() {
+//		INF=true;
+		x=new FP4(0);
+		y=new FP4(1);
+		z=new FP4(0);
+	}
+
+    public ECP4(ECP4 e) {
+        this.x = new FP4(e.x);
+        this.y = new FP4(e.y);
+        this.z = new FP4(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP4 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP4 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+//		boolean bd;
+//		if (d==0) bd=false;
+//		else bd=true;
+//		INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP4 W[],int b)
+	{
+		ECP4 MP=new ECP4(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP4 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP4 a=new FP4(x);                            // *****
+		FP4 b=new FP4(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP4 one=new FP4(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+
+/* extract affine x as FP4 */
+	public FP4 getX()
+	{
+		ECP4 W= new ECP4(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP4 */
+	public FP4 getY()
+	{
+		ECP4 W= new ECP4(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP4 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP4 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP4 getz()
+	{
+		return z;
+	}
+
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP4 W=new ECP4(this);
+		//affine();
+		int MB=BIG.MODBYTES;
+
+		W.x.geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i]=t[i];
+		W.x.geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+MB]=t[i];
+		W.x.getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+2*MB]=t[i];
+		W.x.getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+3*MB]=t[i];
+
+		W.y.geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+4*MB]=t[i];
+		W.y.geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+5*MB]=t[i];
+		W.y.getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+6*MB]=t[i];
+		W.y.getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) 
+			b[i+7*MB]=t[i];
+
+	
+	}
+
+/* convert from byte array to point */
+	public static ECP4 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+		int MB=BIG.MODBYTES;
+
+		for (int i=0;i<MB;i++) {t[i]=b[i];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+MB];}
+		rb=BIG.fromBytes(t);
+
+		FP2 ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+2*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+3*MB];}
+		rb=BIG.fromBytes(t);
+
+		FP2 rb4=new FP2(ra,rb);
+
+		FP4 rx=new FP4(ra4,rb4);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+4*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+5*MB];}
+		rb=BIG.fromBytes(t);
+
+		ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+6*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+7*MB];}
+		rb=BIG.fromBytes(t);
+
+		rb4=new FP2(ra,rb);
+		FP4 ry=new FP4(ra4,rb4);
+
+
+		return new ECP4(rx,ry);
+	}
+
+/* convert this to hex string */
+	public String toString() {
+		ECP4 W=new ECP4(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP4 RHS(FP4 x) {
+		x.norm();
+		FP4 r=new FP4(x);
+		r.sqr();
+		FP4 b=new FP4(new FP2(new BIG(ROM.CURVE_B)));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_i();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.times_i();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP4(FP4 ix,FP4 iy) {
+		x=new FP4(ix);
+		y=new FP4(iy);
+		z=new FP4(1);
+		FP4 rhs=RHS(x);
+		FP4 y2=new FP4(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+		//if (y2.equals(rhs)) INF=false;
+		//else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP4(FP4 ix) {
+		x=new FP4(ix);
+		y=new FP4(1);
+		z=new FP4(1);
+		FP4 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {inf(); /*x.zero();INF=true;*/}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+
+		FP4 iy=new FP4(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.times_i(); //iy.norm();
+		}
+		FP4 t0=new FP4(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.times_i();
+		}
+		FP4 t1=new FP4(iy);  
+		t1.mul(z);
+		FP4 t2=new FP4(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.times_i();
+			//t2.norm();
+		}
+
+		FP4 x3=new FP4(t2);
+		x3.mul(z); 
+
+		FP4 y3=new FP4(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP4 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+
+		int b=3*ROM.CURVE_B_I;
+		FP4 t0=new FP4(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP4 t1=new FP4(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP4 t2=new FP4(z);
+		t2.mul(Q.z);
+		FP4 t3=new FP4(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP4 t4=new FP4(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.times_i();  //t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP4 x3=new FP4(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.times_i(); //t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP4 y3=new FP4(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.times_i(); //t0.norm(); // x.Q.x
+			t1.times_i(); //t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.times_i();
+		}
+		FP4 z3=new FP4(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.times_i(); 
+			//y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP4 Q) {
+		ECP4 NQ=new ECP4(Q);
+		NQ.neg();
+		int D=add(NQ);
+
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+
+	public static FP2[] frob_constants() {
+			BIG Fra=new BIG(ROM.Fra);
+			BIG Frb=new BIG(ROM.Frb);
+			FP2 X=new FP2(Fra,Frb);
+
+			FP2 F0=new FP2(X); F0.sqr();
+			FP2 F2=new FP2(F0);
+			F2.mul_ip(); F2.norm();
+			FP2 F1=new FP2(F2); F1.sqr();
+			F2.mul(F1);
+			F1.copy(X);
+			if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
+			{
+				F1.mul_ip();
+				F1.inverse();
+				F0.copy(F1); F0.sqr();
+			}
+			F0.mul_ip(); F0.norm();
+			F1.mul(F0);
+			FP2[] F={F0,F1,F2};
+			return F;
+	}
+
+
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 F[],int n)
+	{
+//		if (INF) return;
+		for (int i=0;i<n;i++) {
+			x.frob(F[2]);
+			x.pmul(F[0]);
+		
+			y.frob(F[2]);
+			y.pmul(F[1]);
+			y.times_i();
+
+			z.frob(F[2]);
+		}
+	}
+
+/* P*=e */
+	public ECP4 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP4 P=new ECP4();
+		ECP4 Q=new ECP4();
+		ECP4 C=new ECP4();
+		ECP4[] W=new ECP4[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP4();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP4();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP4();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3... */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP4 mul8(ECP4[] Q,BIG[] u)
+	{
+		int i,j,k,nb,pb1,pb2;
+		ECP4 W=new ECP4();
+		ECP4 P=new ECP4();
+		ECP4[] T1=new ECP4[8];
+		ECP4[] T2=new ECP4[8];
+
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[8];
+
+		byte[] w1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<8;i++)
+		{
+			t[i]=new BIG(u[i]);
+			//Q[i].affine();
+			t[i].norm();
+		}
+
+        T1[0] = new ECP4(); T1[0].copy(Q[0]);  // Q[0]
+        T1[1] = new ECP4(); T1[1].copy(T1[0]); T1[1].add(Q[1]);  // Q[0]+Q[1]
+        T1[2] = new ECP4(); T1[2].copy(T1[0]); T1[2].add(Q[2]);  // Q[0]+Q[2]
+        T1[3] = new ECP4(); T1[3].copy(T1[1]); T1[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T1[4] = new ECP4(); T1[4].copy(T1[0]); T1[4].add(Q[3]);  // Q[0]+Q[3]
+        T1[5] = new ECP4(); T1[5].copy(T1[1]); T1[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T1[6] = new ECP4(); T1[6].copy(T1[2]); T1[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T1[7] = new ECP4(); T1[7].copy(T1[3]); T1[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+//  Use Frobenius 
+		FP2[] F=ECP4.frob_constants();
+
+		for (i=0;i<8;i++) {
+			T2[i] = new ECP4(); T2[i].copy(T1[i]);
+			T2[i].frob(F,4);
+		}
+
+    // Make it odd
+        pb1=1-t[0].parity();
+        t[0].inc(pb1);
+        t[0].norm();
+
+        pb2=1-t[4].parity();
+        t[4].inc(pb2);
+        t[4].norm();
+
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<8;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s1[nb-1]=1;
+		s2[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s1[i]=(byte)(2*t[0].parity()-1);
+            t[4].fshr(1);
+            s2[i]=(byte)(2*t[4].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w1[i]=0;
+            k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s1[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w1[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w2[i]=0;
+            k=1;
+            for (j=5; j<8; j++) {
+                byte bt=(byte)(s2[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w2[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T1,(int)(2*w1[nb-1]+1));  
+		W.select(T2,(int)(2*w2[nb-1]+1)); 
+		P.add(W);
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T1,(int)(2*w1[i]+s1[i]));
+            P.add(W);
+            W.select(T2,(int)(2*w2[i]+s2[i]));
+            P.add(W);
+
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb1);   
+
+        W.copy(P);   
+        W.sub(Q[4]);
+        P.cmove(W,pb2);  
+
+		P.affine();
+		return P;
+	}        
+
+/* needed for SOK */
+	public static ECP4 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP4 X;
+		FP2 X2;
+		ECP4 Q;
+		x.mod(q);
+		while (true)
+		{
+			X2=new FP2(one,x);
+			X=new FP4(X2);
+			Q=new ECP4(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		FP2[] F=ECP4.frob_constants();
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+
+		ECP4 xQ=Q.mul(x);
+		ECP4 x2Q=xQ.mul(x);
+		ECP4 x3Q=x2Q.mul(x);
+		ECP4 x4Q=x3Q.mul(x);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			xQ.neg();
+			x3Q.neg();
+		}	
+
+		x4Q.sub(x3Q);
+		x4Q.sub(Q);
+
+		x3Q.sub(x2Q);
+		x3Q.frob(F,1);
+
+		x2Q.sub(xQ);
+		x2Q.frob(F,2);
+
+		xQ.sub(Q);
+		xQ.frob(F,3);
+
+		Q.dbl();
+		Q.frob(F,4);
+
+		Q.add(x4Q);
+		Q.add(x3Q);
+		Q.add(x2Q);
+		Q.add(xQ);
+
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP4 generator()
+	{
+
+		return new ECP4(
+			new FP4(
+				new FP2(
+					new BIG(ROM.CURVE_Pxaa),new BIG(ROM.CURVE_Pxab)),
+				new FP2(
+					new BIG(ROM.CURVE_Pxba),new BIG(ROM.CURVE_Pxbb))),
+			new FP4(
+				new FP2(
+					new BIG(ROM.CURVE_Pyaa),new BIG(ROM.CURVE_Pyab)),
+				new FP2(
+					new BIG(ROM.CURVE_Pyba),new BIG(ROM.CURVE_Pybb))));
+	}
+
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/FP.java b/src/main/java/org/apache/milagro/amcl/BLS24/FP.java
new file mode 100644
index 0000000..1a0258f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=479; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<25);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/FP2.java b/src/main/java/org/apache/milagro/amcl/BLS24/FP2.java
new file mode 100644
index 0000000..6704129
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/FP24.java b/src/main/java/org/apache/milagro/amcl/BLS24/FP24.java
new file mode 100644
index 0000000..d197f0d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/FP24.java
@@ -0,0 +1,851 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^24 functions */
+/* FP24 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class FP24 {
+	private final FP8 a;
+	private final FP8 b;
+	private final FP8 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP24 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP24 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP24 invf=new FP24(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+	/* test x==1 ? */
+	public boolean isunity() {
+		FP8 one=new FP8(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP24 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP8 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP8 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP8 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP24 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP24(FP8 d)
+	{
+		a=new FP8(d);
+		b=new FP8(0);
+		c=new FP8(0);
+	}
+
+	public FP24(int d)
+	{
+		a=new FP8(d);
+		b=new FP8(0);
+		c=new FP8(0);
+	}
+
+	public FP24(FP8 d,FP8 e,FP8 f)
+	{
+		a=new FP8(d);
+		b=new FP8(e);
+		c=new FP8(f);
+	}
+
+	public FP24(FP24 x)
+	{
+		a=new FP8(x.a);
+		b=new FP8(x.b);
+		c=new FP8(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP8 A=new FP8(a);
+		FP8 B=new FP8(c);
+		FP8 C=new FP8(b);
+		FP8 D=new FP8(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+		reduce();
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+		FP8 A=new FP8(a);
+		FP8 B=new FP8(b);
+		FP8 C=new FP8(c);
+		FP8 D=new FP8(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP24 y)
+	{
+//System.out.println("Into mul");
+		FP8 z0=new FP8(a);
+		FP8 z1=new FP8(0);
+		FP8 z2=new FP8(b);
+		FP8 z3=new FP8(0);
+		FP8 t0=new FP8(a);
+		FP8 t1=new FP8(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP24 y,int type)
+	{
+		if (type==ECP.D_TYPE)
+		{
+			FP8 z0=new FP8(a);
+			FP8 z2=new FP8(b);
+			FP8 z3=new FP8(b);
+			FP8 t0=new FP8(0);
+			FP8 t1=new FP8(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP8 z0=new FP8(a);
+			FP8 z1=new FP8(0);
+			FP8 z2=new FP8(0);
+			FP8 z3=new FP8(0);
+			FP8 t0=new FP8(a);
+			FP8 t1=new FP8(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP8 f0=new FP8(a);
+		FP8 f1=new FP8(b);
+		FP8 f2=new FP8(a);
+		FP8 f3=new FP8(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+		f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+		f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+		f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+		f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f,int n)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		f3.mul_ip(); f3.norm();
+
+		for (int i=0;i<n;i++)
+		{
+			a.frob(f3);
+			b.frob(f3);
+			c.frob(f3);
+
+			b.qmul(f); b.times_i2();
+			c.qmul(f2); c.times_i2(); c.times_i2();
+		}
+	}
+
+/* trace function */
+	public FP8 trace()
+	{
+		FP8 t=new FP8(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP24 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 ea,eb;
+		FP8 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		e=new FP8(ea,eb);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+12*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+13*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+14*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+15*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		f=new FP8(ea,eb);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+16*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+17*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+18*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+19*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+20*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+21*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+22*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+23*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		g=new FP8(ea,eb);
+
+		return new FP24(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+
+		a.geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		a.getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		a.getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		a.getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		a.getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+
+		b.geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		b.geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		b.geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		b.geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+
+		b.getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+12*BIG.MODBYTES]=t[i];
+		b.getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+13*BIG.MODBYTES]=t[i];
+		b.getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+14*BIG.MODBYTES]=t[i];
+		b.getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+15*BIG.MODBYTES]=t[i];
+
+		c.geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+16*BIG.MODBYTES]=t[i];
+		c.geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+17*BIG.MODBYTES]=t[i];
+		c.geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+18*BIG.MODBYTES]=t[i];
+		c.geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+19*BIG.MODBYTES]=t[i];
+
+		c.getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+20*BIG.MODBYTES]=t[i];
+		c.getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+21*BIG.MODBYTES]=t[i];
+		c.getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+22*BIG.MODBYTES]=t[i];
+		c.getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+23*BIG.MODBYTES]=t[i];
+
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP24 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP24 w=new FP24(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP24 [] R=new FP24[2];
+		R[0]=new FP24(1);
+		R[1]=new FP24(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP8 compow(BIG e,BIG r)
+	{
+		FP24 g1=new FP24(0);
+		FP24 g2=new FP24(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP8 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f,1);
+		FP8 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP8 cpm1=g2.trace();
+		g2.mul(g1);
+		FP8 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3.... */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP24 pow8(FP24[] q,BIG[] u)
+	{
+		int i,j,k,nb,pb1,pb2;
+		FP24 [] g1=new FP24[8];
+		FP24 [] g2=new FP24[8];
+		FP24 r=new FP24(1);
+		FP24 p=new FP24(0);
+		BIG [] t=new BIG[8];
+		BIG mt=new BIG(0);
+		byte[] w1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<8;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+
+		g1[0]=new FP24(q[0]);  // q[0]
+		g1[1]=new FP24(g1[0]); g1[1].mul(q[1]); // q[0].q[1]
+		g1[2]=new FP24(g1[0]); g1[2].mul(q[2]); // q[0].q[2]
+		g1[3]=new FP24(g1[1]); g1[3].mul(q[2]); // q[0].q[1].q[2]
+		g1[4]=new FP24(q[0]);  g1[4].mul(q[3]); // q[0].q[3]
+		g1[5]=new FP24(g1[1]); g1[5].mul(q[3]); // q[0].q[1].q[3]
+		g1[6]=new FP24(g1[2]); g1[6].mul(q[3]); // q[0].q[2].q[3]
+		g1[7]=new FP24(g1[3]); g1[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+// Use Frobenius
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		for (i=0;i<8;i++)
+		{
+			g2[i]=new FP24(g1[i]);
+			g2[i].frob(f,4);
+		}
+
+    // Make it odd
+        pb1=1-t[0].parity();
+        t[0].inc(pb1);
+        t[0].norm();
+
+        pb2=1-t[4].parity();
+        t[4].inc(pb2);
+        t[4].norm();
+
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<8;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+     // Sign pivot 
+        s1[nb-1]=1;
+		s2[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s1[i]=(byte)(2*t[0].parity()-1);
+            t[4].fshr(1);
+            s2[i]=(byte)(2*t[4].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w1[i]=0;
+            k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s1[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w1[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w2[i]=0;
+            k=1;
+            for (j=5; j<8; j++) {
+                byte bt=(byte)(s2[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w2[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g1,(int)(2*w1[nb-1]+1)); 
+		r.select(g2,(int)(2*w2[nb-1]+1)); 
+		p.mul(r);
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g1,(int)(2*w1[i]+s1[i]));
+            p.mul(r);
+            r.select(g2,(int)(2*w2[i]+s2[i]));
+            p.mul(r);
+
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb1);
+
+        r.copy(q[4]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb2);
+
+ 		p.reduce();
+		return p;
+	}              
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/FP4.java b/src/main/java/org/apache/milagro/amcl/BLS24/FP4.java
new file mode 100644
index 0000000..4580325
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/FP8.java b/src/main/java/org/apache/milagro/amcl/BLS24/FP8.java
new file mode 100644
index 0000000..d164d19
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/FP8.java
@@ -0,0 +1,656 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^8 functions */
+
+/* FP8 elements are of the form a+ib, where i is sqrt(sqrt(-1+sqrt(-1)))  */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class FP8 {
+	private final FP4 a;
+	private final FP4 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP8 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP4 real()
+	{
+		return a;
+	}
+
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP8 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP8(int c)
+	{
+		a=new FP4(c);
+		b=new FP4(0);
+	}
+
+	public FP8(FP8 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+	}
+
+	public FP8(FP4 c,FP4 d)
+	{
+		a=new FP4(c);
+		b=new FP4(d);
+	}
+
+	public FP8(FP4 c)
+	{
+		a=new FP4(c);
+		b=new FP4(0);
+	}
+/* copy this=x */
+	public void copy(FP8 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP4 m=new FP4(a);
+		FP4 t=new FP4(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP8 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP8 x)
+	{
+		FP8 m=new FP8(x);
+		m.neg();
+		add(m);
+	}
+
+/* this=x-this */
+	public void rsub(FP8 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=s where s is FP4 */
+	public void pmul(FP4 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+/* this*=s where s is FP2 */
+	public void qmul(FP2 s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+/* this*=s where s is FP */
+	public void tmul(FP s)
+	{
+		a.qmul(s);
+		b.qmul(s);
+	}
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+		FP4 t3=new FP4(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.times_i();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.times_i();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+
+/* this*=y */
+	public void mul(FP8 y)
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+		FP4 t3=new FP4(0);
+		FP4 t4=new FP4(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+		t3.norm();
+		t4.norm();
+
+		t4.mul(t3);
+
+		t3.copy(t1);
+		t3.neg();
+		t4.add(t3);
+		t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+		t3.copy(t2);
+		t3.neg();
+		b.copy(t4);
+		b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.times_i();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.times_i();
+		t2.norm();
+		t1.sub(t2); t1.norm();
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+		t1.norm();
+		b.mul(t1);
+	}
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP4 s=new FP4(b);
+		FP4 t=new FP4(a);
+		s.times_i();
+
+		b.copy(t);
+		a.copy(s);
+		norm();
+	}
+
+	public void times_i2()
+	{
+		a.times_i();
+		b.times_i();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 ff=new FP2(f); ff.sqr(); ff.mul_ip(); ff.norm();
+
+		a.frob(ff);
+		b.frob(ff);
+		b.pmul(f);
+		b.times_i();
+
+	}
+
+/* this=this^e */
+	public FP8 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP8 w=new FP8(this);
+		BIG z=new BIG(e);
+		FP8 r=new FP8(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+
+/* XTR xtr_a function */
+	public void xtr_A(FP8 w,FP8 y,FP8 z) 
+	{
+		FP8 r=new FP8(w);
+		FP8 t=new FP8(w);
+	
+		r.sub(y);
+		r.norm();
+		r.pmul(a);
+		t.add(y);
+		t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP8 w=new FP8(this);
+		sqr(); w.conj();
+		w.add(w);
+		w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP8 xtr_pow(BIG n) {
+		FP8 a=new FP8(3);
+		FP8 b=new FP8(this);
+		FP8 c=new FP8(b);
+		c.xtr_D();
+		FP8 t=new FP8(0);
+		FP8 r=new FP8(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP8 xtr_pow2(FP8 ck,FP8 ckml,FP8 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP8 cu=new FP8(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP4 u=new FP4(a);
+		FP4 v=new FP4(b);
+		u.div_i();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_i2() {
+		a.div_i();
+		b.div_i();
+	}
+
+	public void div_2i() {
+		FP4 u=new FP4(a);
+		FP4 v=new FP4(b);
+		u.div_2i();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP4 wa=new FP4(a);
+		FP4 ws=new FP4(b);
+		FP4 wt=new FP4(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_i();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.times_i();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/MPIN192.java b/src/main/java/org/apache/milagro/amcl/BLS24/MPIN192.java
new file mode 100644
index 0000000..ee3f566
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/MPIN192.java
@@ -0,0 +1,806 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BLS24;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN192
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP8 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[10*EFS];
+		byte[] h=null;
+		c.geta().geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.geta().getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.geta().getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+	
+		c.getb().geta().getA().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		c.getb().geta().getB().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		c.getb().getb().getA().toBytes(w); for (int i=6*EFS;i<7*EFS;i++) t[i]=w[i-6*EFS];
+		c.getb().getb().getB().toBytes(w); for (int i=7*EFS;i<8*EFS;i++) t[i]=w[i-7*EFS];
+
+		
+		U.getX().toBytes(w); for (int i=8*EFS;i<9*EFS;i++) t[i]=w[i-8*EFS];
+		U.getY().toBytes(w); for (int i=9*EFS;i<10*EFS;i++) t[i]=w[i-9*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP4 P=ECP4.fromBytes(W1);
+		ECP4 Q=ECP4.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR192.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR192.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR192.G1mul(W,x);
+				P.add(W); //P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR192.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR192.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP4 Q=ECP4.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR192.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR192.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR192.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID,false);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP4 Q=ECP4.generator();
+
+		ECP4 sQ=ECP4.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR192.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP24 g;
+
+		g=PAIR192.ate2(Q,R,sQ,P);
+		g=PAIR192.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR192.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR192.ate(Q,P);
+				g=PAIR192.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP24 ge=FP24.fromBytes(E);
+		FP24 gf=FP24.fromBytes(F);
+		int[] distance = new int[TS];
+		FP24 t=new FP24(gf);
+		FP24[] table=new FP24[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP24(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP24 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP4 Q=ECP4.generator();
+
+		g=PAIR192.ate(Q,T);
+		g=PAIR192.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR192.ate(Q,P);
+		g=PAIR192.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP24 g1=FP24.fromBytes(G1);
+		FP24 g2=FP24.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR192.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP8 c=g1.compow(z,r);
+
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP4 sQ=ECP4.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR192.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR192.G1mul(U,w);
+		FP24 g=PAIR192.ate(sQ,R);
+		g=PAIR192.fexp(g);
+
+		FP8 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/PAIR192.java b/src/main/java/org/apache/milagro/amcl/BLS24/PAIR192.java
new file mode 100644
index 0000000..da3d100
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/PAIR192.java
@@ -0,0 +1,550 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BLS24;
+
+public final class PAIR192 {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP24 line(ECP4 A,ECP4 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP8 a,b,c;                            // Edits here
+//		c=new FP8(0);
+		if (A==B)
+		{ // Doubling
+			FP4 XX=new FP4(A.getx());  //X
+			FP4 YY=new FP4(A.gety());  //Y
+			FP4 ZZ=new FP4(A.getz());  //Z
+			FP4 YZ=new FP4(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.qmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.qmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_2i();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.times_i();
+				ZZ.add(ZZ);
+				YZ.times_i();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP8(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP8(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP8(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP8(0);
+				c=new FP8(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP4 X1=new FP4(A.getx());    // X1
+			FP4 Y1=new FP4(A.gety());    // Y1
+			FP4 T1=new FP4(A.getz());    // Z1
+			FP4 T2=new FP4(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.qmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.times_i();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.qmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP8(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP8(Y1);
+				c=new FP8(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP8(0);
+				c=new FP8(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP24(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP24 ate(ECP4 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		FP24 lv;
+		int bt;
+		
+		ECP4 P=new ECP4(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP4 A=new ECP4();
+		FP24 r=new FP24(1);
+		A.copy(P);
+
+		ECP4 MP=new ECP4();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP24 ate2(ECP4 P1,ECP Q1,ECP4 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		FP24 lv;
+		int bt;
+
+		ECP4 P=new ECP4(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP4 R=new ECP4(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP4 A=new ECP4();
+		ECP4 B=new ECP4();
+		FP24 r=new FP24(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP4 MP=new ECP4();
+		MP.copy(P); MP.neg();
+		ECP4 MR=new ECP4();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP24 fexp(FP24 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP24 r=new FP24(m);
+
+/* Easy part of final exp */
+		FP24 lv=new FP24(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f,4);
+		r.mul(lv);
+
+		FP24 t0,t1,t2,t3,t4,t5,t6,t7;
+/* Hard part of final exp */	
+// Ghamman & Fouotsa Method
+
+		t7=new FP24(r); t7.usqr();
+		t1=t7.pow(x);
+
+		x.fshr(1);
+		t2=t1.pow(x);
+		x.fshl(1);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+		t3=new FP24(t1); t3.conj();
+		t2.mul(t3);
+		t2.mul(r);
+
+		t3=t2.pow(x);
+		t4=t3.pow(x);
+		t5=t4.pow(x);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t3.conj(); t5.conj();
+		}
+
+		t3.frob(f,6); t4.frob(f,5);
+		t3.mul(t4);
+
+		t6=t5.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t6.conj();
+		}
+
+		t5.frob(f,4);
+		t3.mul(t5);
+
+		t0=new FP24(t2); t0.conj();
+		t6.mul(t0);
+
+		t5.copy(t6);
+		t5.frob(f,3);
+
+		t3.mul(t5);
+		t5=t6.pow(x);
+		t6=t5.pow(x);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t5.conj();
+		}
+
+		t0.copy(t5);
+		t0.frob(f,2);
+		t3.mul(t0);
+		t0.copy(t6);
+		t0.frob(f,1);
+
+		t3.mul(t0);
+		t5=t6.pow(x);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t5.conj();
+		}
+		t2.frob(f,7);
+
+		t5.mul(t7);
+		t3.mul(t2);
+		t3.mul(t5);
+
+		r.mul(t3);
+
+		r.reduce();
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+// -(x^4).P = (Beta.x,y)
+		BIG q=new BIG(ROM.CURVE_Order);
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG x2=BIG.smul(x,x);
+		x=BIG.smul(x2,x2);
+		u[0]=new BIG(e);
+		u[0].mod(x);
+		u[1]=new BIG(e);
+		u[1].div(x);
+		u[1].rsub(q);
+
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[8];
+
+		BIG q=new BIG(ROM.CURVE_Order);
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG w=new BIG(e);
+		for (int i=0;i<7;i++)
+		{
+			u[i]=new BIG(w);
+			u[i].mod(x);
+			w.div(x);
+		}
+		u[7]=new BIG(w);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			u[1].copy(BIG.modneg(u[1],q));
+			u[3].copy(BIG.modneg(u[3],q));
+			u[5].copy(BIG.modneg(u[5],q));
+			u[7].copy(BIG.modneg(u[7],q));
+		}
+
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP4 G2mul(ECP4 P,BIG e)
+	{
+		ECP4 R;
+		if (USE_GS_G2)
+		{
+			ECP4[] Q=new ECP4[8];
+			FP2[] F=ECP4.frob_constants();
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP4(); Q[0].copy(P);
+			for (i=1;i<8;i++)
+			{
+				Q[i]=new ECP4(); Q[i].copy(Q[i-1]);
+				Q[i].frob(F,1);
+			}
+			for (i=0;i<8;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP4.mul8(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP8.java */
+	public static FP24 GTpow(FP24 d,BIG e)
+	{
+		FP24 r;
+		if (USE_GS_GT)
+		{
+			FP24[] g=new FP24[8];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP24(d);
+			for (i=1;i<8;i++)
+			{
+				g[i]=new FP24(0); g[i].copy(g[i-1]);
+				g[i].frob(f,1);
+			}
+			for (i=0;i<8;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP24.pow8(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS24/ROM.java b/src/main/java/org/apache/milagro/amcl/BLS24/ROM.java
new file mode 100644
index 0000000..14658f9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS24/ROM.java
@@ -0,0 +1,60 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BLS24;
+
+public class ROM
+{
+
+// Base Bits= 56
+	public static final long[] Modulus= {0x44C1674A06152BL,0xFFE2E82D30DAF8L,0x6F1C5CBDB6A642L,0x3220DF068A328BL,0xE09E1F24406187L,0xBA825079733568L,0x6E803F2E77E4C1L,0x3CCC5BA839AECL,0x555C0078L};
+	public static final long[] R2modp= {0x6A4A1FE013DF5BL,0xE8E46D4D1BDE65L,0x1F841391F45C67L,0x9148A4516FB28L,0x4398524EDF4C88L,0x41C0E241B6DCE8L,0xE42C208C19411L,0xA7FE6FD73A7B1CL,0xFCCCA76L};
+	public static final long MConst= 0xBD5D7D8095FE7DL;
+	public static final long[] Fra= {0x5CA74ABBF96F1DL,0x1FF8BD0C6FFBADL,0x49E9E26237469CL,0x3CECA48407F8E5L,0x69D68FF59267B7L,0x5D199E33127CBDL,0xB97549184F313AL,0x4E77242DA52D8DL,0x4BBC87B9L};
+	public static final long[] Frb= {0xE81A1C8E0CA60EL,0xDFEA2B20C0DF4AL,0x25327A5B7F5FA6L,0xF5343A828239A6L,0x76C78F2EADF9CFL,0x5D68B24660B8ABL,0xB50AF61628B387L,0xB555A18CDE6D5EL,0x99F78BEL};
+
+	public static final int CURVE_A= 0;
+	public static final int CURVE_B_I= 19;
+	public static final int CURVE_Cof_I= 0;
+	public static final long[] CURVE_B= {0x13L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0x1A08FFF0000001L,0x1E7033FF551190L,0x6ADE7EE322DDAFL,0x848FC9D0CED13AL,0x50D81729CC224L,0x1F0F05B98BB44AL,0x10010010005A0L,0x0L,0x0L};
+	public static final long[] CURVE_Gx= {0x6760F5EBE3CCD4L,0xEFE2DAED9F4564L,0x783F08EBA1FCC1L,0xC6F8D95AF88134L,0xDCA8D1AE2D8477L,0x9077586CEFE4BFL,0x8B7FEA5D99BC1DL,0x17CAF9486DE9E1L,0x1AB2BE34L};
+	public static final long[] CURVE_Gy= {0xCBA5CAD21E5245L,0x6D6608C55DF6C4L,0xB3ED294F39746BL,0x145824920FF3C8L,0x63AA4FD63E5A64L,0x492A2BF79CE00FL,0x66A7A4529FF79AL,0x6C53E477B861CAL,0x47FCB70CL};
+
+	public static final long[] CURVE_Bnx= {0x100020011FF80L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cof= {0xC1FFBFF9F415ABL,0x5556AAB7FFL,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cru= {0xBC27146DD794A9L,0x3A30938AF33A43L,0xB112175223DDC6L,0x125CFBB4236DFBL,0x2358E379CE607L,0xD680C6EB20806EL,0x314C200860FF77L,0x3CBC5A88268E4L,0x555C0078L};
+	public static final long[] CURVE_Pxaa= {0xE2935374E24678L,0xC34342582408BL,0xF765CCDEFC69EL,0xC33AAD2888D7F9L,0x7FD2458967473AL,0x52908ED55CBAB3L,0x786671EB14AB88L,0xA3EC96077958C8L,0x959DE53L};
+	public static final long[] CURVE_Pxab= {0x7F9EBAFFB099B8L,0x3775A012A47038L,0x6B5D1B1FC23856L,0x7F0A26A730F9E3L,0x1C38F85DB2A5CAL,0x76A753E17E6926L,0x2D39D1BE5AD0F9L,0x31733DFC651E4CL,0x3B0DED08L};
+	public static final long[] CURVE_Pxba= {0xA1CDE711AD15D3L,0x853178DF6E16EDL,0x64BF43EA3E09A1L,0x2D8CD6DE566B2FL,0xF21C26C74FDB8BL,0x47BCC89E3F6B1EL,0x3FE2103F329F00L,0x4E507AF2AA28C3L,0x3EC27FADL};
+	public static final long[] CURVE_Pxbb= {0x7AB2875EE0F480L,0x4556E43D6C4B8CL,0xFB22DF80E1CB99L,0xF70FD0122F1FFDL,0xD5DB25698EF5EAL,0x4805CE1AF1BA3AL,0x1DA7CE2E465CB7L,0xCA0799F7E65855L,0xA5B38DBL};
+	public static final long[] CURVE_Pyaa= {0x86499314781AA0L,0x609DA303B70AB1L,0xA52A6145FC44BBL,0x462E04C42A3124L,0xC383AE19AE68BBL,0xA1B34F6BE4FCADL,0x198F901AD0BF4L,0x736C094362CED0L,0x5057F35DL};
+	public static final long[] CURVE_Pyab= {0xBBEC57EEAE08FAL,0x78774BAA5F96ADL,0x64CAF099A42CA0L,0xC89FBBCCF70478L,0x6B720FEF855245L,0x97F916376F7B3EL,0x60F5587B5DF7E1L,0x61EE89637816BDL,0x2CE2B496L};
+	public static final long[] CURVE_Pyba= {0x730276A5F0CC41L,0xF89325530AA1F5L,0xD9CD879AF8A147L,0xEE53E8A9FE2880L,0x420F07D3715390L,0x4C15D519B71F3AL,0x1A39DD3CB5B9B1L,0x3EE631A6BE39F8L,0x18070466L};
+	public static final long[] CURVE_Pybb= {0xF1B2E6515C1CAEL,0xD40D355B0988DCL,0xC243FDC38A7772L,0x5D338136B675CAL,0x164E8A1D72FCDFL,0xBBAE5CD0961ACL,0xD6D04691771EB1L,0xD9BDEC8B792840L,0x499D14EAL};
+	public static final long[][] CURVE_W= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_SB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+	public static final long[][] CURVE_WB= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_BB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/BIG.java b/src/main/java/org/apache/milagro/amcl/BLS381/BIG.java
new file mode 100644
index 0000000..5a5644f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BLS381;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/DBIG.java b/src/main/java/org/apache/milagro/amcl/BLS381/DBIG.java
new file mode 100644
index 0000000..fad920e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BLS381;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/ECDH.java b/src/main/java/org/apache/milagro/amcl/BLS381/ECDH.java
new file mode 100644
index 0000000..672ee85
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BLS381;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/ECP.java b/src/main/java/org/apache/milagro/amcl/BLS381/ECP.java
new file mode 100644
index 0000000..a08bc11
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BLS;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=NEGATIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/ECP2.java b/src/main/java/org/apache/milagro/amcl/BLS381/ECP2.java
new file mode 100644
index 0000000..1870e3a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/FP.java b/src/main/java/org/apache/milagro/amcl/BLS381/FP.java
new file mode 100644
index 0000000..f3ae560
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=381; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<25);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/FP12.java b/src/main/java/org/apache/milagro/amcl/BLS381/FP12.java
new file mode 100644
index 0000000..f1ffef9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/FP2.java b/src/main/java/org/apache/milagro/amcl/BLS381/FP2.java
new file mode 100644
index 0000000..e77fc00
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/FP4.java b/src/main/java/org/apache/milagro/amcl/BLS381/FP4.java
new file mode 100644
index 0000000..47c4bf0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/MPIN.java b/src/main/java/org/apache/milagro/amcl/BLS381/MPIN.java
new file mode 100644
index 0000000..7365f3d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BLS381;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/PAIR.java b/src/main/java/org/apache/milagro/amcl/BLS381/PAIR.java
new file mode 100644
index 0000000..55e86b4
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BLS381;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS381/ROM.java b/src/main/java/org/apache/milagro/amcl/BLS381/ROM.java
new file mode 100644
index 0000000..b59e7a1
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS381/ROM.java
@@ -0,0 +1,57 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BLS381;
+
+public class ROM
+{
+
+// Base Bits= 58
+public static final long[] Modulus= {0x1FEFFFFFFFFAAABL,0x2FFFFAC54FFFFEEL,0x12A0F6B0F6241EAL,0x213CE144AFD9CC3L,0x2434BACD764774BL,0x25FF9A692C6E9EDL,0x1A0111EA3L};
+public static final long[] R2modp= {0x20639A1D5BEF7AEL,0x1244C6462DD93E8L,0x22D09B54E6E2CD2L,0x111C4B63170E5DBL,0x38A6DE8FB366399L,0x4F16CFED1F9CBCL,0x19EA66A2BL};
+public static final long MConst= 0x1F3FFFCFFFCFFFDL;
+
+public static final int CURVE_A= 0;
+public static final int CURVE_B_I= 4;
+public static final int CURVE_Cof_I= 0;
+public static final long[] CURVE_B= {0x4L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x3FFFFFF00000001L,0x36900BFFF96FFBFL,0x180809A1D80553BL,0x14CA675F520CCE7L,0x73EDA7L,0x0L,0x0L};
+public static final long[] CURVE_Gx= {0x33AF00ADB22C6BBL,0x17A0FFE5E86BBFEL,0x3A3F171BAC586C5L,0x13E5DD2E4168538L,0x4FA9AC0FC3688CL,0x65F5E509A558E3L,0x17F1D3A73L};
+public static final long[] CURVE_Gy= {0xAA232946C5E7E1L,0x331D128A222B903L,0x18CB2C04B3EDD03L,0x25757402BD8036CL,0x1741D8AE4FCF5E0L,0xEAA83C68278C3BL,0x8B3F481EL};
+
+
+public static final long[] Fra= {0x10775ED92235FB8L,0x3A94F58F9E04F63L,0x3D784BAB9C4F67L,0x3F4F2F57D3DEC91L,0x202C0D1F0FD603L,0xAEC199F08C6FADL,0x1904D3BF0L};
+public static final long[] Frb= {0xF78A126DDC4AF3L,0x356B0535B1FB08BL,0xEC971F63C5F282L,0x21EDB1ECDBFB032L,0x2231F9FB854A147L,0x1B1380CA23A7A40L,0xFC3E2B3L};
+public static final long[] CURVE_Bnx= {0x201000000010000L,0x34L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cof= {0xAAAB0000AAABL,0x3230015557855A3L,0x396L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cru= {0x201FFFFFFFEFFFEL,0x1F604D88280008BL,0x293BE6F89688DE1L,0x1DA83DDFAB76CEL,0x3DF76CE51BA69C6L,0x17C659CBL,0x0L};
+public static final long[] CURVE_Pxa= {0x8056C8C121BDB8L,0x300C9AA016EFBF5L,0xB647AE3D1770BAL,0x353E900EC0AD144L,0x32DC51051C6E47AL,0x23C2A449820149L,0x24AA2B2FL};
+public static final long[] CURVE_Pxb= {0x1AC7D055D042B7EL,0x33C4484E51755F9L,0x21BBDC7F5049334L,0x3426482D86AD769L,0x88274F65596BD0L,0x9C67D81F6B34E8L,0x13E02B605L};
+public static final long[] CURVE_Pya= {0x193548608B82801L,0x2B2730EEB28A278L,0x1A695160D12C923L,0x2AA32F74E9DB50AL,0x2DA2E351AADFD9BL,0x9F5B8463327371L,0xCE5D5277L};
+public static final long[] CURVE_Pyb= {0x2A9075FF05F79BEL,0x1C349D73B07686AL,0x12AB572E99AB3F3L,0x1FA169D8EBC99D2L,0x2BC28B99CB3E28L,0x3A9CD330CAB34ACL,0x606C4A02L};
+public static final long[][] CURVE_W= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_SB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+public static final long[][] CURVE_WB= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_BB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/BIG.java b/src/main/java/org/apache/milagro/amcl/BLS383/BIG.java
new file mode 100644
index 0000000..6a9195d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BLS383;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/DBIG.java b/src/main/java/org/apache/milagro/amcl/BLS383/DBIG.java
new file mode 100644
index 0000000..bfebc30
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BLS383;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/ECDH.java b/src/main/java/org/apache/milagro/amcl/BLS383/ECDH.java
new file mode 100644
index 0000000..6f678a4
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BLS383;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/ECP.java b/src/main/java/org/apache/milagro/amcl/BLS383/ECP.java
new file mode 100644
index 0000000..8b11cf9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BLS;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=POSITIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/ECP2.java b/src/main/java/org/apache/milagro/amcl/BLS383/ECP2.java
new file mode 100644
index 0000000..509de9f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/FP.java b/src/main/java/org/apache/milagro/amcl/BLS383/FP.java
new file mode 100644
index 0000000..0ec6de4
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=383; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<23);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/FP12.java b/src/main/java/org/apache/milagro/amcl/BLS383/FP12.java
new file mode 100644
index 0000000..5ac3ac6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/FP2.java b/src/main/java/org/apache/milagro/amcl/BLS383/FP2.java
new file mode 100644
index 0000000..2423571
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/FP4.java b/src/main/java/org/apache/milagro/amcl/BLS383/FP4.java
new file mode 100644
index 0000000..1723f0a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/MPIN.java b/src/main/java/org/apache/milagro/amcl/BLS383/MPIN.java
new file mode 100644
index 0000000..4dde8c6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BLS383;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/PAIR.java b/src/main/java/org/apache/milagro/amcl/BLS383/PAIR.java
new file mode 100644
index 0000000..24341da
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BLS383;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS383/ROM.java b/src/main/java/org/apache/milagro/amcl/BLS383/ROM.java
new file mode 100644
index 0000000..15b0dc2
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS383/ROM.java
@@ -0,0 +1,55 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BLS383;
+
+public class ROM
+{
+
+// Base Bits= 58
+public static final long[] Modulus= {0x2371D6485AAB0ABL,0x30FCA6299214AF6L,0x3801696124F47A8L,0xB3CD969446B0C6L,0x1FEA9284A0AD46L,0x12ADBAD681B6B71L,0x556556956L};
+public static final long[] R2modp= {0x80B6E0116907F4L,0xCF53CF9752AC11L,0x35D47189941C581L,0x19D0835CB1E4D22L,0x16963E90A0FC49BL,0x367FB9DB3852312L,0x4DFECE397L};
+public static final long MConst= 0x1BC0571073435FDL;
+public static final long[] Fra= {0x52D72D3311DAC1L,0x24D203F99DCF806L,0x344AE550D8C8A36L,0x348FEE86A1A0959L,0x2C11B52F10E4C6CL,0x9FDA2F0CE2E7F0L,0x22ACD5BF0L};
+public static final long[] Frb= {0x1E446375298D5EAL,0xC2AA22FF4452F0L,0x3B684104C2BD72L,0x16ACEAE2A2CA76DL,0x15ECF3F939260D9L,0x8B017E5B388380L,0x32B880D66L};
+
+public static final int CURVE_A= 0;
+public static final int CURVE_Cof_I= 0;
+public static final long[] CURVE_Cof= {0x150556155169EABL,0x2AAB0002AAEFFEDL,0x555L,0x0L,0x0L,0x0L,0x0L};
+public static final int CURVE_B_I= 15;
+public static final long[] CURVE_B= {0xFL,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x32099EBFEBC0001L,0x17C25684834E5CEL,0x1C81698B381DE0L,0x2003002E0270110L,0x1002001L,0x0L,0x0L};
+public static final long[] CURVE_Gx= {0xC4773908734573L,0x176FC20FD1DC11EL,0x3AD84AF1E3445C5L,0x1DAC207D0B0BE1EL,0x52DDB050F31D9FL,0x25E7B3938E0D7D0L,0x41FCBA55BL};
+public static final long[] CURVE_Gy= {0x12D165E8003F224L,0x1F527B21FE63F48L,0xA94ADEB4D2DDE5L,0x319AED912441D4CL,0x1C31C46D99D0DADL,0x133ECC00092BA73L,0x68F16727L};
+
+public static final long[] CURVE_Bnx= {0x8000001001200L,0x40L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cru= {0xC367502EAAC2A9L,0x17DA068B7D974B7L,0x2F4A34DEA341BC2L,0xD36F75C5738948L,0x6E94874605445L,0x12ADBAD28116AD1L,0x556556956L};
+public static final long[] CURVE_Pxa= {0x3CB3B62D7F2D86L,0x3F6AD9E57474F85L,0x1C90F562572EE81L,0x3214B55C96F51FCL,0x27CB1E746432501L,0x1FB00FA301E6425L,0x634D2240L};
+public static final long[] CURVE_Pxb= {0x3D9E41EC452DE15L,0x12ACA355FF9837BL,0xBA88E92D5D75B5L,0x3B6741732277F66L,0x3288361DD24F498L,0x592EBCDE9DC5L,0x300D78006L};
+public static final long[] CURVE_Pya= {0x68F0BB9408CB41L,0x27B793C83586597L,0x3ACA913A2E75B4L,0x359CF266CF9A25EL,0x33FE6347B6E990EL,0x34894D1F2527615L,0x33792CF93L};
+public static final long[] CURVE_Pyb= {0x2D846437F479093L,0x10F2C379889218EL,0x32F449F7BC98B01L,0x111ACFBEA3DEBC2L,0x3D15A7AE001CE0DL,0xB3631AC93B9EE9L,0x20E5247DDL};
+public static final long[][] CURVE_W= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_SB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+public static final long[][] CURVE_WB= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_BB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/BIG.java b/src/main/java/org/apache/milagro/amcl/BLS461/BIG.java
new file mode 100644
index 0000000..34077cc
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BLS461;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=58; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/DBIG.java b/src/main/java/org/apache/milagro/amcl/BLS461/DBIG.java
new file mode 100644
index 0000000..c4b639a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BLS461;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/ECDH.java b/src/main/java/org/apache/milagro/amcl/BLS461/ECDH.java
new file mode 100644
index 0000000..a4bce39
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BLS461;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/ECP.java b/src/main/java/org/apache/milagro/amcl/BLS461/ECP.java
new file mode 100644
index 0000000..cc790da
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BLS;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=NEGATIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/ECP2.java b/src/main/java/org/apache/milagro/amcl/BLS461/ECP2.java
new file mode 100644
index 0000000..0d3303c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/FP.java b/src/main/java/org/apache/milagro/amcl/BLS461/FP.java
new file mode 100644
index 0000000..992734e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=461; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<19);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/FP12.java b/src/main/java/org/apache/milagro/amcl/BLS461/FP12.java
new file mode 100644
index 0000000..0514cc3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/FP2.java b/src/main/java/org/apache/milagro/amcl/BLS461/FP2.java
new file mode 100644
index 0000000..28d70ed
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/FP4.java b/src/main/java/org/apache/milagro/amcl/BLS461/FP4.java
new file mode 100644
index 0000000..2f68288
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/MPIN.java b/src/main/java/org/apache/milagro/amcl/BLS461/MPIN.java
new file mode 100644
index 0000000..67890d5
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BLS461;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/PAIR.java b/src/main/java/org/apache/milagro/amcl/BLS461/PAIR.java
new file mode 100644
index 0000000..7d49bc0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BLS461;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS461/ROM.java b/src/main/java/org/apache/milagro/amcl/BLS461/ROM.java
new file mode 100644
index 0000000..c5c5ed1
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS461/ROM.java
@@ -0,0 +1,56 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BLS461;
+
+public class ROM
+{
+
+// Base Bits= 60
+public static final long[] Modulus= {0xAAC0000AAAAAAABL,0x20000555554AAAAL,0x6AA91557F004000L,0xA8DFFA5C1CC00F2L,0xACCA47B14848B42L,0x935FBD6F1E32D8BL,0xD5A555A55D69414L,0x15555545554L};
+public static final long[] R2modp= {0x96D08774614DDA8L,0xCD45F539225D5BDL,0xD712EB760C95AB1L,0xB3B687155F30B55L,0xC4E62A05C3F5B81L,0xBA1151676CA3CD0L,0x7EDD8A958F442BEL,0x12B89DD3F91L};
+public static final long MConst= 0xC0005FFFFFFFDL;
+
+public static final int CURVE_A= 0;
+public static final int CURVE_B_I= 9;
+public static final int CURVE_Cof_I= 0;
+public static final long[] CURVE_B= {0x9L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x1L,0x7FEFFFEFFFFC0L,0xC017FFC80001100L,0x7FE05FD000E801FL,0xFFFF7FFFC018001L,0xFFL,0x0L,0x0L};
+public static final long[] CURVE_Gx= {0x14D026A8ADEE93DL,0xF2D9C00EE74B741L,0x229C3981B531AC7L,0x6650D3564DC9218L,0x436166F7C292A09L,0x2CF668BE922B197L,0x463B73A0C813271L,0xAD0E74E99BL};
+public static final long[] CURVE_Gy= {0xF763157AD1D465L,0x5D17884C8C4FF47L,0x9D0A819E66B8D21L,0x910AE5C3245F495L,0x96EECB8BFA40B84L,0x277ACC8BF9F8CBEL,0x5F68C95F1C3F2FL,0x77BCDB14B3L};
+
+public static final long[] Fra= {0xF7117BF9B812A3AL,0xA1C6308A599C400L,0x5A6510E07505BF8L,0xB31ACE4858D45FAL,0xFC61EBC2CB04770L,0x366190D073588E2L,0x69E55E24DFEFA84L,0x12E40504B7FL};
+public static final long[] Frb= {0xB3AE8410F298071L,0x7E39D4CAFBAE6A9L,0x104404777AFE407L,0xF5C52C13C3EBAF8L,0xB0685BEE7D443D1L,0x5CFE2C9EAADA4A8L,0x6BBFF7807D79990L,0x27150409D5L};
+public static final long[] CURVE_Bnx= {0xFFBFFFE00000000L,0x1FFFFL,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cof= {0xAA7FFFEAAAAAAABL,0xFFD55AAAB01556AL,0x1555554FFL,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cru= {0x40001FFFFFFFEL,0x6FFFE7FFFFE0000L,0x6047200C47F0FFFL,0x777115796DB7BCCL,0x3F0E89875433CF4L,0xBFFF60500050261L,0x1FFFFFEL,0x0L};
+public static final long[] CURVE_Pxa= {0x65B503186D0A37CL,0xA9C2E492E75DCC4L,0x564E01F919D6878L,0x3F086DB74FF92FL,0xED78D46D581A668L,0x270C892F97C2907L,0x6A50A9AF679453CL,0x10CC54138A0L};
+public static final long[] CURVE_Pxb= {0x9F85CA8C2C1C0ADL,0x96CD66C425CADEL,0x1AC612951A2896L,0xB17D529ABEBEE24L,0xC5AF5BA09D33F65L,0x6A672E4D4371ED4L,0xACEA37CA279D224L,0x95C1FB4FE5L};
+public static final long[] CURVE_Pya= {0x7CCD0C1B02FB006L,0x953D194A4A12A33L,0x68B4960CFCC92C8L,0xBA0F3A9B00F39FCL,0xCDFD8A7DBBC5ED1L,0xE73ED227CC2F7A9L,0xEBA7E676070F4F4L,0x226AC848E7L};
+public static final long[] CURVE_Pyb= {0x8A506ADFDF1457CL,0xB4D6A31DC04C20AL,0x668EA9A8F136E3FL,0x12973C3BE4492F5L,0xA20BE74BEABA67AL,0x5157F04C42E3856L,0xBB402EA2AB1D004L,0xE38101B4FAL};
+public static final long[][] CURVE_W= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_SB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+public static final long[][] CURVE_WB= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_BB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/BIG.java b/src/main/java/org/apache/milagro/amcl/BLS48/BIG.java
new file mode 100644
index 0000000..dcc527a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BLS48;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=70; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/DBIG.java b/src/main/java/org/apache/milagro/amcl/BLS48/DBIG.java
new file mode 100644
index 0000000..f81bf5c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BLS48;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/ECDH.java b/src/main/java/org/apache/milagro/amcl/BLS48/ECDH.java
new file mode 100644
index 0000000..9146ab5
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BLS48;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/ECP.java b/src/main/java/org/apache/milagro/amcl/BLS48/ECP.java
new file mode 100644
index 0000000..280eb49
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BLS;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=POSITIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/ECP8.java b/src/main/java/org/apache/milagro/amcl/BLS48/ECP8.java
new file mode 100644
index 0000000..8b5885e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/ECP8.java
@@ -0,0 +1,930 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP8 */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class ECP8 {
+	private FP8 x;
+	private FP8 y;
+	private FP8 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP8() {
+//		INF=true;
+		x=new FP8(0);
+		y=new FP8(1);
+		z=new FP8(0);
+	}
+
+    public ECP8(ECP8 e) {
+        this.x = new FP8(e.x);
+        this.y = new FP8(e.y);
+        this.z = new FP8(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP8 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP8 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+//		boolean bd;
+//		if (d==0) bd=false;
+//		else bd=true;
+//		INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP8 W[],int b)
+	{
+		ECP8 MP=new ECP8(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP8 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP8 a=new FP8(x);                            // *****
+		FP8 b=new FP8(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP8 one=new FP8(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+
+/* extract affine x as FP8 */
+	public FP8 getX()
+	{
+		ECP8 W= new ECP8(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP8 */
+	public FP8 getY()
+	{
+		ECP8 W= new ECP8(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP8 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP8 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP8 getz()
+	{
+		return z;
+	}
+
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP8 W=new ECP8(this);
+		W.affine();
+		int MB=BIG.MODBYTES;
+
+		W.x.geta().geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i]=t[i];}
+		W.x.geta().geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+MB]=t[i];}
+		W.x.geta().getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+2*MB]=t[i];}
+		W.x.geta().getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+3*MB]=t[i];}
+
+		W.x.getb().geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+4*MB]=t[i];}
+		W.x.getb().geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+5*MB]=t[i];}
+		W.x.getb().getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+6*MB]=t[i];}
+		W.x.getb().getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+7*MB]=t[i];}
+
+
+		W.y.geta().geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+8*MB]=t[i];}
+		W.y.geta().geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+9*MB]=t[i];}
+		W.y.geta().getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+10*MB]=t[i];}
+		W.y.geta().getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+11*MB]=t[i];}
+	
+		W.y.getb().geta().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+12*MB]=t[i];}
+		W.y.getb().geta().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+13*MB]=t[i];}
+		W.y.getb().getb().getA().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+14*MB]=t[i];}
+		W.y.getb().getb().getB().toBytes(t);
+		for (int i=0;i<MB;i++) { b[i+15*MB]=t[i];}
+
+	}
+
+/* convert from byte array to point */
+	public static ECP8 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+		int MB=BIG.MODBYTES;
+
+		for (int i=0;i<MB;i++) {t[i]=b[i];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+MB];}
+		rb=BIG.fromBytes(t);
+
+		FP2 ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+2*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+3*MB];}
+		rb=BIG.fromBytes(t);
+
+		FP2 rb4=new FP2(ra,rb);
+
+		FP4 ra8=new FP4(ra4,rb4);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+4*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+5*MB];}
+		rb=BIG.fromBytes(t);
+
+		ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+6*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+7*MB];}
+		rb=BIG.fromBytes(t);
+
+		rb4=new FP2(ra,rb);
+
+		FP4 rb8=new FP4(ra4,rb4);
+
+		FP8 rx=new FP8(ra8,rb8);
+
+
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+8*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+9*MB];}
+		rb=BIG.fromBytes(t);
+
+		ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+10*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+11*MB];}
+		rb=BIG.fromBytes(t);
+
+		rb4=new FP2(ra,rb);
+
+		ra8=new FP4(ra4,rb4);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+12*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+13*MB];}
+		rb=BIG.fromBytes(t);
+
+		ra4=new FP2(ra,rb);
+
+		for (int i=0;i<MB;i++) {t[i]=b[i+14*MB];}
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<MB;i++) {t[i]=b[i+15*MB];}
+		rb=BIG.fromBytes(t);
+
+		rb4=new FP2(ra,rb);
+
+		rb8=new FP4(ra4,rb4);
+
+		FP8 ry=new FP8(ra8,rb8);
+
+		return new ECP8(rx,ry);
+	}
+
+/* convert this to hex string */
+	public String toString() {
+		ECP8 W=new ECP8(this);		
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP8 RHS(FP8 x) {
+		x.norm();
+		FP8 r=new FP8(x);
+		r.sqr();
+		FP8 b=new FP8(new FP4(new FP2(new BIG(ROM.CURVE_B))));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_i();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.times_i();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP8(FP8 ix,FP8 iy) {
+		x=new FP8(ix);
+		y=new FP8(iy);
+		z=new FP8(1);
+		FP8 rhs=RHS(x);
+		FP8 y2=new FP8(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+		//if (y2.equals(rhs)) INF=false;
+		//else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP8(FP8 ix) {
+		x=new FP8(ix);
+		y=new FP8(1);
+		z=new FP8(1);
+		FP8 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+		//	INF=false;
+		}
+		else {inf();/*x.zero();INF=true;*/}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+
+		FP8 iy=new FP8(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.times_i(); //iy.norm();
+		}
+		FP8 t0=new FP8(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.times_i();
+		}
+		FP8 t1=new FP8(iy);  
+		t1.mul(z);
+		FP8 t2=new FP8(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.times_i();
+			//t2.norm();
+		}
+
+		FP8 x3=new FP8(t2);
+		x3.mul(z); 
+
+		FP8 y3=new FP8(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP8 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+
+		int b=3*ROM.CURVE_B_I;
+		FP8 t0=new FP8(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP8 t1=new FP8(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP8 t2=new FP8(z);
+		t2.mul(Q.z);
+		FP8 t3=new FP8(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP8 t4=new FP8(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.times_i();  //t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP8 x3=new FP8(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.times_i(); //t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP8 y3=new FP8(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.times_i(); //t0.norm(); // x.Q.x
+			t1.times_i(); //t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.times_i();
+		}
+		FP8 z3=new FP8(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.times_i(); 
+			//y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP8 Q) {
+		ECP8 NQ=new ECP8(Q);
+		NQ.neg();
+		int D=add(NQ);
+
+//		Q.neg();
+//		int D=add(Q);
+//		Q.neg();
+		return D;
+	}
+
+	public static FP2[] frob_constants() {
+			BIG Fra=new BIG(ROM.Fra);
+			BIG Frb=new BIG(ROM.Frb);
+			FP2 X=new FP2(Fra,Frb);
+
+			FP2 F0=new FP2(X); F0.sqr();
+			FP2 F2=new FP2(F0);
+			F2.mul_ip(); F2.norm();
+			FP2 F1=new FP2(F2); F1.sqr();
+			F2.mul(F1);
+
+			F2.mul_ip(); F2.norm();
+
+			F1.copy(X);
+			if (ECP.SEXTIC_TWIST == ECP.M_TYPE)
+			{
+				F1.mul_ip();
+				F1.inverse();
+				F0.copy(F1); F0.sqr();
+			}
+			F0.mul_ip(); F0.norm();
+			F1.mul(F0);
+			FP2[] F={F0,F1,F2};
+			return F;
+	}
+
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 F[],int n)
+	{
+//		if (INF) return;
+		for (int i=0;i<n;i++) {
+			x.frob(F[2]);
+			x.qmul(F[0]);
+			if (ECP.SEXTIC_TWIST == ECP.M_TYPE) {
+				x.div_i2();
+			}
+			if (ECP.SEXTIC_TWIST == ECP.D_TYPE) {
+				x.times_i2();
+			}		
+
+			y.frob(F[2]);
+			y.qmul(F[1]);
+
+			if (ECP.SEXTIC_TWIST == ECP.M_TYPE) {
+				y.div_i();
+			}
+			if (ECP.SEXTIC_TWIST == ECP.D_TYPE) {
+				y.times_i2(); y.times_i2(); y.times_i();
+			}
+				z.frob(F[2]);
+		}
+	}
+
+/* P*=e */
+	public ECP8 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP8 P=new ECP8();
+		ECP8 Q=new ECP8();
+		ECP8 C=new ECP8();
+		ECP8[] W=new ECP8[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP8();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP8();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP8();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3... */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP8 mul16(ECP8[] Q,BIG[] u)
+	{
+		int i,j,k,nb,pb1,pb2,pb3,pb4;
+		ECP8 W=new ECP8();
+		ECP8 P=new ECP8();
+		ECP8[] T1=new ECP8[8];
+		ECP8[] T2=new ECP8[8];
+		ECP8[] T3=new ECP8[8];
+		ECP8[] T4=new ECP8[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[16];
+
+		byte[] w1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w3=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s3=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w4=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s4=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<16;i++)
+		{
+			t[i]=new BIG(u[i]);
+			//Q[i].affine();
+			t[i].norm();
+		}
+
+        T1[0] = new ECP8(); T1[0].copy(Q[0]);  // Q[0]
+        T1[1] = new ECP8(); T1[1].copy(T1[0]); T1[1].add(Q[1]);  // Q[0]+Q[1]
+        T1[2] = new ECP8(); T1[2].copy(T1[0]); T1[2].add(Q[2]);  // Q[0]+Q[2]
+        T1[3] = new ECP8(); T1[3].copy(T1[1]); T1[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T1[4] = new ECP8(); T1[4].copy(T1[0]); T1[4].add(Q[3]);  // Q[0]+Q[3]
+        T1[5] = new ECP8(); T1[5].copy(T1[1]); T1[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T1[6] = new ECP8(); T1[6].copy(T1[2]); T1[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T1[7] = new ECP8(); T1[7].copy(T1[3]); T1[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+//  Use Frobenius 
+		FP2[] F=ECP8.frob_constants();
+
+		for (i=0;i<8;i++) {
+			T2[i] = new ECP8(); T2[i].copy(T1[i]);
+			T2[i].frob(F,4);
+			T3[i] = new ECP8(); T3[i].copy(T2[i]);
+			T3[i].frob(F,4);
+			T4[i] = new ECP8(); T4[i].copy(T3[i]);
+			T4[i].frob(F,4);
+
+		}
+
+    // Make it odd
+        pb1=1-t[0].parity();
+        t[0].inc(pb1);
+        t[0].norm();
+
+        pb2=1-t[4].parity();
+        t[4].inc(pb2);
+        t[4].norm();
+
+        pb3=1-t[8].parity();
+        t[8].inc(pb3);
+        t[8].norm();
+
+        pb4=1-t[12].parity();
+        t[12].inc(pb4);
+        t[12].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<16;i++) {
+            mt.or(t[i]);
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s1[nb-1]=1;
+		s2[nb-1]=1;
+        s3[nb-1]=1;
+		s4[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s1[i]=(byte)(2*t[0].parity()-1);
+            t[4].fshr(1);
+            s2[i]=(byte)(2*t[4].parity()-1);
+            t[8].fshr(1);
+            s3[i]=(byte)(2*t[8].parity()-1);
+            t[12].fshr(1);
+            s4[i]=(byte)(2*t[12].parity()-1);
+ 
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w1[i]=0;
+            k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s1[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w1[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w2[i]=0;
+            k=1;
+            for (j=5; j<8; j++) {
+                byte bt=(byte)(s2[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w2[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w3[i]=0;
+            k=1;
+            for (j=9; j<12; j++) {
+                byte bt=(byte)(s3[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w3[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w4[i]=0;
+            k=1;
+            for (j=13; j<16; j++) {
+                byte bt=(byte)(s4[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w4[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+        } 
+
+    // Main loop
+        P.select(T1,(int)(2*w1[nb-1]+1));  
+		W.select(T2,(int)(2*w2[nb-1]+1)); 
+		P.add(W);
+		W.select(T3,(int)(2*w3[nb-1]+1));
+		P.add(W);
+		W.select(T4,(int)(2*w4[nb-1]+1));
+		P.add(W);
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T1,(int)(2*w1[i]+s1[i]));
+            P.add(W);
+            W.select(T2,(int)(2*w2[i]+s2[i]));
+            P.add(W);
+            W.select(T3,(int)(2*w3[i]+s3[i]));
+            P.add(W);
+            W.select(T4,(int)(2*w4[i]+s4[i]));
+            P.add(W);
+
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb1);   
+
+        W.copy(P);   
+        W.sub(Q[4]);
+        P.cmove(W,pb2);  
+
+        W.copy(P);   
+        W.sub(Q[8]);
+        P.cmove(W,pb3);   
+
+        W.copy(P);   
+        W.sub(Q[12]);
+        P.cmove(W,pb4);  
+
+		P.affine();
+		return P;
+	}        
+
+/* needed for SOK */
+	public static ECP8 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP8 X;
+		FP2 X2;
+		FP4 X4;
+		ECP8 Q;
+		x.mod(q);
+		while (true)
+		{
+			X2=new FP2(one,x);
+			X4=new FP4(X2);
+			X=new FP8(X4);
+			Q=new ECP8(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		FP2[] F=ECP8.frob_constants();
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+
+		ECP8 xQ=Q.mul(x);
+		ECP8 x2Q=xQ.mul(x);
+		ECP8 x3Q=x2Q.mul(x);
+		ECP8 x4Q=x3Q.mul(x);
+		ECP8 x5Q=x4Q.mul(x);
+		ECP8 x6Q=x5Q.mul(x);
+		ECP8 x7Q=x6Q.mul(x);
+		ECP8 x8Q=x7Q.mul(x);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			xQ.neg();
+			x3Q.neg();
+			x5Q.neg();
+			x7Q.neg();
+		}	
+
+		x8Q.sub(x7Q);
+		x8Q.sub(Q);
+
+		x7Q.sub(x6Q);
+		x7Q.frob(F,1);
+
+		x6Q.sub(x5Q);
+		x6Q.frob(F,2);
+
+		x5Q.sub(x4Q);
+		x5Q.frob(F,3);
+
+		x4Q.sub(x3Q);
+		x4Q.frob(F,4);
+
+		x3Q.sub(x2Q);
+		x3Q.frob(F,5);
+
+		x2Q.sub(xQ);
+		x2Q.frob(F,6);
+
+		xQ.sub(Q);
+		xQ.frob(F,7);
+
+		Q.dbl();
+		Q.frob(F,8);
+
+		Q.add(x8Q);
+		Q.add(x7Q);
+		Q.add(x6Q);
+		Q.add(x5Q);
+
+		Q.add(x4Q);
+		Q.add(x3Q);
+		Q.add(x2Q);
+		Q.add(xQ);
+
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP8 generator()
+	{
+		return new ECP8(
+			new FP8(
+				new FP4(
+					new FP2(
+						new BIG(ROM.CURVE_Pxaaa),new BIG(ROM.CURVE_Pxaab)),
+					new FP2(
+						new BIG(ROM.CURVE_Pxaba),new BIG(ROM.CURVE_Pxabb))),
+				new FP4(
+					new FP2(
+						new BIG(ROM.CURVE_Pxbaa),new BIG(ROM.CURVE_Pxbab)),
+					new FP2(
+						new BIG(ROM.CURVE_Pxbba),new BIG(ROM.CURVE_Pxbbb)))),
+			new FP8(
+				new FP4(
+					new FP2(
+						new BIG(ROM.CURVE_Pyaaa),new BIG(ROM.CURVE_Pyaab)),
+					new FP2(
+						new BIG(ROM.CURVE_Pyaba),new BIG(ROM.CURVE_Pyabb))),
+				new FP4(
+					new FP2(
+						new BIG(ROM.CURVE_Pybaa),new BIG(ROM.CURVE_Pybab)),
+					new FP2(
+						new BIG(ROM.CURVE_Pybba),new BIG(ROM.CURVE_Pybbb)))));
+
+	}
+
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP.java
new file mode 100644
index 0000000..866c8d8
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=556; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP16.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP16.java
new file mode 100644
index 0000000..728e940
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP16.java
@@ -0,0 +1,563 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^16 functions */
+
+/* FP16 elements are of the form a+ib, where i is sqrt(sqrt(sqrt(-1+sqrt(-1))))  */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP16 {
+	private final FP8 a;
+	private final FP8 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP16 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP8 one=new FP8(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP8 real()
+	{
+		return a;
+	}
+
+	public FP8 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP8 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP16 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP16(int c)
+	{
+		a=new FP8(c);
+		b=new FP8(0);
+	}
+
+	public FP16(FP16 x)
+	{
+		a=new FP8(x.a);
+		b=new FP8(x.b);
+	}
+
+	public FP16(FP8 c,FP8 d)
+	{
+		a=new FP8(c);
+		b=new FP8(d);
+	}
+
+	public FP16(FP8 c)
+	{
+		a=new FP8(c);
+		b=new FP8(0);
+	}
+/* copy this=x */
+	public void copy(FP16 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP8 m=new FP8(a);
+		FP8 t=new FP8(0);
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP16 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP16 x)
+	{
+		FP16 m=new FP16(x);
+		m.neg();
+		add(m);
+	}
+
+/* this=x-this */
+	public void rsub(FP16 x)
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s where s is FP8 */
+	public void pmul(FP8 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+/* this*=s where s is FP2 */
+	public void qmul(FP2 s)
+	{
+		a.qmul(s);
+		b.qmul(s);
+	}
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP8 t1=new FP8(a);
+		FP8 t2=new FP8(b);
+		FP8 t3=new FP8(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.times_i();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.times_i();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+
+/* this*=y */
+	public void mul(FP16 y)
+	{
+//		norm();
+
+		FP8 t1=new FP8(a);
+		FP8 t2=new FP8(b);
+		FP8 t3=new FP8(0);
+		FP8 t4=new FP8(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+		t3.norm();
+		t4.norm();
+
+		t4.mul(t3);
+
+		t3.copy(t1);
+		t3.neg();
+		t4.add(t3);
+		t4.norm();
+
+		t3.copy(t2);
+		t3.neg();
+		b.copy(t4);
+		b.add(t3);
+
+		t2.times_i();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP8 t1=new FP8(a);
+		FP8 t2=new FP8(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.times_i();
+		t2.norm();
+		t1.sub(t2); t1.norm();
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+		t1.norm();
+		b.mul(t1);
+	}
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP8 s=new FP8(b);
+		FP8 t=new FP8(a);
+		s.times_i();
+		b.copy(t);
+		a.copy(s);
+		norm();
+	}
+
+	public void times_i2()
+	{
+		a.times_i();
+		b.times_i();
+	}
+
+	public void times_i4()
+	{
+		a.times_i2();
+		b.times_i2();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 ff=new FP2(f); ff.sqr(); ff.norm();
+
+		a.frob(ff);
+		b.frob(ff);
+		b.qmul(f);
+		b.times_i();
+	}
+
+/* this=this^e */
+	public FP16 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP16 w=new FP16(this);
+		BIG z=new BIG(e);
+		FP16 r=new FP16(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+
+/* XTR xtr_a function */
+	public void xtr_A(FP16 w,FP16 y,FP16 z) 
+	{
+		FP16 r=new FP16(w);
+		FP16 t=new FP16(w);
+	
+		r.sub(y);
+		r.norm();
+		r.pmul(a);
+		t.add(y);
+		t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP16 w=new FP16(this);
+		sqr(); w.conj();
+		w.add(w);
+		w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP16 xtr_pow(BIG n) {
+		FP16 a=new FP16(3);
+		FP16 b=new FP16(this);
+		FP16 c=new FP16(b);
+		c.xtr_D();
+		FP16 t=new FP16(0);
+		FP16 r=new FP16(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP16 xtr_pow2(FP16 ck,FP16 ckml,FP16 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP16 cu=new FP16(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP2.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP2.java
new file mode 100644
index 0000000..c27129f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP4.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP4.java
new file mode 100644
index 0000000..6e672a3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP48.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP48.java
new file mode 100644
index 0000000..25c5abd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP48.java
@@ -0,0 +1,1057 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^48 functions */
+/* FP48 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP48 {
+	private final FP16 a;
+	private final FP16 b;
+	private final FP16 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP48 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP48 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP48 invf=new FP48(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+	/* test x==1 ? */
+	public boolean isunity() {
+		FP16 one=new FP16(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP48 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP16 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP16 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP16 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP48 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP48(FP16 d)
+	{
+		a=new FP16(d);
+		b=new FP16(0);
+		c=new FP16(0);
+	}
+
+	public FP48(int d)
+	{
+		a=new FP16(d);
+		b=new FP16(0);
+		c=new FP16(0);
+	}
+
+	public FP48(FP16 d,FP16 e,FP16 f)
+	{
+		a=new FP16(d);
+		b=new FP16(e);
+		c=new FP16(f);
+	}
+
+	public FP48(FP48 x)
+	{
+		a=new FP16(x.a);
+		b=new FP16(x.b);
+		c=new FP16(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+		FP16 A=new FP16(a);
+		FP16 B=new FP16(c);
+		FP16 C=new FP16(b);
+		FP16 D=new FP16(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+		reduce();
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+		FP16 A=new FP16(a);
+		FP16 B=new FP16(b);
+		FP16 C=new FP16(c);
+		FP16 D=new FP16(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+		B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+		c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP48 y)
+	{
+		FP16 z0=new FP16(a);
+		FP16 z1=new FP16(0);
+		FP16 z2=new FP16(b);
+		FP16 z3=new FP16(0);
+		FP16 t0=new FP16(a);
+		FP16 t1=new FP16(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+		t0.norm();
+		t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+		t0.norm();
+		t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+		t0.norm();
+		t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+		z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP48 y,int type)
+	{
+		if (type==ECP.D_TYPE)
+		{
+			FP16 z0=new FP16(a);
+			FP16 z2=new FP16(b);
+			FP16 z3=new FP16(b);
+			FP16 t0=new FP16(0);
+			FP16 t1=new FP16(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP16 z0=new FP16(a);
+			FP16 z1=new FP16(0);
+			FP16 z2=new FP16(0);
+			FP16 z3=new FP16(0);
+			FP16 t0=new FP16(a);
+			FP16 t1=new FP16(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP16 f0=new FP16(a);
+		FP16 f1=new FP16(b);
+		FP16 f2=new FP16(a);
+		FP16 f3=new FP16(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+		f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+		f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+		f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+		f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f,int n)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		f3.mul_ip(); f3.norm();
+		f3.mul_ip(); f3.norm();
+
+		for (int i=0;i<n;i++)
+		{
+			a.frob(f3);
+			b.frob(f3);
+			c.frob(f3);
+
+			b.qmul(f); b.times_i4(); b.times_i2(); 
+			c.qmul(f2); c.times_i4(); c.times_i4(); c.times_i4(); 
+		}
+	}
+
+/* trace function */
+	public FP16 trace()
+	{
+		FP16 t=new FP16(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP48 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 ea,eb;
+		FP8 fa,fb;
+		FP16 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fa=new FP8(ea,eb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+12*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+13*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+14*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+15*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fb=new FP8(ea,eb);
+
+		e=new FP16(fa,fb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+16*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+17*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+18*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+19*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+20*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+21*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+22*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+23*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fa=new FP8(ea,eb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+24*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+25*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+26*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+27*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+28*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+29*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+30*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+31*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fb=new FP8(ea,eb);
+
+		f=new FP16(fa,fb);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+32*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+33*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+34*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+35*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+36*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+37*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+38*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+39*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fa=new FP8(ea,eb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+40*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+41*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+42*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+43*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		ea=new FP4(c,d);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+44*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+45*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+46*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+47*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		eb=new FP4(c,d);
+
+		fb=new FP8(ea,eb);
+
+		g=new FP16(fa,fb);
+
+		return new FP48(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+
+		a.geta().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.geta().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.geta().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		a.geta().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		a.geta().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		a.geta().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		a.geta().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+		a.getb().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		a.getb().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		a.getb().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		a.getb().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+		a.getb().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+12*BIG.MODBYTES]=t[i];
+		a.getb().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+13*BIG.MODBYTES]=t[i];
+		a.getb().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+14*BIG.MODBYTES]=t[i];
+		a.getb().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+15*BIG.MODBYTES]=t[i];
+
+		b.geta().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+16*BIG.MODBYTES]=t[i];
+		b.geta().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+17*BIG.MODBYTES]=t[i];
+		b.geta().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+18*BIG.MODBYTES]=t[i];
+		b.geta().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+19*BIG.MODBYTES]=t[i];
+
+		b.geta().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+20*BIG.MODBYTES]=t[i];
+		b.geta().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+21*BIG.MODBYTES]=t[i];
+		b.geta().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+22*BIG.MODBYTES]=t[i];
+		b.geta().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+23*BIG.MODBYTES]=t[i];
+		b.getb().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+24*BIG.MODBYTES]=t[i];
+		b.getb().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+25*BIG.MODBYTES]=t[i];
+		b.getb().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+26*BIG.MODBYTES]=t[i];
+		b.getb().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+27*BIG.MODBYTES]=t[i];
+		b.getb().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+28*BIG.MODBYTES]=t[i];
+		b.getb().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+29*BIG.MODBYTES]=t[i];
+		b.getb().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+30*BIG.MODBYTES]=t[i];
+		b.getb().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+31*BIG.MODBYTES]=t[i];
+
+
+		c.geta().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+32*BIG.MODBYTES]=t[i];
+		c.geta().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+33*BIG.MODBYTES]=t[i];
+		c.geta().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+34*BIG.MODBYTES]=t[i];
+		c.geta().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+35*BIG.MODBYTES]=t[i];
+		c.geta().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+36*BIG.MODBYTES]=t[i];
+		c.geta().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+37*BIG.MODBYTES]=t[i];
+		c.geta().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+38*BIG.MODBYTES]=t[i];
+		c.geta().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+39*BIG.MODBYTES]=t[i];
+		c.getb().geta().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+40*BIG.MODBYTES]=t[i];
+		c.getb().geta().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+41*BIG.MODBYTES]=t[i];
+		c.getb().geta().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+42*BIG.MODBYTES]=t[i];
+		c.getb().geta().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+43*BIG.MODBYTES]=t[i];
+		c.getb().getb().geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+44*BIG.MODBYTES]=t[i];
+		c.getb().getb().geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+45*BIG.MODBYTES]=t[i];
+		c.getb().getb().getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+46*BIG.MODBYTES]=t[i];
+		c.getb().getb().getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+47*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP48 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP48 w=new FP48(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP48 [] R=new FP48[2];
+		R[0]=new FP48(1);
+		R[1]=new FP48(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP16 compow(BIG e,BIG r)
+	{
+		FP48 g1=new FP48(0);
+		FP48 g2=new FP48(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP16 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f,1);
+		FP16 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP16 cpm1=g2.trace();
+		g2.mul(g1);
+		FP16 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3.... */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP48 pow16(FP48[] q,BIG[] u)
+	{
+		int i,j,k,nb,pb1,pb2,pb3,pb4;
+		FP48 [] g1=new FP48[8];
+		FP48 [] g2=new FP48[8];
+		FP48 [] g3=new FP48[8];
+		FP48 [] g4=new FP48[8];
+		FP48 r=new FP48(1);
+		FP48 p=new FP48(0);
+		BIG [] t=new BIG[16];
+		BIG mt=new BIG(0);
+		byte[] w1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s1=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s2=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w3=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s3=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] w4=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s4=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<16;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+
+		g1[0]=new FP48(q[0]);  // q[0]
+		g1[1]=new FP48(g1[0]); g1[1].mul(q[1]); // q[0].q[1]
+		g1[2]=new FP48(g1[0]); g1[2].mul(q[2]); // q[0].q[2]
+		g1[3]=new FP48(g1[1]); g1[3].mul(q[2]); // q[0].q[1].q[2]
+		g1[4]=new FP48(q[0]);  g1[4].mul(q[3]); // q[0].q[3]
+		g1[5]=new FP48(g1[1]); g1[5].mul(q[3]); // q[0].q[1].q[3]
+		g1[6]=new FP48(g1[2]); g1[6].mul(q[3]); // q[0].q[2].q[3]
+		g1[7]=new FP48(g1[3]); g1[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+// Use Frobenius
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		for (i=0;i<8;i++)
+		{
+			g2[i]=new FP48(g1[i]);
+			g2[i].frob(f,4);
+			g3[i]=new FP48(g2[i]);
+			g3[i].frob(f,4);
+			g4[i]=new FP48(g3[i]);
+			g4[i].frob(f,4);
+		}
+
+    // Make it odd
+        pb1=1-t[0].parity();
+        t[0].inc(pb1);
+        t[0].norm();
+
+        pb2=1-t[4].parity();
+        t[4].inc(pb2);
+        t[4].norm();
+
+        pb3=1-t[8].parity();
+        t[8].inc(pb3);
+        t[8].norm();
+
+        pb4=1-t[12].parity();
+        t[12].inc(pb4);
+        t[12].norm();
+
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<16;i++) {
+            mt.or(t[i]);
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s1[nb-1]=1;
+		s2[nb-1]=1;
+        s3[nb-1]=1;
+		s4[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s1[i]=(byte)(2*t[0].parity()-1);
+            t[4].fshr(1);
+            s2[i]=(byte)(2*t[4].parity()-1);
+            t[8].fshr(1);
+            s3[i]=(byte)(2*t[8].parity()-1);
+            t[12].fshr(1);
+            s4[i]=(byte)(2*t[12].parity()-1);
+ 
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w1[i]=0;
+            k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s1[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w1[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w2[i]=0;
+            k=1;
+            for (j=5; j<8; j++) {
+                byte bt=(byte)(s2[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w2[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w3[i]=0;
+            k=1;
+            for (j=9; j<12; j++) {
+                byte bt=(byte)(s3[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w3[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+            w4[i]=0;
+            k=1;
+            for (j=13; j<16; j++) {
+                byte bt=(byte)(s4[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w4[i]+=bt*(byte)k;
+                k*=2;
+            }
+
+        } 
+
+
+     // Main loop
+        p.select(g1,(int)(2*w1[nb-1]+1)); 
+		r.select(g2,(int)(2*w2[nb-1]+1)); 
+		p.mul(r);
+		r.select(g3,(int)(2*w3[nb-1]+1)); 
+		p.mul(r);
+		r.select(g4,(int)(2*w4[nb-1]+1)); 
+		p.mul(r);
+
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g1,(int)(2*w1[i]+s1[i]));
+            p.mul(r);
+            r.select(g2,(int)(2*w2[i]+s2[i]));
+            p.mul(r);
+            r.select(g3,(int)(2*w3[i]+s3[i]));
+            p.mul(r);
+            r.select(g4,(int)(2*w4[i]+s4[i]));
+            p.mul(r);
+
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb1);
+
+        r.copy(q[4]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb2);
+
+        r.copy(q[8]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb3);
+
+        r.copy(q[12]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb4);
+
+ 		p.reduce();
+		return p;
+	}              
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/FP8.java b/src/main/java/org/apache/milagro/amcl/BLS48/FP8.java
new file mode 100644
index 0000000..145ecfa
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/FP8.java
@@ -0,0 +1,656 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^8 functions */
+
+/* FP8 elements are of the form a+ib, where i is sqrt(sqrt(-1+sqrt(-1)))  */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class FP8 {
+	private final FP4 a;
+	private final FP4 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP8 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP4 real()
+	{
+		return a;
+	}
+
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP8 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP8(int c)
+	{
+		a=new FP4(c);
+		b=new FP4(0);
+	}
+
+	public FP8(FP8 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+	}
+
+	public FP8(FP4 c,FP4 d)
+	{
+		a=new FP4(c);
+		b=new FP4(d);
+	}
+
+	public FP8(FP4 c)
+	{
+		a=new FP4(c);
+		b=new FP4(0);
+	}
+/* copy this=x */
+	public void copy(FP8 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP4 m=new FP4(a);
+		FP4 t=new FP4(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP8 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP8 x)
+	{
+		FP8 m=new FP8(x);
+		m.neg();
+		add(m);
+	}
+
+/* this=x-this */
+	public void rsub(FP8 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=s where s is FP4 */
+	public void pmul(FP4 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+/* this*=s where s is FP2 */
+	public void qmul(FP2 s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+/* this*=s where s is FP */
+	public void tmul(FP s)
+	{
+		a.qmul(s);
+		b.qmul(s);
+	}
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+		FP4 t3=new FP4(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.times_i();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.times_i();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+
+/* this*=y */
+	public void mul(FP8 y)
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+		FP4 t3=new FP4(0);
+		FP4 t4=new FP4(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+		t3.norm();
+		t4.norm();
+
+		t4.mul(t3);
+
+		t3.copy(t1);
+		t3.neg();
+		t4.add(t3);
+		t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+		t3.copy(t2);
+		t3.neg();
+		b.copy(t4);
+		b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.times_i();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP4 t1=new FP4(a);
+		FP4 t2=new FP4(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.times_i();
+		t2.norm();
+		t1.sub(t2); t1.norm();
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+		t1.norm();
+		b.mul(t1);
+	}
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP4 s=new FP4(b);
+		FP4 t=new FP4(a);
+		s.times_i();
+
+		b.copy(t);
+		a.copy(s);
+		norm();
+	}
+
+	public void times_i2()
+	{
+		a.times_i();
+		b.times_i();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 ff=new FP2(f); ff.sqr(); ff.mul_ip(); ff.norm();
+
+		a.frob(ff);
+		b.frob(ff);
+		b.pmul(f);
+		b.times_i();
+
+	}
+
+/* this=this^e */
+	public FP8 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP8 w=new FP8(this);
+		BIG z=new BIG(e);
+		FP8 r=new FP8(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+
+/* XTR xtr_a function */
+	public void xtr_A(FP8 w,FP8 y,FP8 z) 
+	{
+		FP8 r=new FP8(w);
+		FP8 t=new FP8(w);
+	
+		r.sub(y);
+		r.norm();
+		r.pmul(a);
+		t.add(y);
+		t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP8 w=new FP8(this);
+		sqr(); w.conj();
+		w.add(w);
+		w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP8 xtr_pow(BIG n) {
+		FP8 a=new FP8(3);
+		FP8 b=new FP8(this);
+		FP8 c=new FP8(b);
+		c.xtr_D();
+		FP8 t=new FP8(0);
+		FP8 r=new FP8(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP8 xtr_pow2(FP8 ck,FP8 ckml,FP8 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP8 cu=new FP8(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP4 u=new FP4(a);
+		FP4 v=new FP4(b);
+		u.div_i();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_i2() {
+		a.div_i();
+		b.div_i();
+	}
+
+	public void div_2i() {
+		FP4 u=new FP4(a);
+		FP4 v=new FP4(b);
+		u.div_2i();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP4 wa=new FP4(a);
+		FP4 ws=new FP4(b);
+		FP4 wt=new FP4(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_i();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.times_i();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/MPIN256.java b/src/main/java/org/apache/milagro/amcl/BLS48/MPIN256.java
new file mode 100644
index 0000000..9a42266
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/MPIN256.java
@@ -0,0 +1,815 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BLS48;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN256
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP16 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[18*EFS];
+		byte[] h=null;
+		c.geta().geta().geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().geta().geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.geta().geta().getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.geta().geta().getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+		c.geta().getb().geta().getA().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		c.geta().getb().geta().getB().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		c.geta().getb().getb().getA().toBytes(w); for (int i=6*EFS;i<7*EFS;i++) t[i]=w[i-6*EFS];
+		c.geta().getb().getb().getB().toBytes(w); for (int i=7*EFS;i<8*EFS;i++) t[i]=w[i-7*EFS];
+
+		c.getb().geta().geta().getA().toBytes(w); for (int i=8*EFS;i<9*EFS;i++) t[i]=w[i-8*EFS];
+		c.getb().geta().geta().getB().toBytes(w); for (int i=9*EFS;i<10*EFS;i++) t[i]=w[i-9*EFS];
+		c.getb().geta().getb().getA().toBytes(w); for (int i=10*EFS;i<11*EFS;i++) t[i]=w[i-10*EFS];
+		c.getb().geta().getb().getB().toBytes(w); for (int i=11*EFS;i<12*EFS;i++) t[i]=w[i-11*EFS];
+		c.getb().getb().geta().getA().toBytes(w); for (int i=12*EFS;i<13*EFS;i++) t[i]=w[i-12*EFS];
+		c.getb().getb().geta().getB().toBytes(w); for (int i=13*EFS;i<14*EFS;i++) t[i]=w[i-13*EFS];
+		c.getb().getb().getb().getA().toBytes(w); for (int i=14*EFS;i<15*EFS;i++) t[i]=w[i-14*EFS];
+		c.getb().getb().getb().getB().toBytes(w); for (int i=15*EFS;i<16*EFS;i++) t[i]=w[i-15*EFS];
+	
+		
+
+		U.getX().toBytes(w); for (int i=16*EFS;i<17*EFS;i++) t[i]=w[i-16*EFS];
+		U.getY().toBytes(w); for (int i=17*EFS;i<18*EFS;i++) t[i]=w[i-17*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP8 P=ECP8.fromBytes(W1);
+		ECP8 Q=ECP8.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR256.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR256.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR256.G1mul(W,x);
+				P.add(W); //P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR256.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR256.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP8 Q=ECP8.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR256.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR256.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR256.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID,false);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP8 Q=ECP8.generator();
+
+		ECP8 sQ=ECP8.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR256.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP48 g;
+
+		g=PAIR256.ate2(Q,R,sQ,P);
+		g=PAIR256.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR256.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR256.ate(Q,P);
+				g=PAIR256.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP48 ge=FP48.fromBytes(E);
+		FP48 gf=FP48.fromBytes(F);
+		int[] distance = new int[TS];
+		FP48 t=new FP48(gf);
+		FP48[] table=new FP48[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP48(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP48 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP8 Q=ECP8.generator();
+
+		g=PAIR256.ate(Q,T);
+		g=PAIR256.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR256.ate(Q,P);
+		g=PAIR256.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP48 g1=FP48.fromBytes(G1);
+		FP48 g2=FP48.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR256.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP16 c=g1.compow(z,r);
+
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP8 sQ=ECP8.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR256.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR256.G1mul(U,w);
+		FP48 g=PAIR256.ate(sQ,R);
+		g=PAIR256.fexp(g);
+
+		FP16 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/PAIR256.java b/src/main/java/org/apache/milagro/amcl/BLS48/PAIR256.java
new file mode 100644
index 0000000..f80c41b
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/PAIR256.java
@@ -0,0 +1,628 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BLS48;
+
+public final class PAIR256 {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP48 line(ECP8 A,ECP8 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP16 a,b,c;                            // Edits here
+//		c=new FP16(0);
+		if (A==B)
+		{ // Doubling
+			FP8 XX=new FP8(A.getx());  //X
+			FP8 YY=new FP8(A.gety());  //Y
+			FP8 ZZ=new FP8(A.getz());  //Z
+			FP8 YZ=new FP8(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.tmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.tmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_2i();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.times_i();
+				ZZ.add(ZZ);
+				YZ.times_i();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP16(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP16(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP16(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP16(0);
+				c=new FP16(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP8 X1=new FP8(A.getx());    // X1
+			FP8 Y1=new FP8(A.gety());    // Y1
+			FP8 T1=new FP8(A.getz());    // Z1
+			FP8 T2=new FP8(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.tmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.times_i();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.tmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP16(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP16(Y1);
+				c=new FP16(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP16(0);
+				c=new FP16(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP48(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP48 ate(ECP8 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		FP48 lv;
+		int bt;
+		
+		ECP8 P=new ECP8(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP8 A=new ECP8();
+		FP48 r=new FP48(1);
+		A.copy(P);
+
+		ECP8 MP=new ECP8();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP48 ate2(ECP8 P1,ECP Q1,ECP8 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		FP48 lv;
+		int bt;
+
+		ECP8 P=new ECP8(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP8 R=new ECP8(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP8 A=new ECP8();
+		ECP8 B=new ECP8();
+		FP48 r=new FP48(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP8 MP=new ECP8();
+		MP.copy(P); MP.neg();
+		ECP8 MR=new ECP8();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP48 fexp(FP48 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP48 r=new FP48(m);
+
+/* Easy part of final exp */
+		FP48 lv=new FP48(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f,8);
+		r.mul(lv);
+
+		FP48 t0,t1,t2,t3,t4,t5,t6,t7;
+/* Hard part of final exp */	
+// Ghamman & Fouotsa Method
+
+		t7=new FP48(r); t7.usqr();
+		t1=t7.pow(x);
+
+		x.fshr(1);
+		t2=t1.pow(x);
+		x.fshl(1);
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3=new FP48(t1); t3.conj();
+		t2.mul(t3);
+		t2.mul(r);
+
+		r.mul(t7);
+
+		t1=t2.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+		t3.copy(t1);
+		t3.frob(f,14);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,13);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,12);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,11);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,10);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,9);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,8);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t2); t3.conj();
+		t1.mul(t3);
+		t3.copy(t1);
+		t3.frob(f,7);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,6);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,5);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,4);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,3);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,2);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+
+		t3.copy(t1);
+		t3.frob(f,1);
+		r.mul(t3);
+		t1=t1.pow(x);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX) {
+			t1.conj();
+		}
+	
+		r.mul(t1);
+		t2.frob(f,15);
+		r.mul(t2);
+
+		r.reduce();
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+// -(x^8).P = (Beta.x,y)
+		BIG q=new BIG(ROM.CURVE_Order);
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG x2=BIG.smul(x,x);
+		x=BIG.smul(x2,x2);
+		x2=BIG.smul(x,x);
+		u[0]=new BIG(e);
+		u[0].mod(x2);
+		u[1]=new BIG(e);
+		u[1].div(x2);
+		u[1].rsub(q);
+
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[16];
+
+		BIG q=new BIG(ROM.CURVE_Order);
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG w=new BIG(e);
+		for (int i=0;i<15;i++)
+		{
+			u[i]=new BIG(w);
+			u[i].mod(x);
+			w.div(x);
+		}
+		u[15]=new BIG(w);
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			u[1].copy(BIG.modneg(u[1],q));
+			u[3].copy(BIG.modneg(u[3],q));
+			u[5].copy(BIG.modneg(u[5],q));
+			u[7].copy(BIG.modneg(u[7],q));
+			u[9].copy(BIG.modneg(u[9],q));
+			u[11].copy(BIG.modneg(u[11],q));
+			u[13].copy(BIG.modneg(u[13],q));
+			u[15].copy(BIG.modneg(u[15],q));
+		}
+
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP(); 
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP8 G2mul(ECP8 P,BIG e)
+	{
+		ECP8 R;
+		if (USE_GS_G2)
+		{
+			ECP8[] Q=new ECP8[16];
+			FP2[] F=ECP8.frob_constants();
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP8(); Q[0].copy(P);
+			for (i=1;i<16;i++)
+			{
+				Q[i]=new ECP8(); Q[i].copy(Q[i-1]);
+				Q[i].frob(F,1);
+			}
+			for (i=0;i<16;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();
+				//Q[i].affine();
+			}
+
+			R=ECP8.mul16(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP16.java */
+	public static FP48 GTpow(FP48 d,BIG e)
+	{
+		FP48 r;
+		if (USE_GS_GT)
+		{
+			FP48[] g=new FP48[16];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP48(d);
+			for (i=1;i<16;i++)
+			{
+				g[i]=new FP48(0); g[i].copy(g[i-1]);
+				g[i].frob(f,1);
+			}
+			for (i=0;i<16;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP48.pow16(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BLS48/ROM.java b/src/main/java/org/apache/milagro/amcl/BLS48/ROM.java
new file mode 100644
index 0000000..cbe6fa7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BLS48/ROM.java
@@ -0,0 +1,68 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BLS48;
+
+public class ROM
+{
+
+// Base Bits= 58
+	public static final long[] Modulus= {0x2F6E60FFCF6AC0BL,0x259C02699877E7BL,0x37A9870D4228402L,0x80821A1DACBB04L,0x13016A7C025A415L,0x2BB355ACDE6E250L,0x20536F405DA950L,0x295B219C54AB351L,0x3FCFC5B23729047L,0x3F45F610BL};
+	public static final long[] R2modp= {0x25E03FA0D59D0FAL,0x6B55DC2DE8FD41L,0xA0E01D0B937F48L,0x20336279F50EFCEL,0x2212822A3470A2FL,0xD5A21C4F9FB72DL,0x89E8F0A1CFD9F8L,0x2291DA62B48793L,0x3DC6978EF609E61L,0x1735D29EL};
+	public static final long MConst= 0x21BFCBCA9DA805DL;
+	public static final long[] Fra= {0x2623CFD9325BF89L,0x341FA8DCCD0A56FL,0x1952FBA0E83BCCAL,0xBE3C26F8D1D297L,0x27F84ABE7AB9F2CL,0x13BDE945C9DECEBL,0x3B3213C83C0F60BL,0x3B7F0411FF27FF7L,0x80089C089BB36CL,0xA62E01EEL};
+	public static final long[] Frb= {0x2623CFD9325BF89L,0x341FA8DCCD0A56FL,0x1952FBA0E83BCCAL,0xBE3C26F8D1D297L,0x27F84ABE7AB9F2CL,0x13BDE945C9DECEBL,0x3B3213C83C0F60BL,0x3B7F0411FF27FF7L,0x80089C089BB36CL,0xA62E01EEL};
+
+	public static final int CURVE_A= 0;
+	public static final int CURVE_B_I= 17;
+	public static final int CURVE_Cof_I= 0;
+	public static final long[] CURVE_B= {0x11L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0x2FFFF0000000001L,0x11550278A769C21L,0x14D1EB162029C21L,0x2309B4A2B6307F4L,0x34790BD26DFED78L,0x2C6FE3F2571037BL,0x1306A973C465FB0L,0x28446ABB18DF17AL,0xC43BF73EL,0x0L};
+	public static final long[] CURVE_Gx= {0x3286D2F65D71D33L,0x3601553F8CB783FL,0xFF01647711EE0BL,0x268BC07F29FD8CCL,0xE0702E69A80F66L,0x285003EAC056511L,0x35E130D242B2C3AL,0x107024C87924166L,0x17595DB8957EDD7L,0x26A27A4A1L};
+	public static final long[] CURVE_Gy= {0x29A5B3FEA6ED83AL,0x3712E552A29C33DL,0x3391EA8E6958677L,0x29F3C7B9DED7E3EL,0x4E2E3818FB7229L,0x1CC30999551E32DL,0xE67A4086260E3CL,0x2A68CCB8579C437L,0x62C5FAE2B3349DL,0x2B634253L};
+
+	public static final long[] CURVE_Bnx= {0x7DE40020L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cof= {0xA2D10F7F12ABEBL,0x5L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cru= {0x364E7E6CBBA429L,0x338C28A4D3DD160L,0x28DC3C68308093AL,0x230B290AE0E768L,0x127B0AB9B73BC2DL,0x23192337B1A639CL,0x1E399AEEFF04AE3L,0x20C88F0091318E5L,0x37CEF23203A79F7L,0x3F45F60F3L};
+	public static final long[] CURVE_Pxaaa= {0x28D2E8E8923CE4AL,0x2F5C40B4AE04F4AL,0x2165D8A1313A20CL,0x2BFC7FD18DF074FL,0x12B37F0A7C90B98L,0x286ED92CE57BD37L,0x1C416C4ABF57375L,0x39779D0B2EE2172L,0x1A1C0497A5D9487L,0x3995E3602L};
+	public static final long[] CURVE_Pxaab= {0x271CDC5AC0A1BE1L,0x2A3F8EC01DF5FDCL,0xAD5478433972C5L,0x22B73FAE2491D8CL,0x30E75C6B40A11FAL,0xE960C8FF259C26L,0x8CE48632D18B04L,0x39549A6BC27F419L,0x274A97B58DB48B6L,0xA5080497L};
+	public static final long[] CURVE_Pxaba= {0x23A724C770C5DC4L,0x2A592B776B3BCB6L,0x110934259BEC736L,0x18E2C5A649AB2A8L,0x2B84CB2C58CD55L,0x168195F91EE8B90L,0xF7D917CE233167L,0x2A38FB7729335BDL,0x36D71DDA78B689BL,0x2D4BFBE3DL};
+	public static final long[] CURVE_Pxabb= {0xD629669A64B740L,0x47F52632481578L,0x40D7054323ADD1L,0x3F9F4CCCD789E1BL,0x1E3C73C41F4EEA7L,0x15E7D7A61968610L,0x1B4186B40590D3BL,0x19F3BA577306AAFL,0x12DFE5F23F63B1AL,0x24E102A76L};
+	public static final long[] CURVE_Pxbaa= {0x1BB0C6172F1E01FL,0x30C4734D2C29802L,0x990FA39218788L,0xEEB80ED6AE2501L,0x34728852870C80BL,0x94841D1637D478L,0x21CBCE27C3AD4D4L,0xA29F9E111E6AD5L,0x18CF1447CC49D3L,0x37787BDFDL};
+	public static final long[] CURVE_Pxbab= {0x30A38238637383DL,0x288094FE661F866L,0x135C51ED5D3D212L,0x3C39C57E8051F25L,0x164639D737D882FL,0x312AEC8AA8DB8FCL,0x3FE838885E54DA8L,0x2FC3978BA297414L,0x850556F014F91FL,0x20B6CE9E3L};
+	public static final long[] CURVE_Pxbba= {0x1683DB3D711939CL,0x26F9475A69066BAL,0xBCDB572CF2F6C0L,0x128DC8902CE1323L,0x29B3233EF353D1CL,0x342402A46B7046L,0x3187D1A403D6070L,0x3E3466F9F23BA45L,0xD943BE2435A9CCL,0x2A08A9CE1L};
+	public static final long[] CURVE_Pxbbb= {0x32D410A856F4899L,0x7147AE4A959750L,0x28AEA57990BC9BCL,0x2807F11E9E26DAL,0x282C5EBA71895E3L,0x2832162D9FEC5FFL,0x33479E30007597CL,0x227A376C26A4B00L,0x1C16F1567857A32L,0x37DD51E0FL};
+	public static final long[] CURVE_Pyaaa= {0x2E097CFB4137844L,0x313B1927FD3CCDDL,0x1EB86FABC768851L,0x4156382E29C659L,0x3C10CC7CF8896E0L,0x22FC388FD1D539CL,0x2C3E202F56CDD39L,0x2E9645FB43E8C72L,0x93548FD8706190L,0x1D9BB42E1L};
+	public static final long[] CURVE_Pyaab= {0x25E3248EDC83190L,0x2BAABD11AA26424L,0x161D23BAC418D32L,0x5B3258247CBFF7L,0xED295CADE03C1FL,0x3A84758C5C741A2L,0x3D207E205E02B9EL,0x86743E24EA6513L,0x1DAA8E268EFA1C4L,0x9E72CE4FL};
+	public static final long[] CURVE_Pyaba= {0x1DC5FD041985C0DL,0x2350136864770FAL,0x3179A5F5483ACE9L,0x2C25AB1A171F32CL,0x397C4403E658341L,0xE7E1C2186E971L,0x15921F60B0A5F40L,0x46E9317635E008L,0x17EF1353F3140D6L,0x35166F259L};
+	public static final long[] CURVE_Pyabb= {0x36FE0A8159D42F8L,0x290EBF4445895D7L,0x20273B0FE9E7F2BL,0x23A6E2FF0F3FD7DL,0x1F37678869E5006L,0x2CA2DB53C9ED8DL,0x4E4BFD902F51DEL,0x1FF8649F125B66L,0x382D89BED80731L,0x28383AAA8L};
+	public static final long[] CURVE_Pybaa= {0xD512B39F38039FL,0x23BA255F3C68984L,0x390AA14058093CFL,0x1FF0B2F2FFA1622L,0x310C5CC5F2ABB75L,0x3D9016C9EB6A2C9L,0x1CF7EE268EC2F18L,0x338BBB12C36B65AL,0x1EEE591B8A1D1ABL,0xAC11927CL};
+	public static final long[] CURVE_Pybab= {0x269E06F295F7865L,0x2FC1D5BA1CE9A0EL,0x3631F3F1DACADD7L,0x30CCF3581D3943L,0x3FBE3B902505BB0L,0x23C4A9D31B36A49L,0x2056135CA438576L,0x2B78046739984F4L,0x12C0AC57B6F180EL,0xC48CA65BL};
+	public static final long[] CURVE_Pybba= {0x1D83A9F67CC1979L,0x12ABE71DD89E6F0L,0x247B1C21635FDA9L,0x92880950076209L,0x2ECF179E0D733D7L,0x20D2DFFB53841F9L,0x3441B1645BC9FE8L,0x3089222CE22EC9DL,0x3699AE4108C86C5L,0x320034967L};
+	public static final long[] CURVE_Pybbb= {0xFC89562FC9F25BL,0xB13E01AE9AB5D3L,0x18E8F169C9D264FL,0x3A5828D76B24A13L,0x1E8FD9BCEF84D9AL,0x36D20E3DBFEE16AL,0x17D3B3DF1AB4C1CL,0xF190510390F005L,0x12640E61B9BF549L,0x283D84D97L};
+	public static final long[][] CURVE_W= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_SB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+	public static final long[][] CURVE_WB= {{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_BB= {{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/BIG.java b/src/main/java/org/apache/milagro/amcl/BN254/BIG.java
new file mode 100644
index 0000000..89ac1bd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BN254;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/DBIG.java b/src/main/java/org/apache/milagro/amcl/BN254/DBIG.java
new file mode 100644
index 0000000..33e219d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BN254;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/ECDH.java b/src/main/java/org/apache/milagro/amcl/BN254/ECDH.java
new file mode 100644
index 0000000..07050ab
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BN254;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/ECP.java b/src/main/java/org/apache/milagro/amcl/BN254/ECP.java
new file mode 100644
index 0000000..aef855b
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BN;
+	public static final int SEXTIC_TWIST=D_TYPE;
+	public static final int SIGN_OF_X=NEGATIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/ECP2.java b/src/main/java/org/apache/milagro/amcl/BN254/ECP2.java
new file mode 100644
index 0000000..673da96
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/FP.java b/src/main/java/org/apache/milagro/amcl/BN254/FP.java
new file mode 100644
index 0000000..6c3003f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=254; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<26);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/FP12.java b/src/main/java/org/apache/milagro/amcl/BN254/FP12.java
new file mode 100644
index 0000000..0aba532
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/FP2.java b/src/main/java/org/apache/milagro/amcl/BN254/FP2.java
new file mode 100644
index 0000000..d9c4723
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/FP4.java b/src/main/java/org/apache/milagro/amcl/BN254/FP4.java
new file mode 100644
index 0000000..d535f93
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/MPIN.java b/src/main/java/org/apache/milagro/amcl/BN254/MPIN.java
new file mode 100644
index 0000000..dfbeea8
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BN254;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/PAIR.java b/src/main/java/org/apache/milagro/amcl/BN254/PAIR.java
new file mode 100644
index 0000000..a9619e6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BN254;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254/ROM.java b/src/main/java/org/apache/milagro/amcl/BN254/ROM.java
new file mode 100644
index 0000000..f1927c1
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254/ROM.java
@@ -0,0 +1,55 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BN254;
+
+public class ROM
+{
+
+	public static final long[] Modulus= {0x13L,0x13A7L,0x80000000086121L,0x40000001BA344DL,0x25236482L};
+	public static final long[] R2modp= {0x2F2A96FF5E7E39L,0x64E8642B96F13CL,0x9926F7B00C7146L,0x8321E7B4DACD24L,0x1D127A2EL};
+	public static final long MConst= 0x435E50D79435E5L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final int CURVE_A= 0;
+	public static final int CURVE_B_I= 2;
+	public static final long[] CURVE_B= {0x2L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0xDL,0x800000000010A1L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L};
+	public static final long[] CURVE_Gx= {0x12L,0x13A7L,0x80000000086121L,0x40000001BA344DL,0x25236482L};
+	public static final long[] CURVE_Gy= {0x1L,0x0L,0x0L,0x0L,0x0L};
+
+	public static final long[] CURVE_Bnx= {0x80000000000001L,0x40L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cru= {0x80000000000007L,0x6CDL,0x40000000024909L,0x49B362L,0x0L};
+	public static final long[] Fra= {0x7DE6C06F2A6DE9L,0x74924D3F77C2E1L,0x50A846953F8509L,0x212E7C8CB6499BL,0x1B377619L};
+	public static final long[] Frb= {0x82193F90D5922AL,0x8B6DB2C08850C5L,0x2F57B96AC8DC17L,0x1ED1837503EAB2L,0x9EBEE69L};
+	public static final long[] CURVE_Pxa= {0xEE4224C803FB2BL,0x8BBB4898BF0D91L,0x7E8C61EDB6A464L,0x519EB62FEB8D8CL,0x61A10BBL};
+	public static final long[] CURVE_Pxb= {0x8C34C1E7D54CF3L,0x746BAE3784B70DL,0x8C5982AA5B1F4DL,0xBA737833310AA7L,0x516AAF9L};
+	public static final long[] CURVE_Pya= {0xF0E07891CD2B9AL,0xAE6BDBE09BD19L,0x96698C822329BDL,0x6BAF93439A90E0L,0x21897A0L};
+	public static final long[] CURVE_Pyb= {0x2D1AEC6B3ACE9BL,0x6FFD739C9578AL,0x56F5F38D37B090L,0x7C8B15268F6D44L,0xEBB2B0EL};
+	public static final long[][] CURVE_W= {{0x3L,0x80000000000204L,0x6181L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_SB= {{{0x4L,0x80000000000285L,0x6181L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}},{{0x1L,0x81L,0x0L,0x0L,0x0L},{0xAL,0xE9DL,0x80000000079E1EL,0x40000001BA344DL,0x25236482L}}};
+	public static final long[][] CURVE_WB= {{0x80000000000000L,0x80000000000040L,0x2080L,0x0L,0x0L},{0x80000000000005L,0x54AL,0x8000000001C707L,0x312241L,0x0L},{0x80000000000003L,0x800000000002C5L,0xC000000000E383L,0x189120L,0x0L},{0x80000000000001L,0x800000000000C1L,0x2080L,0x0L,0x0L}};
+	public static final long[][][] CURVE_BB= {{{0x8000000000000DL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x2L,0x81L,0x0L,0x0L,0x0L}},{{0x1L,0x81L,0x0L,0x0L,0x0L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000DL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L}},{{0x2L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}},{{0x80000000000002L,0x40L,0x0L,0x0L,0x0L},{0x2L,0x102L,0x0L,0x0L,0x0L},{0xAL,0x80000000001020L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x80000000000002L,0x40L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/BIG.java b/src/main/java/org/apache/milagro/amcl/BN254CX/BIG.java
new file mode 100644
index 0000000..ff8ac77
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BN254CX;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/DBIG.java b/src/main/java/org/apache/milagro/amcl/BN254CX/DBIG.java
new file mode 100644
index 0000000..efc3777
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BN254CX;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/ECDH.java b/src/main/java/org/apache/milagro/amcl/BN254CX/ECDH.java
new file mode 100644
index 0000000..721eaf9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BN254CX;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/ECP.java b/src/main/java/org/apache/milagro/amcl/BN254CX/ECP.java
new file mode 100644
index 0000000..660b808
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BN;
+	public static final int SEXTIC_TWIST=D_TYPE;
+	public static final int SIGN_OF_X=NEGATIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/ECP2.java b/src/main/java/org/apache/milagro/amcl/BN254CX/ECP2.java
new file mode 100644
index 0000000..cb8f663
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/FP.java b/src/main/java/org/apache/milagro/amcl/BN254CX/FP.java
new file mode 100644
index 0000000..474343e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=254; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<26);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/FP12.java b/src/main/java/org/apache/milagro/amcl/BN254CX/FP12.java
new file mode 100644
index 0000000..481a544
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/FP2.java b/src/main/java/org/apache/milagro/amcl/BN254CX/FP2.java
new file mode 100644
index 0000000..7848512
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/FP4.java b/src/main/java/org/apache/milagro/amcl/BN254CX/FP4.java
new file mode 100644
index 0000000..d7b47d7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/MPIN.java b/src/main/java/org/apache/milagro/amcl/BN254CX/MPIN.java
new file mode 100644
index 0000000..7317e3d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.BN254CX;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/PAIR.java b/src/main/java/org/apache/milagro/amcl/BN254CX/PAIR.java
new file mode 100644
index 0000000..6c587bf
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.BN254CX;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BN254CX/ROM.java b/src/main/java/org/apache/milagro/amcl/BN254CX/ROM.java
new file mode 100644
index 0000000..0e837f0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BN254CX/ROM.java
@@ -0,0 +1,58 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.BN254CX;
+
+public class ROM
+{
+// Base Bits= 56
+	public static final long[] Modulus= {0x6623EF5C1B55B3L,0xD6EE18093EE1BEL,0x647A6366D3243FL,0x8702A0DB0BDDFL,0x24000000L};
+	public static final long[] R2modp= {0x466A0618A0800AL,0x2B3A22543056A3L,0x148515B09C6600L,0xEC9EA5606BDF50L,0x1C992E66L};
+	public static final long MConst= 0x4E205BF9789E85L;
+
+	public static final int CURVE_A= 0;
+	public static final int CURVE_B_I= 2;
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_B= {0x2L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0x11C0A636EB1F6DL,0xD6EE0CC906CEBEL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L};
+	public static final long[] CURVE_Gx= {0x6623EF5C1B55B2L,0xD6EE18093EE1BEL,0x647A6366D3243FL,0x8702A0DB0BDDFL,0x24000000L};
+	public static final long[] CURVE_Gy= {0x1L,0x0L,0x0L,0x0L,0x0L};
+
+	public static final long[] CURVE_Bnx= {0x3C012B1L,0x40L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Cru= {0xE0931794235C97L,0xDF6471EF875631L,0xCA83F1440BDL,0x480000L,0x0L};
+	public static final long[] Fra= {0xD9083355C80EA3L,0x7326F173F8215BL,0x8AACA718986867L,0xA63A0164AFE18BL,0x1359082FL};
+	public static final long[] Frb= {0x8D1BBC06534710L,0x63C7269546C062L,0xD9CDBC4E3ABBD8L,0x623628A900DC53L,0x10A6F7D0L};
+
+	public static final long[] CURVE_Pxa= {0x851CEEE4D2EC74L,0x85BFA03E2726C0L,0xF5C34BBB907CL,0x7053B256358B25L,0x19682D2CL};
+	public static final long[] CURVE_Pxb= {0xA58E8B2E29CFE1L,0x97B0C209C30F47L,0x37A8E99743F81BL,0x3E19F64AA011C9L,0x1466B9ECL};
+	public static final long[] CURVE_Pya= {0xFBFCEBCF0BE09FL,0xB33D847EC1B30CL,0x157DAEE2096361L,0x72332B8DD81E22L,0xA79EDD9L};
+	public static final long[] CURVE_Pyb= {0x904B228898EE9DL,0x4EA569D2EDEBEDL,0x512D8D3461C286L,0xECC4C09035C6E4L,0x6160C39L};
+
+
+	public static final long[][] CURVE_W= {{0x546349162FEB83L,0xB40381200L,0x6000L,0x0L,0x0L},{0x7802561L,0x80L,0x0L,0x0L,0x0L}};
+	public static final long[][][] CURVE_SB= {{{0x5463491DB010E4L,0xB40381280L,0x6000L,0x0L,0x0L},{0x7802561L,0x80L,0x0L,0x0L,0x0L}},{{0x7802561L,0x80L,0x0L,0x0L,0x0L},{0xBD5D5D20BB33EAL,0xD6EE0188CEBCBDL,0x647A6366D2643FL,0x8702A0DB0BDDFL,0x24000000L}}};
+	public static final long[][] CURVE_WB= {{0x1C2118567A84B0L,0x3C012B040L,0x2000L,0x0L,0x0L},{0xCDF995BE220475L,0x94EDA8CA7F9A36L,0x8702A0DC07EL,0x300000L,0x0L},{0x66FCCAE0F10B93L,0x4A76D4653FCD3BL,0x4381506E03FL,0x180000L,0x0L},{0x1C21185DFAAA11L,0x3C012B0C0L,0x2000L,0x0L,0x0L}};
+	public static final long[][][] CURVE_BB= {{{0x11C0A6332B0CBDL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x11C0A6332B0CBCL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x11C0A6332B0CBCL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x7802562L,0x80L,0x0L,0x0L,0x0L}},{{0x7802561L,0x80L,0x0L,0x0L,0x0L},{0x11C0A6332B0CBCL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x11C0A6332B0CBDL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x11C0A6332B0CBCL,0xD6EE0CC906CE7EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L}},{{0x7802562L,0x80L,0x0L,0x0L,0x0L},{0x7802561L,0x80L,0x0L,0x0L,0x0L},{0x7802561L,0x80L,0x0L,0x0L,0x0L},{0x7802561L,0x80L,0x0L,0x0L,0x0L}},{{0x3C012B2L,0x40L,0x0L,0x0L,0x0L},{0xF004AC2L,0x100L,0x0L,0x0L,0x0L},{0x11C0A62F6AFA0AL,0xD6EE0CC906CE3EL,0x647A6366D2C43FL,0x8702A0DB0BDDFL,0x24000000L},{0x3C012B2L,0x40L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/BIG.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/BIG.java
new file mode 100644
index 0000000..575028b
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.BRAINPOOL;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/DBIG.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/DBIG.java
new file mode 100644
index 0000000..45d1ffe
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.BRAINPOOL;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECDH.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECDH.java
new file mode 100644
index 0000000..2c164cb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.BRAINPOOL;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECP.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECP.java
new file mode 100644
index 0000000..46df5b7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.BRAINPOOL;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/FP.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/FP.java
new file mode 100644
index 0000000..35adafa
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.BRAINPOOL;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ROM.java b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ROM.java
new file mode 100644
index 0000000..e234556
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/BRAINPOOL/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+/* Note that the original curve has been transformed to an isomorphic curve with A=-3 */
+
+package org.apache.milagro.amcl.BRAINPOOL;
+
+public class ROM
+{
+
+// Base Bits= 56
+	public static final long[] Modulus= {0x13481D1F6E5377L,0xF623D526202820L,0x909D838D726E3BL,0xA1EEA9BC3E660AL,0xA9FB57DBL};
+	public static final long[] R2modp= {0x9E04F49B9A3787L,0x29317218F3CF49L,0x54E8C3CF1DBC89L,0xBB411A3F7559CAL,0x9773E15FL};
+	public static final long MConst= 0xA75590CEFD89B9L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 0;
+	public static final long[] CURVE_B= {0xE58101FEE92B04L,0xEBC4AF2F49256AL,0x733D0B76B7BF93L,0x30D84EA4FE66A7L,0x662C61C4L};
+	public static final long[] CURVE_Order= {0x1E0E82974856A7L,0x7AA3B561A6F790L,0x909D838D718C39L,0xA1EEA9BC3E660AL,0xA9FB57DBL};
+	public static final long[] CURVE_Gx= {0xA191562E1305F4L,0x42C47AAFBC2B79L,0xB23A656149AFA1L,0xC1CFE7B7732213L,0xA3E8EB3CL};
+	public static final long[] CURVE_Gy= {0xABE8F35B25C9BEL,0xB6DE39D027001DL,0xE14644417E69BCL,0x3439C56D7F7B22L,0x2D996C82L};
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/BIG.java b/src/main/java/org/apache/milagro/amcl/C25519/BIG.java
new file mode 100644
index 0000000..a661762
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.C25519;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/DBIG.java b/src/main/java/org/apache/milagro/amcl/C25519/DBIG.java
new file mode 100644
index 0000000..1e27a1d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.C25519;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/ECDH.java b/src/main/java/org/apache/milagro/amcl/C25519/ECDH.java
new file mode 100644
index 0000000..5532f65
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.C25519;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/ECP.java b/src/main/java/org/apache/milagro/amcl/C25519/ECP.java
new file mode 100644
index 0000000..aeb3526
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.C25519;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=MONTGOMERY;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/FP.java b/src/main/java/org/apache/milagro/amcl/C25519/FP.java
new file mode 100644
index 0000000..3a78107
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.C25519;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=255; /* Number of bits in Modulus */
+	public static final int MOD8=5;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<25);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C25519/ROM.java b/src/main/java/org/apache/milagro/amcl/C25519/ROM.java
new file mode 100644
index 0000000..dc3c95a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C25519/ROM.java
@@ -0,0 +1,42 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.C25519;
+
+public class ROM
+{
+
+// Base Bits= 56
+public static final long[] Modulus= {0xFFFFFFFFFFFFEDL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0x7FFFFFFFL};
+public static final long[] R2modp= {0xA4000000000000L,0x5L,0x0L,0x0L,0x0L};
+public static final long MConst= 0x13L;
+
+public static final int CURVE_Cof_I= 8;
+public static final long[] CURVE_Cof= {0x8L,0x0L,0x0L,0x0L,0x0L};
+public static final int CURVE_A= 486662;
+public static final int CURVE_B_I= 0;
+public static final long[] CURVE_B= {0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x12631A5CF5D3EDL,0xF9DEA2F79CD658L,0x14DEL,0x0L,0x10000000L};
+public static final long[] CURVE_Gx= {0x9L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Gy= {0x0L,0x0L,0x0L,0x0L,0x0L};
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/BIG.java b/src/main/java/org/apache/milagro/amcl/C41417/BIG.java
new file mode 100644
index 0000000..145342f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.C41417;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=52; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/DBIG.java b/src/main/java/org/apache/milagro/amcl/C41417/DBIG.java
new file mode 100644
index 0000000..2dbd26a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.C41417;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/ECDH.java b/src/main/java/org/apache/milagro/amcl/C41417/ECDH.java
new file mode 100644
index 0000000..60a340e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.C41417;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/ECP.java b/src/main/java/org/apache/milagro/amcl/C41417/ECP.java
new file mode 100644
index 0000000..61b523c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.C41417;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/FP.java b/src/main/java/org/apache/milagro/amcl/C41417/FP.java
new file mode 100644
index 0000000..673d16f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.C41417;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=414; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<6);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/C41417/ROM.java b/src/main/java/org/apache/milagro/amcl/C41417/ROM.java
new file mode 100644
index 0000000..f23f20f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/C41417/ROM.java
@@ -0,0 +1,44 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.C41417;
+
+public class ROM
+{
+
+// Base Bits= 60
+	public static final long[] Modulus= {0xFFFFFFFFFFFFFEFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFL};
+	public static final long[] R2modp= {0x121000L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x11L;
+
+
+	public static final int CURVE_Cof_I= 8;
+	public static final long[] CURVE_Cof= {0x8L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= 1;
+	public static final int CURVE_B_I= 3617;
+	public static final long[] CURVE_B= {0xE21L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0xB0E71A5E106AF79L,0x1C0338AD63CF181L,0x414CF706022B36FL,0xFFFFFFFFEB3CC92L,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0x7FFFFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x4FD3812F3CBC595L,0x1A73FAA8537C64CL,0x4AB4D6D6BA11130L,0x3EC7F57FF35498AL,0xE5FCD46369F44C0L,0x300218C0631C326L,0x1A334905141443L};
+	public static final long[] CURVE_Gy= {0x22L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/BIG.java b/src/main/java/org/apache/milagro/amcl/ED25519/BIG.java
new file mode 100644
index 0000000..8fa4f59
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.ED25519;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/DBIG.java b/src/main/java/org/apache/milagro/amcl/ED25519/DBIG.java
new file mode 100644
index 0000000..18d7453
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.ED25519;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/ECDH.java b/src/main/java/org/apache/milagro/amcl/ED25519/ECDH.java
new file mode 100644
index 0000000..55dcaeb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.ED25519;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/ECP.java b/src/main/java/org/apache/milagro/amcl/ED25519/ECP.java
new file mode 100644
index 0000000..65f151a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.ED25519;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/FP.java b/src/main/java/org/apache/milagro/amcl/ED25519/FP.java
new file mode 100644
index 0000000..cab29f7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.ED25519;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=255; /* Number of bits in Modulus */
+	public static final int MOD8=5;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<25);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/ED25519/ROM.java b/src/main/java/org/apache/milagro/amcl/ED25519/ROM.java
new file mode 100644
index 0000000..a50866a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/ED25519/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.ED25519;
+
+public class ROM
+{
+
+public static final long[] Modulus= {0xFFFFFFFFFFFFEDL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0x7FFFFFFFL};
+public static final long[] R2modp= {0xA4000000000000L,0x5L,0x0L,0x0L,0x0L};
+public static final long MConst= 0x13;
+
+
+public static final int CURVE_Cof_I= 8;
+public static final long[] CURVE_Cof= {0x8L,0x0L,0x0L,0x0L,0x0L};
+public static final int CURVE_A= -1;
+public static final int CURVE_B_I= 0;
+public static final long[] CURVE_B= {0xEB4DCA135978A3L,0xA4D4141D8AB75L,0x797779E8980070L,0x2B6FFE738CC740L,0x52036CEEL};
+public static final long[] CURVE_Order= {0x12631A5CF5D3EDL,0xF9DEA2F79CD658L,0x14DEL,0x0L,0x10000000L};
+public static final long[] CURVE_Gx= {0x562D608F25D51AL,0xC7609525A7B2C9L,0x31FDD6DC5C692CL,0xCD6E53FEC0A4E2L,0x216936D3L};
+public static final long[] CURVE_Gy= {0x66666666666658L,0x66666666666666L,0x66666666666666L,0x66666666666666L,0x66666666L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/BIG.java b/src/main/java/org/apache/milagro/amcl/FP256BN/BIG.java
new file mode 100644
index 0000000..80cee96
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.FP256BN;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/DBIG.java b/src/main/java/org/apache/milagro/amcl/FP256BN/DBIG.java
new file mode 100644
index 0000000..88d39eb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.FP256BN;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/ECDH.java b/src/main/java/org/apache/milagro/amcl/FP256BN/ECDH.java
new file mode 100644
index 0000000..9d9de60
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.FP256BN;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/ECP.java b/src/main/java/org/apache/milagro/amcl/FP256BN/ECP.java
new file mode 100644
index 0000000..4c45abb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BN;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=NEGATIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/ECP2.java b/src/main/java/org/apache/milagro/amcl/FP256BN/ECP2.java
new file mode 100644
index 0000000..43499d3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/FP.java b/src/main/java/org/apache/milagro/amcl/FP256BN/FP.java
new file mode 100644
index 0000000..d24323b
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/FP12.java b/src/main/java/org/apache/milagro/amcl/FP256BN/FP12.java
new file mode 100644
index 0000000..0e6ee71
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/FP2.java b/src/main/java/org/apache/milagro/amcl/FP256BN/FP2.java
new file mode 100644
index 0000000..e9cc7f9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/FP4.java b/src/main/java/org/apache/milagro/amcl/FP256BN/FP4.java
new file mode 100644
index 0000000..2f4cc41
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/MPIN.java b/src/main/java/org/apache/milagro/amcl/FP256BN/MPIN.java
new file mode 100644
index 0000000..369638c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.FP256BN;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/PAIR.java b/src/main/java/org/apache/milagro/amcl/FP256BN/PAIR.java
new file mode 100644
index 0000000..93dc4ca
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.FP256BN;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP256BN/ROM.java b/src/main/java/org/apache/milagro/amcl/FP256BN/ROM.java
new file mode 100644
index 0000000..7a8a637
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP256BN/ROM.java
@@ -0,0 +1,55 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.FP256BN;
+
+public class ROM
+{
+// Base Bits= 56
+public static final long[] Modulus={0x292DDBAED33013L,0x65FB12980A82D3L,0x5EEE71A49F0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL};
+public static final long[] R2modp={0xEDE336303B9F8BL,0x92FFEE9FEC54E8L,0x13C1C063C55F79L,0xA12F2EAC0123FAL,0x8E559B2AL};
+public static final long MConst= 0x6C964E0537E5E5L;
+
+public static final int CURVE_A= 0;
+public static final int CURVE_B_I= 3;
+public static final int CURVE_Cof_I= 1;
+public static final long[] CURVE_B= {0x3L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x2D536CD10B500DL,0x65FB1299921AF6L,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL};
+public static final long[] CURVE_Gx= {0x1L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Gy= {0x2L,0x0L,0x0L,0x0L,0x0L};
+
+public static final long[] Fra={0x760328AF943106L,0x71511E3AB28F74L,0x8DDB0867CF39A1L,0xCA786F352D1A6EL,0x3D617662L};
+public static final long[] Frb={0xB32AB2FF3EFF0DL,0xF4A9F45D57F35EL,0xD113693CCFD33AL,0x3584819819CB83L,0xC29E899DL};
+public static final long[] CURVE_Bnx= {0x82F5C030B0A801L,0x68L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cru= {0x1C0A24A3A1B807L,0xD79DF1932D1EDBL,0x40921018659BCDL,0x13988E1L,0x0L};
+public static final long[] CURVE_Pxa= {0x2616B689C09EFBL,0x539A12BF843CD2L,0x577C28913ACE1CL,0xB4C96C2028560FL,0xFE0C3350L};
+public static final long[] CURVE_Pxb= {0x69ED34A37E6A2BL,0x78E287D03589D2L,0xC637D813B924DDL,0x738AC054DB5AE1L,0x4EA66057L};
+public static final long[] CURVE_Pya= {0x9B481BEDC27FFL,0x24758D615848E9L,0x75124E3E51EFCBL,0xC542A3B376770DL,0x702046E7L};
+public static final long[] CURVE_Pyb= {0x1281114AAD049BL,0xBE80821A98B3E0L,0x49297EB29F8B4CL,0xD388C29042EEA6L,0x554E3BCL};
+public static final long[][] CURVE_W= {{0xF0036E1B054003L,0xFFFFFFFE78663AL,0xFFFFL,0x0L,0x0L},{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_SB= {{{0xF5EEEE7C669004L,0xFFFFFFFE78670BL,0xFFFFL,0x0L,0x0L},{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L}},{{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L},{0x3D4FFEB606100AL,0x65FB129B19B4BBL,0x5EEE71A49D0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL}}};
+public static final long[][] CURVE_WB= {{0x20678F0D30A800L,0x55555554D2CC10L,0x5555L,0x0L,0x0L},{0xD6764C0D7DC805L,0x8FBEA10BC3AD1AL,0x806160104467DEL,0xD105EBL,0x0L},{0xACB6061F173803L,0x47DF5085E1D6C1L,0xC030B0082233EFL,0x6882F5L,0x0L},{0x26530F6E91F801L,0x55555554D2CCE1L,0x5555L,0x0L,0x0L}};
+public static final long[][][] CURVE_BB= {{{0xAA5DACA05AA80DL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0xAA5DACA05AA80CL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0xAA5DACA05AA80CL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0x5EB8061615002L,0xD1L,0x0L,0x0L,0x0L}},{{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L},{0xAA5DACA05AA80CL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0xAA5DACA05AA80DL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0xAA5DACA05AA80CL,0x65FB1299921A8DL,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL}},{{0x5EB8061615002L,0xD1L,0x0L,0x0L,0x0L},{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L},{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L},{0x5EB8061615001L,0xD1L,0x0L,0x0L,0x0L}},{{0x82F5C030B0A802L,0x68L,0x0L,0x0L,0x0L},{0xBD700C2C2A002L,0x1A2L,0x0L,0x0L,0x0L},{0x2767EC6FAA000AL,0x65FB1299921A25L,0x5EEE71A49E0CDCL,0xFFFCF0CD46E5F2L,0xFFFFFFFFL},{0x82F5C030B0A802L,0x68L,0x0L,0x0L,0x0L}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/BIG.java b/src/main/java/org/apache/milagro/amcl/FP512BN/BIG.java
new file mode 100644
index 0000000..a865f22
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.FP512BN;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=64; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/DBIG.java b/src/main/java/org/apache/milagro/amcl/FP512BN/DBIG.java
new file mode 100644
index 0000000..b563ee9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.FP512BN;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/ECDH.java b/src/main/java/org/apache/milagro/amcl/FP512BN/ECDH.java
new file mode 100644
index 0000000..227faca
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.FP512BN;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/ECP.java b/src/main/java/org/apache/milagro/amcl/FP512BN/ECP.java
new file mode 100644
index 0000000..557e2c3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=BN;
+	public static final int SEXTIC_TWIST=M_TYPE;
+	public static final int SIGN_OF_X=POSITIVEX;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/ECP2.java b/src/main/java/org/apache/milagro/amcl/FP512BN/ECP2.java
new file mode 100644
index 0000000..2213a56
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/ECP2.java
@@ -0,0 +1,796 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Weierstrass elliptic curve functions over FP2 */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class ECP2 {
+	private FP2 x;
+	private FP2 y;
+	private FP2 z;
+//	private boolean INF;
+
+/* Constructor - set this=O */
+	public ECP2() {
+//		INF=true;
+		x=new FP2(0);
+		y=new FP2(1);
+		z=new FP2(0);
+	}
+
+    public ECP2(ECP2 e) {
+        this.x = new FP2(e.x);
+        this.y = new FP2(e.y);
+        this.z = new FP2(e.z);
+    }
+
+/* Test this=O? */
+	public boolean is_infinity() {
+//		if (INF) return true;                    //******
+		return (x.iszilch() && z.iszilch());
+	}
+/* copy this=P */
+	public void copy(ECP2 P)
+	{
+		x.copy(P.x);
+		y.copy(P.y);
+		z.copy(P.z);
+//		INF=P.INF;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		y.one();
+		z.zero();
+	}
+
+/* Conditional move of Q to P dependant on d */
+	public void cmove(ECP2 Q,int d)
+	{
+		x.cmove(Q.x,d);
+		y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+
+	//	boolean bd;
+	//	if (d==0) bd=false;
+	//	else bd=true;
+	//	INF^=(INF^Q.INF)&bd;
+	}
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(ECP2 W[],int b)
+	{
+		ECP2 MP=new ECP2(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test if P == Q */
+	public boolean equals(ECP2 Q) {
+//		if (is_infinity() && Q.is_infinity()) return true;
+//		if (is_infinity() || Q.is_infinity()) return false;
+
+
+		FP2 a=new FP2(x);                            // *****
+		FP2 b=new FP2(Q.x);
+		a.mul(Q.z); 
+		b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		a.copy(y); a.mul(Q.z); 
+		b.copy(Q.y); b.mul(z); 
+		if (!a.equals(b)) return false;
+
+		return true;
+	}
+/* set this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		y.norm();
+		y.neg(); y.norm();
+		return;
+	}
+/* set to Affine - (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;
+		FP2 one=new FP2(1);
+		if (z.equals(one))
+		{
+			x.reduce();
+			y.reduce();
+			return;
+		}
+		z.inverse();
+
+		x.mul(z); x.reduce();               // *****
+		y.mul(z); y.reduce();
+		z.copy(one);
+	}
+/* extract affine x as FP2 */
+	public FP2 getX()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.x;
+	}
+/* extract affine y as FP2 */
+	public FP2 getY()
+	{
+		ECP2 W=new ECP2(this);
+		W.affine();
+		return W.y;
+	}
+/* extract projective x */
+	public FP2 getx()
+	{
+		return x;
+	}
+/* extract projective y */
+	public FP2 gety()
+	{
+		return y;
+	}
+/* extract projective z */
+	public FP2 getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP2 W=new ECP2(this);
+		W.affine();
+		W.x.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i]=t[i];
+		W.x.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+BIG.MODBYTES]=t[i];
+
+		W.y.getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+2*BIG.MODBYTES]=t[i];
+		W.y.getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++)
+			b[i+3*BIG.MODBYTES]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP2 fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG ra;
+		BIG rb;
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 rx=new FP2(ra,rb);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+2*BIG.MODBYTES];
+		ra=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+3*BIG.MODBYTES];
+		rb=BIG.fromBytes(t);
+		FP2 ry=new FP2(ra,rb);
+
+		return new ECP2(rx,ry);
+	}
+/* convert this to hex string */
+	public String toString() {
+		ECP2 W=new ECP2(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		return "("+W.x.toString()+","+W.y.toString()+")";
+	}
+
+/* Calculate RHS of twisted curve equation x^3+B/i */
+	public static FP2 RHS(FP2 x) {
+		x.norm();
+		FP2 r=new FP2(x);
+		r.sqr();
+		FP2 b=new FP2(new BIG(ROM.CURVE_B));
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			b.div_ip();
+		}
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			b.norm();
+			b.mul_ip();
+			b.norm();
+		}
+
+
+		r.mul(x);
+		r.add(b);
+
+		r.reduce();
+		return r;
+	}
+
+/* construct this from (x,y) - but set to O if not on curve */
+	public ECP2(FP2 ix,FP2 iy) {
+		x=new FP2(ix);
+		y=new FP2(iy);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		FP2 y2=new FP2(y);
+		y2.sqr();
+		if (!y2.equals(rhs)) inf();
+//		if (y2.equals(rhs)) INF=false;
+//		else {x.zero();INF=true;}
+	}
+
+/* construct this from x - but set to O if not on curve */
+	public ECP2(FP2 ix) {
+		x=new FP2(ix);
+		y=new FP2(1);
+		z=new FP2(1);
+		FP2 rhs=RHS(x);
+		if (rhs.sqrt()) 
+		{
+			y.copy(rhs);
+			//INF=false;
+		}
+		else {/*x.zero();INF=true;*/ inf();}
+	}
+
+/* this+=this */
+	public int dbl() {
+//		if (INF) return -1;      
+//System.out.println("Into dbl");
+		FP2 iy=new FP2(y);
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			iy.mul_ip(); iy.norm();
+		}
+		FP2 t0=new FP2(y);                  //***** Change 
+		t0.sqr();            
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t0.mul_ip();
+		}
+		FP2 t1=new FP2(iy);  
+		t1.mul(z);
+		FP2 t2=new FP2(z);
+		t2.sqr();
+
+		z.copy(t0);
+		z.add(t0); z.norm(); 
+		z.add(z); 
+		z.add(z); 
+		z.norm();  
+
+		t2.imul(3*ROM.CURVE_B_I); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip();
+			t2.norm();
+		}
+
+		FP2 x3=new FP2(t2);
+		x3.mul(z); 
+
+		FP2 y3=new FP2(t0);   
+
+		y3.add(t2); y3.norm();
+		z.mul(t1);
+		t1.copy(t2); t1.add(t2); t2.add(t1); t2.norm();  
+		t0.sub(t2); t0.norm();                           //y^2-9bz^2
+		y3.mul(t0); y3.add(x3);                          //(y^2+3z*2)(y^2-9z^2)+3b.z^2.8y^2
+		t1.copy(x); t1.mul(iy);						//
+		x.copy(t0); x.norm(); x.mul(t1); x.add(x);       //(y^2-9bz^2)xy2
+
+		x.norm(); 
+		y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+		return 1;
+	}
+
+/* this+=Q - return 0 for add, 1 for double, -1 for O */
+	public int add(ECP2 Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return -1;
+//		}
+//		if (Q.INF) return -1;
+//System.out.println("Into add");
+		int b=3*ROM.CURVE_B_I;
+		FP2 t0=new FP2(x);
+		t0.mul(Q.x);         // x.Q.x
+		FP2 t1=new FP2(y);
+		t1.mul(Q.y);		 // y.Q.y
+
+		FP2 t2=new FP2(z);
+		t2.mul(Q.z);
+		FP2 t3=new FP2(x);
+		t3.add(y); t3.norm();          //t3=X1+Y1
+		FP2 t4=new FP2(Q.x);            
+		t4.add(Q.y); t4.norm();			//t4=X2+Y2
+		t3.mul(t4);						//t3=(X1+Y1)(X2+Y2)
+		t4.copy(t0); t4.add(t1);		//t4=X1.X2+Y1.Y2
+
+		t3.sub(t4); t3.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{		
+			t3.mul_ip();  t3.norm();         //t3=(X1+Y1)(X2+Y2)-(X1.X2+Y1.Y2) = X1.Y2+X2.Y1
+		}
+		t4.copy(y);                    
+		t4.add(z); t4.norm();			//t4=Y1+Z1
+		FP2 x3=new FP2(Q.y);
+		x3.add(Q.z); x3.norm();			//x3=Y2+Z2
+
+		t4.mul(x3);						//t4=(Y1+Z1)(Y2+Z2)
+		x3.copy(t1);					//
+		x3.add(t2);						//X3=Y1.Y2+Z1.Z2
+	
+		t4.sub(x3); t4.norm(); 
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{	
+			t4.mul_ip(); t4.norm();          //t4=(Y1+Z1)(Y2+Z2) - (Y1.Y2+Z1.Z2) = Y1.Z2+Y2.Z1
+		}
+		x3.copy(x); x3.add(z); x3.norm();	// x3=X1+Z1
+		FP2 y3=new FP2(Q.x);				
+		y3.add(Q.z); y3.norm();				// y3=X2+Z2
+		x3.mul(y3);							// x3=(X1+Z1)(X2+Z2)
+		y3.copy(t0);
+		y3.add(t2);							// y3=X1.X2+Z1+Z2
+		y3.rsub(x3); y3.norm();				// y3=(X1+Z1)(X2+Z2) - (X1.X2+Z1.Z2) = X1.Z2+X2.Z1
+
+		if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+		{
+			t0.mul_ip(); t0.norm(); // x.Q.x
+			t1.mul_ip(); t1.norm(); // y.Q.y
+		}
+		x3.copy(t0); x3.add(t0); 
+		t0.add(x3); t0.norm();
+		t2.imul(b); 	
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			t2.mul_ip(); t2.norm();
+		}
+		FP2 z3=new FP2(t1); z3.add(t2); z3.norm();
+		t1.sub(t2); t1.norm(); 
+		y3.imul(b); 
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			y3.mul_ip(); 
+			y3.norm();
+		}
+		x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+		y3.mul(t0); t1.mul(z3); y3.add(t1);
+		t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+		x.copy(x3); x.norm(); 
+		y.copy(y3); y.norm();
+		z.copy(z3); z.norm();
+//System.out.println("Out of add");
+		return 0;
+	}
+
+/* set this-=Q */
+	public int sub(ECP2 Q) {
+		ECP2 NQ=new ECP2(Q);
+		NQ.neg();
+		int D=add(NQ);
+		//Q.neg();
+		//int D=add(Q);
+		//Q.neg();
+		return D;
+	}
+/* set this*=q, where q is Modulus, using Frobenius */
+	public void frob(FP2 X)
+	{
+//		if (INF) return;
+		FP2 X2=new FP2(X);
+
+		X2.sqr();
+		x.conj();
+		y.conj();
+		z.conj();
+		z.reduce();
+		x.mul(X2);
+
+		y.mul(X2);
+		y.mul(X);
+	}
+
+/* P*=e */
+	public ECP2 mul(BIG e)
+	{
+/* fixed size windows */
+		int i,b,nb,m,s,ns;
+		BIG mt=new BIG();
+		BIG t=new BIG();
+		ECP2 P=new ECP2();
+		ECP2 Q=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2[] W=new ECP2[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+		if (is_infinity()) return new ECP2();
+
+		//affine();
+
+/* precompute table */
+		Q.copy(this);
+		Q.dbl();
+		W[0]=new ECP2();
+		W[0].copy(this);
+
+		for (i=1;i<8;i++)
+		{
+			W[i]=new ECP2();
+			W[i].copy(W[i-1]);
+			W[i].add(Q);
+		}
+
+/* make exponent odd - add 2P if even, P if odd */
+		t.copy(e);
+		s=t.parity();
+		t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+		t.cmove(mt,s);
+		Q.cmove(this,ns);
+		C.copy(Q);
+
+		nb=1+(t.nbits()+3)/4;
+/* convert exponent to signed 4-bit window */
+		for (i=0;i<nb;i++)
+		{
+			w[i]=(byte)(t.lastbits(5)-16);
+			t.dec(w[i]); t.norm();
+			t.fshr(4);	
+		}
+		w[nb]=(byte)t.lastbits(5);
+	
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			Q.select(W,w[i]);
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.dbl();
+			P.add(Q);
+		}
+		P.sub(C);
+		P.affine();
+		return P;
+	}
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		ECP2 W=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] T=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+			//Q[i].affine();
+		}
+
+        T[0] = new ECP2(); T[0].copy(Q[0]);  // Q[0]
+        T[1] = new ECP2(); T[1].copy(T[0]); T[1].add(Q[1]);  // Q[0]+Q[1]
+        T[2] = new ECP2(); T[2].copy(T[0]); T[2].add(Q[2]);  // Q[0]+Q[2]
+        T[3] = new ECP2(); T[3].copy(T[1]); T[3].add(Q[2]);  // Q[0]+Q[1]+Q[2]
+        T[4] = new ECP2(); T[4].copy(T[0]); T[4].add(Q[3]);  // Q[0]+Q[3]
+        T[5] = new ECP2(); T[5].copy(T[1]); T[5].add(Q[3]);  // Q[0]+Q[1]+Q[3]
+        T[6] = new ECP2(); T[6].copy(T[2]); T[6].add(Q[3]);  // Q[0]+Q[2]+Q[3]
+        T[7] = new ECP2(); T[7].copy(T[3]); T[7].add(Q[3]);  // Q[0]+Q[1]+Q[2]+Q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+    // Main loop
+        P.select(T,(int)(2*w[nb-1]+1));  
+        for (i=nb-2;i>=0;i--) {
+            P.dbl();
+            W.select(T,(int)(2*w[i]+s[i]));
+            P.add(W);
+        }
+
+    // apply correction
+        W.copy(P);   
+        W.sub(Q[0]);
+        P.cmove(W,pb);   
+		P.affine();
+		return P;
+	}        
+
+
+/* P=u0.Q0+u1*Q1+u2*Q2+u3*Q3 */
+/*
+	public static ECP2 mul4(ECP2[] Q,BIG[] u)
+	{
+		int i,j,nb;
+		int[] a=new int[4];
+		ECP2 T=new ECP2();
+		ECP2 C=new ECP2();
+		ECP2 P=new ECP2();
+		ECP2[] W=new ECP2[8];
+
+		BIG mt=new BIG();
+		BIG[] t=new BIG[4];
+
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			Q[i].affine();
+		}
+
+// precompute table 
+
+		W[0]=new ECP2(); W[0].copy(Q[0]); W[0].sub(Q[1]);
+
+		W[1]=new ECP2(); W[1].copy(W[0]);
+		W[2]=new ECP2(); W[2].copy(W[0]);
+		W[3]=new ECP2(); W[3].copy(W[0]);
+		W[4]=new ECP2(); W[4].copy(Q[0]); W[4].add(Q[1]);
+		W[5]=new ECP2(); W[5].copy(W[4]);
+		W[6]=new ECP2(); W[6].copy(W[4]);
+		W[7]=new ECP2(); W[7].copy(W[4]);
+		T.copy(Q[2]); T.sub(Q[3]);
+		W[1].sub(T);
+		W[2].add(T);
+		W[5].sub(T);
+		W[6].add(T);
+		T.copy(Q[2]); T.add(Q[3]);
+		W[0].sub(T);
+		W[3].add(T);
+		W[4].sub(T);
+		W[7].add(T);
+
+// if multiplier is even add 1 to multiplier, and add P to correction 
+		mt.zero(); C.inf();
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				C.add(Q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(byte)(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+
+		P.copy(W[(w[nb]-1)/2]);  
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			P.dbl();
+			P.add(T);
+		}
+		P.sub(C); // apply correction 
+
+		P.affine();
+		return P;
+	}
+*/
+
+/* needed for SOK */
+	public static ECP2 mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		BIG one=new BIG(1);
+		FP2 X;
+		ECP2 Q;
+		x.mod(q);
+		while (true)
+		{
+			X=new FP2(one,x);
+			Q=new ECP2(X);
+			if (!Q.is_infinity()) break;
+			x.inc(1); x.norm();
+		}
+
+		BIG Fra=new BIG(ROM.Fra);
+		BIG Frb=new BIG(ROM.Frb);
+		X=new FP2(Fra,Frb);
+
+		if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+		{
+			X.inverse();
+			X.norm();
+		}
+
+		x=new BIG(ROM.CURVE_Bnx);
+
+/* Fast Hashing to G2 - Fuentes-Castaneda, Knapp and Rodriguez-Henriquez */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			ECP2 T,K;
+
+			T=new ECP2(); T.copy(Q);
+			T=T.mul(x); 
+			
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				T.neg();
+			}	
+			K=new ECP2(); K.copy(T);
+			K.dbl(); K.add(T); //K.affine();
+
+			K.frob(X);
+			Q.frob(X); Q.frob(X); Q.frob(X);
+			Q.add(T); Q.add(K);
+			T.frob(X); T.frob(X);
+			Q.add(T);
+
+		}
+
+/* Efficient hash maps to G2 on BLS curves - Budroni, Pintore */
+/* Q -> x2Q -xQ -Q +F(xQ -Q) +F(F(2Q)) */
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BLS)
+		{
+		//	ECP2 xQ,x2Q;
+		//	xQ=new ECP2();
+		//	x2Q=new ECP2();
+
+			ECP2 xQ=Q.mul(x);
+			ECP2 x2Q=xQ.mul(x);
+
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				xQ.neg();
+			}	
+
+			x2Q.sub(xQ);
+			x2Q.sub(Q);
+
+			xQ.sub(Q);
+			xQ.frob(X);
+
+			Q.dbl();
+			Q.frob(X);
+			Q.frob(X);
+
+			Q.add(x2Q);
+			Q.add(xQ);
+		}
+		Q.affine();
+		return Q;
+	}
+
+	public static ECP2 generator()
+	{
+		return new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+	}
+
+/*
+	public static void main(String[] args) {
+		BIG r=new BIG(ROM.Modulus);
+
+		BIG Pxa=new BIG(ROM.CURVE_Pxa);
+		BIG Pxb=new BIG(ROM.CURVE_Pxb);
+		BIG Pya=new BIG(ROM.CURVE_Pya);
+		BIG Pyb=new BIG(ROM.CURVE_Pyb);
+
+		BIG Fra=new BIG(ROM.CURVE_Fra);
+		BIG Frb=new BIG(ROM.CURVE_Frb);
+
+		FP2 f=new FP2(Fra,Frb);
+
+		FP2 Px=new FP2(Pxa,Pxb);
+		FP2 Py=new FP2(Pya,Pyb);
+
+		ECP2 P=new ECP2(Px,Py);
+
+		System.out.println("P= "+P.toString());
+
+		P=P.mul(r);
+		System.out.println("P= "+P.toString());
+
+		ECP2 Q=new ECP2(Px,Py);
+		Q.frob(f);
+		System.out.println("Q= "+Q.toString());
+	} */
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/FP.java b/src/main/java/org/apache/milagro/amcl/FP512BN/FP.java
new file mode 100644
index 0000000..42ee199
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=512; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<28);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/FP12.java b/src/main/java/org/apache/milagro/amcl/FP512BN/FP12.java
new file mode 100644
index 0000000..d3dc59f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/FP12.java
@@ -0,0 +1,907 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL Fp^12 functions */
+/* FP12 elements are of the form a+i.b+i^2.c */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class FP12 {
+	private final FP4 a;
+	private final FP4 b;
+	private final FP4 c;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+		c.reduce();
+	}
+/* normalise all components of this */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+		c.norm();
+	}
+/* test x==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch() && c.iszilch());
+	}
+
+	public void cmove(FP12 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+		c.cmove(g.c,d);		
+	}
+
+
+/* return 1 if b==c, no branching */
+	public static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	public void select(FP12 g[],int b)
+	{
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+
+		cmove(g[0],teq(babs,0));  // conditional move
+		cmove(g[1],teq(babs,1));
+		cmove(g[2],teq(babs,2));
+		cmove(g[3],teq(babs,3));
+		cmove(g[4],teq(babs,4));
+		cmove(g[5],teq(babs,5));
+		cmove(g[6],teq(babs,6));
+		cmove(g[7],teq(babs,7));
+ 
+		FP12 invf=new FP12(this); 
+		invf.conj();
+		cmove(invf,(int)(m&1));
+	}
+
+
+/* test x==1 ? */
+	public boolean isunity() {
+		FP4 one=new FP4(1);
+		return (a.equals(one) && b.iszilch() && c.iszilch());
+	}
+/* return 1 if x==y, else 0 */
+	public boolean equals(FP12 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b) && c.equals(x.c));
+	}
+/* extract a from this */
+	public FP4 geta()
+	{
+		return a;
+	}
+/* extract b */
+	public FP4 getb()
+	{
+		return b;
+	}
+/* extract c */
+	public FP4 getc()
+	{
+		return c;
+	}
+/* copy this=x */
+	public void copy(FP12 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+		c.copy(x.c);
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+		c.zero();
+	}
+/* this=conj(this) */
+	public void conj()
+	{
+		a.conj();
+		b.nconj();
+		c.conj();
+	}
+/* Constructors */
+	public FP12(FP4 d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(int d)
+	{
+		a=new FP4(d);
+		b=new FP4(0);
+		c=new FP4(0);
+	}
+
+	public FP12(FP4 d,FP4 e,FP4 f)
+	{
+		a=new FP4(d);
+		b=new FP4(e);
+		c=new FP4(f);
+	}
+
+	public FP12(FP12 x)
+	{
+		a=new FP4(x.a);
+		b=new FP4(x.b);
+		c=new FP4(x.c);
+	}
+
+/* Granger-Scott Unitary Squaring */
+	public void usqr()
+	{
+//System.out.println("Into usqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(c);
+		FP4 C=new FP4(b);
+		FP4 D=new FP4(0);
+
+		a.sqr();
+		D.copy(a); D.add(a);
+		a.add(D);
+
+		a.norm();
+		A.nconj();
+
+		A.add(A);
+		a.add(A);
+		B.sqr();
+		B.times_i();
+
+		D.copy(B); D.add(B);
+		B.add(D);
+		B.norm();
+
+		C.sqr();
+		D.copy(C); D.add(C);
+		C.add(D);
+		C.norm();
+
+		b.conj();
+		b.add(b);
+		c.nconj();
+
+		c.add(c);
+		b.add(B);
+		c.add(C);
+//System.out.println("Out of usqr 1");
+		reduce();
+//System.out.println("Out of usqr 2");
+	}
+
+/* Chung-Hasan SQR2 method from http://cacr.uwaterloo.ca/techreports/2006/cacr2006-24.pdf */
+	public void sqr()
+	{
+//System.out.println("Into sqr");
+		FP4 A=new FP4(a);
+		FP4 B=new FP4(b);
+		FP4 C=new FP4(c);
+		FP4 D=new FP4(a);
+
+		A.sqr();
+		B.mul(c);
+		B.add(B);
+	B.norm();
+		C.sqr();
+		D.mul(b);
+		D.add(D);
+
+		c.add(a);
+		c.add(b);
+	c.norm();
+		c.sqr();
+
+		a.copy(A);
+
+		A.add(B);
+		A.norm();
+		A.add(C);
+		A.add(D);
+		A.norm();
+
+		A.neg();
+		B.times_i();
+		C.times_i();
+
+		a.add(B);
+
+		b.copy(C); b.add(D);
+		c.add(A);
+//System.out.println("Out of sqr");
+		norm();
+	}
+
+/* FP12 full multiplication this=this*y */
+	public void mul(FP12 y)
+	{
+//System.out.println("Into mul");
+		FP4 z0=new FP4(a);
+		FP4 z1=new FP4(0);
+		FP4 z2=new FP4(b);
+		FP4 z3=new FP4(0);
+		FP4 t0=new FP4(a);
+		FP4 t1=new FP4(y.a);
+
+		z0.mul(y.a);
+		z2.mul(y.b);
+
+		t0.add(b);
+		t1.add(y.b);
+
+	t0.norm();
+	t1.norm();
+
+		z1.copy(t0); z1.mul(t1);
+		t0.copy(b); t0.add(c);
+
+		t1.copy(y.b); t1.add(y.c);
+
+	t0.norm();
+	t1.norm();
+
+		z3.copy(t0); z3.mul(t1);
+
+		t0.copy(z0); t0.neg();
+		t1.copy(z2); t1.neg();
+
+		z1.add(t0);
+		//z1.norm();
+		b.copy(z1); b.add(t1);
+
+		z3.add(t1);
+		z2.add(t0);
+
+		t0.copy(a); t0.add(c);
+		t1.copy(y.a); t1.add(y.c);
+
+t0.norm();
+t1.norm();
+	
+		t0.mul(t1);
+		z2.add(t0);
+
+		t0.copy(c); t0.mul(y.c);
+		t1.copy(t0); t1.neg();
+
+//		z2.norm();
+//		z3.norm();
+//		b.norm();
+
+		c.copy(z2); c.add(t1);
+		z3.add(t1);
+		t0.times_i();
+		b.add(t0);
+	z3.norm();
+		z3.times_i();
+		a.copy(z0); a.add(z3);
+		norm();
+//System.out.println("Out of mul");
+	}
+
+/* Special case of multiplication arises from special form of ATE pairing line function */
+	public void smul(FP12 y,int type)
+	{
+//System.out.println("Into smul");
+
+		if (type==ECP.D_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z2=new FP4(b);
+			FP4 z3=new FP4(b);
+			FP4 t0=new FP4(0);
+			FP4 t1=new FP4(y.a);
+			z0.mul(y.a);
+			z2.pmul(y.b.real());
+			b.add(a);
+			t1.real().add(y.b.real());
+
+			t1.norm();
+			b.norm();
+			b.mul(t1);
+			z3.add(c);
+			z3.norm();
+			z3.pmul(y.b.real());
+
+			t0.copy(z0); t0.neg();
+			t1.copy(z2); t1.neg();
+
+			b.add(t0);
+
+			b.add(t1);
+			z3.add(t1);
+			z2.add(t0);
+
+			t0.copy(a); t0.add(c);
+			t0.norm();
+			z3.norm();
+			t0.mul(y.a);
+			c.copy(z2); c.add(t0);
+
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		if (type==ECP.M_TYPE)
+		{
+			FP4 z0=new FP4(a);
+			FP4 z1=new FP4(0);
+			FP4 z2=new FP4(0);
+			FP4 z3=new FP4(0);
+			FP4 t0=new FP4(a);
+			FP4 t1=new FP4(0);
+		
+			z0.mul(y.a);
+			t0.add(b);
+			t0.norm();
+
+			z1.copy(t0); z1.mul(y.a);
+			t0.copy(b); t0.add(c);
+			t0.norm();
+
+			z3.copy(t0); //z3.mul(y.c);
+			z3.pmul(y.c.getb());
+			z3.times_i();
+
+			t0.copy(z0); t0.neg();
+
+			z1.add(t0);
+			b.copy(z1); 
+			z2.copy(t0);
+
+			t0.copy(a); t0.add(c);
+			t1.copy(y.a); t1.add(y.c);
+
+			t0.norm();
+			t1.norm();
+	
+			t0.mul(t1);
+			z2.add(t0);
+
+			t0.copy(c); 
+			
+			t0.pmul(y.c.getb());
+			t0.times_i();
+
+			t1.copy(t0); t1.neg();
+
+			c.copy(z2); c.add(t1);
+			z3.add(t1);
+			t0.times_i();
+			b.add(t0);
+			z3.norm();
+			z3.times_i();
+			a.copy(z0); a.add(z3);
+		}
+		norm();
+//System.out.println("Out of smul");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		FP4 f0=new FP4(a);
+		FP4 f1=new FP4(b);
+		FP4 f2=new FP4(a);
+		FP4 f3=new FP4(0);
+
+		norm();
+		f0.sqr();
+		f1.mul(c);
+		f1.times_i();
+		f0.sub(f1);
+	f0.norm();
+
+		f1.copy(c); f1.sqr();
+		f1.times_i();
+		f2.mul(b);
+		f1.sub(f2);
+	f1.norm();
+
+		f2.copy(b); f2.sqr();
+		f3.copy(a); f3.mul(c);
+		f2.sub(f3);
+	f2.norm();
+
+		f3.copy(b); f3.mul(f2);
+		f3.times_i();
+		a.mul(f0);
+		f3.add(a);
+		c.mul(f1);
+		c.times_i();
+
+		f3.add(c);
+	f3.norm();
+		f3.inverse();
+		a.copy(f0); a.mul(f3);
+		b.copy(f1); b.mul(f3);
+		c.copy(f2); c.mul(f3);
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		FP2 f2=new FP2(f);
+		FP2 f3=new FP2(f);
+
+		f2.sqr();
+		f3.mul(f2);
+
+		a.frob(f3);
+		b.frob(f3);
+		c.frob(f3);
+
+		b.pmul(f);
+		c.pmul(f2);
+	}
+
+/* trace function */
+	public FP4 trace()
+	{
+		FP4 t=new FP4(0);
+		t.copy(a);
+		t.imul(3);
+		t.reduce();
+		return t;
+	}
+
+/* convert from byte array to FP12 */
+	public static FP12 fromBytes(byte[] w)
+	{
+		BIG a,b;
+		FP2 c,d;
+		FP4 e,f,g;
+		byte[] t=new byte[BIG.MODBYTES];
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+2*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+3*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		e=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+4*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+5*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+6*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+7*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		f=new FP4(c,d);
+
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+8*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+9*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		c=new FP2(a,b);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+10*BIG.MODBYTES];
+		a=BIG.fromBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=w[i+11*BIG.MODBYTES];
+		b=BIG.fromBytes(t);
+		d=new FP2(a,b);
+
+		g=new FP4(c,d);
+
+		return new FP12(e,f,g);
+	}
+
+/* convert this to byte array */
+	public void toBytes(byte[] w)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		a.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i]=t[i];
+		a.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+BIG.MODBYTES]=t[i];
+		a.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+2*BIG.MODBYTES]=t[i];
+		a.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+3*BIG.MODBYTES]=t[i];
+
+		b.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+4*BIG.MODBYTES]=t[i];
+		b.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+5*BIG.MODBYTES]=t[i];
+		b.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+6*BIG.MODBYTES]=t[i];
+		b.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+7*BIG.MODBYTES]=t[i];
+
+		c.geta().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+8*BIG.MODBYTES]=t[i];
+		c.geta().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+9*BIG.MODBYTES]=t[i];
+		c.getb().getA().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+10*BIG.MODBYTES]=t[i];
+		c.getb().getB().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) w[i+11*BIG.MODBYTES]=t[i];
+	}
+
+/* convert to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+","+c.toString()+"]");
+	}
+
+/* this=this^e */ 
+/* Note this is simple square and multiply, so not side-channel safe */
+	public FP12 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		BIG e3=new BIG(e);
+		e3.pmul(3);
+		e3.norm();
+
+		FP12 w=new FP12(this);
+
+		int nb=e3.nbits();
+		for (int i=nb-2;i>=1;i--)
+		{
+			w.usqr();
+			int bt=e3.bit(i)-e.bit(i);
+			if (bt==1)
+				w.mul(this);
+			if (bt==-1)
+			{
+				conj(); w.mul(this); conj();
+			}
+		}
+		w.reduce();
+		return w;
+
+
+/*
+		BIG z=new BIG(e);
+		FP12 r=new FP12(1);
+
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.usqr();
+		}
+		r.reduce();
+		return r; */
+	}
+
+/* constant time powering by small integer of max length bts */
+	public void pinpow(int e,int bts)
+	{
+		int i,b;
+		FP12 [] R=new FP12[2];
+		R[0]=new FP12(1);
+		R[1]=new FP12(this);
+		for (i=bts-1;i>=0;i--)
+		{
+			b=(e>>i)&1;
+			R[1-b].mul(R[b]);
+			R[b].usqr();
+		}
+		this.copy(R[0]);
+	}
+
+	public FP4 compow(BIG e,BIG r)
+	{
+		FP12 g1=new FP12(0);
+		FP12 g2=new FP12(0);
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG q=new BIG(ROM.Modulus);
+
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(e);
+		a.mod(m);
+
+		BIG b=new BIG(e);
+		b.div(m);
+
+		g1.copy(this);
+		g2.copy(this);
+
+		FP4 c=g1.trace();
+
+		if (b.iszilch())
+		{
+			c=c.xtr_pow(e);
+			return c;
+		}
+
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+
+		return c;
+	}
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+// Bos & Costello https://eprint.iacr.org/2013/458.pdf
+// Faz-Hernandez & Longa & Sanchez  https://eprint.iacr.org/2013/158.pdf
+// Side channel attack secure 
+
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,pb;
+		FP12 [] g=new FP12[8];
+		FP12 r=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+		byte[] s=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+		{
+			t[i]=new BIG(u[i]);
+			t[i].norm();
+		}
+		g[0]=new FP12(q[0]);  // q[0]
+		g[1]=new FP12(g[0]); g[1].mul(q[1]); // q[0].q[1]
+		g[2]=new FP12(g[0]); g[2].mul(q[2]); // q[0].q[2]
+		g[3]=new FP12(g[1]); g[3].mul(q[2]); // q[0].q[1].q[2]
+		g[4]=new FP12(q[0]); g[4].mul(q[3]); // q[0].q[3]
+		g[5]=new FP12(g[1]); g[5].mul(q[3]); // q[0].q[1].q[3]
+		g[6]=new FP12(g[2]); g[6].mul(q[3]); // q[0].q[2].q[3]
+		g[7]=new FP12(g[3]); g[7].mul(q[3]); // q[0].q[1].q[2].q[3]
+
+    // Make it odd
+        pb=1-t[0].parity();
+        t[0].inc(pb);
+        t[0].norm();
+
+    // Number of bits
+        mt.zero();
+        for (i=0;i<4;i++) {
+            mt.or(t[i]); 
+        }
+        nb=1+mt.nbits();
+
+    // Sign pivot 
+        s[nb-1]=1;
+        for (i=0;i<nb-1;i++) {
+            t[0].fshr(1);
+            s[i]=(byte)(2*t[0].parity()-1);
+        }
+
+    // Recoded exponent
+        for (i=0; i<nb; i++) {
+            w[i]=0;
+            int k=1;
+            for (j=1; j<4; j++) {
+                byte bt=(byte)(s[i]*t[j].parity());
+                t[j].fshr(1);
+                t[j].dec((int)(bt)>>1);
+                t[j].norm();
+                w[i]+=bt*(byte)k;
+                k*=2;
+            }
+        } 
+
+     // Main loop
+        p.select(g,(int)(2*w[nb-1]+1)); 
+        for (i=nb-2;i>=0;i--) {
+            p.usqr();
+            r.select(g,(int)(2*w[i]+s[i]));
+            p.mul(r);
+        }
+
+    // apply correction
+        r.copy(q[0]); r.conj();   
+        r.mul(p);
+        p.cmove(r,pb);
+
+ 		p.reduce();
+		return p;
+	}              
+
+/* p=q0^u0.q1^u1.q2^u2.q3^u3 */
+/* Timing attack secure, but not cache attack secure */
+/*
+	public static FP12 pow4(FP12[] q,BIG[] u)
+	{
+		int i,j,nb,m;
+		int[] a=new int[4];
+		FP12 [] g=new FP12[8];
+		FP12 [] s=new FP12[2];
+		FP12 c=new FP12(1);
+		FP12 p=new FP12(0);
+		BIG [] t=new BIG[4];
+		BIG mt=new BIG(0);
+		byte[] w=new byte[BIG.NLEN*BIG.BASEBITS+1];
+
+		for (i=0;i<4;i++)
+			t[i]=new BIG(u[i]);
+
+		s[0]=new FP12(0);
+		s[1]=new FP12(0);
+
+		g[0]=new FP12(q[0]); s[0].copy(q[1]); s[0].conj(); g[0].mul(s[0]);
+		g[1]=new FP12(g[0]);
+		g[2]=new FP12(g[0]);
+		g[3]=new FP12(g[0]);
+		g[4]=new FP12(q[0]); g[4].mul(q[1]);
+		g[5]=new FP12(g[4]);
+		g[6]=new FP12(g[4]);
+		g[7]=new FP12(g[4]);
+
+		s[1].copy(q[2]); s[0].copy(q[3]); s[0].conj(); s[1].mul(s[0]);
+		s[0].copy(s[1]); s[0].conj(); g[1].mul(s[0]);
+		g[2].mul(s[1]);
+		g[5].mul(s[0]);
+		g[6].mul(s[1]);
+		s[1].copy(q[2]); s[1].mul(q[3]);
+		s[0].copy(s[1]); s[0].conj(); g[0].mul(s[0]);
+		g[3].mul(s[1]);
+		g[4].mul(s[0]);
+		g[7].mul(s[1]);
+
+// if power is even add 1 to power, and add q to correction 
+
+		for (i=0;i<4;i++)
+		{
+			if (t[i].parity()==0)
+			{
+				t[i].inc(1); t[i].norm();
+				c.mul(q[i]);
+			}
+			mt.add(t[i]); mt.norm();
+		}
+		c.conj();
+		nb=1+mt.nbits();
+
+// convert exponent to signed 1-bit window 
+		for (j=0;j<nb;j++)
+		{
+			for (i=0;i<4;i++)
+			{
+				a[i]=(t[i].lastbits(2)-2);
+				t[i].dec(a[i]); t[i].norm(); 
+				t[i].fshr(1);
+			}
+			w[j]=(byte)(8*a[0]+4*a[1]+2*a[2]+a[3]);
+		}
+		w[nb]=(byte)(8*t[0].lastbits(2)+4*t[1].lastbits(2)+2*t[2].lastbits(2)+t[3].lastbits(2));
+		p.copy(g[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			m=w[i]>>7;
+			j=(w[i]^m)-m;  // j=abs(w[i]) 
+			j=(j-1)/2;
+			s[0].copy(g[j]); s[1].copy(g[j]); s[1].conj();
+			p.usqr();
+			p.mul(s[m&1]);
+		}
+		p.mul(c);  // apply correction 
+		p.reduce();
+		return p;
+	}
+*/
+/*
+	public static void main(String[] args) {
+		BIG p=new BIG(ROM.Modulus);
+		FP2 w0,w1;
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.zero(); b.zero(); a.inc(1); b.inc(2);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(3); b.inc(4);
+		w1=new FP2(a,b);
+		FP4 t0=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(5); b.inc(6);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(7); b.inc(8);
+		w1=new FP2(a,b);
+		FP4 t1=new FP4(w0,w1);
+
+		a.zero(); b.zero(); a.inc(9); b.inc(10);
+		w0=new FP2(a,b);
+		a.zero(); b.zero(); a.inc(11); b.inc(12);
+		w1=new FP2(a,b);
+		FP4 t2=new FP4(w0,w1);
+
+		FP12 w=new FP12(t0,t1,t2);
+		FP12 t=new FP12(w);
+
+		System.out.println("w= "+w.toString());
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		w.frob(f);
+		System.out.println("w= "+w.toString());
+
+		w=t.pow(p);
+
+		System.out.println("w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/w= "+w.toString());
+
+		w.inverse();
+
+		System.out.println("w= "+w.toString());
+
+		t.copy(w);
+		w.conj();
+		t.inverse();
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)= "+w.toString());
+
+		t.copy(w);
+		w.frob(f);
+		w.frob(f);
+		w.mul(t);
+
+		System.out.println("w^(p^6-1)(p^2+1)= "+w.toString());
+
+		t.copy(w);
+
+		t.inverse();
+		w.conj();
+
+		System.out.println("w= "+w.toString());
+		System.out.println("t= "+t.toString());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/FP2.java b/src/main/java/org/apache/milagro/amcl/FP512BN/FP2.java
new file mode 100644
index 0000000..50a4d6d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/FP2.java
@@ -0,0 +1,425 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^2 functions */
+
+/* FP2 elements are of the form a+ib, where i is sqrt(-1) */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class FP2 {
+	private final FP a;
+	private final FP b;
+
+/* reduce components mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+
+/* normalise components of w */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+
+/* test this=0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP2 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this=1 ? */
+	public boolean isunity() {
+		FP one=new FP(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test this=x */
+	public boolean equals(FP2 x) {
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+
+/* Constructors */
+	public FP2(int c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(FP2 x)
+	{
+		a=new FP(x.a);
+		b=new FP(x.b);
+	}
+
+	public FP2(FP c,FP d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(BIG c,BIG d)
+	{
+		a=new FP(c);
+		b=new FP(d);
+	}
+
+	public FP2(FP c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+
+	public FP2(BIG c)
+	{
+		a=new FP(c);
+		b=new FP(0);
+	}
+/*
+	public BIG geta()
+	{
+		return a.tobig();
+	}
+*/
+/* extract a */
+	public BIG getA()
+	{ 
+		return a.redc();
+	}
+
+/* extract b */
+	public BIG getB()
+	{
+		return b.redc();
+	}
+
+/* copy this=x */
+	public void copy(FP2 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+
+/* negate this mod Modulus */
+	public void neg()
+	{
+		FP m=new FP(a);
+		FP t=new FP(0);
+
+		m.add(b);
+		m.neg();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	}
+
+/* set to a-ib */
+	public void conj()
+	{
+		b.neg();
+		b.norm();
+	}
+
+/* this+=a */
+	public void add(FP2 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+
+/* this-=a */
+	public void sub(FP2 x)
+	{
+		FP2 m=new FP2(x);
+		m.neg();
+		add(m);
+	}
+
+	public void rsub(FP2 x)       // *****
+	{
+		neg();
+		add(x);
+	}
+
+/* this*=s, where s is an FP */
+	public void pmul(FP s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this*=i, where i is an int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+
+/* this*=this */
+	public void sqr()
+	{
+		FP w1=new FP(a);
+		FP w3=new FP(a);
+		FP mb=new FP(b);
+
+		w1.add(b);
+		mb.neg();
+
+		w3.add(a);
+		w3.norm();
+		b.mul(w3);
+
+		a.add(mb);
+
+		w1.norm();
+		a.norm();
+
+		a.mul(w1);
+	}
+
+/* this*=y */
+/* Now uses Lazy reduction */
+	public void mul(FP2 y)
+	{
+		if ((long)(a.XES+b.XES)*(y.a.XES+y.b.XES)>(long)FP.FEXCESS)
+		{
+			if (a.XES>1) a.reduce();
+			if (b.XES>1) b.reduce();		
+		}
+
+		DBIG pR=new DBIG(0);
+		BIG C=new BIG(a.x);
+		BIG D=new BIG(y.a.x);
+
+		pR.ucopy(new BIG(ROM.Modulus));
+
+		DBIG A=BIG.mul(a.x,y.a.x);
+		DBIG B=BIG.mul(b.x,y.b.x);
+
+		C.add(b.x); C.norm();
+		D.add(y.b.x); D.norm();
+
+		DBIG E=BIG.mul(C,D);
+		DBIG F=new DBIG(A); F.add(B);
+		B.rsub(pR);
+
+		A.add(B); A.norm();
+		E.sub(F); E.norm();
+
+		a.x.copy(FP.mod(A)); a.XES=3;
+		b.x.copy(FP.mod(E)); b.XES=2;
+	}
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP w1=new FP(b);
+		FP w2=new FP(a);
+		w1.sqr(); w2.sqr(); w1.add(w2);
+		if (w1.jacobi()!=1) { zero(); return false; }
+		w1=w1.sqrt();
+		w2.copy(a); w2.add(w1); 
+		w2.norm(); w2.div2();
+		if (w2.jacobi()!=1)
+		{
+			w2.copy(a); w2.sub(w1); 
+			w2.norm(); w2.div2();
+			if (w2.jacobi()!=1) { zero(); return false; }
+		}
+		w2=w2.sqrt();
+		a.copy(w2);
+		w2.add(w2);
+		w2.inverse();
+		b.mul(w2);
+		return true;
+	}
+
+/* output to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+		norm();
+		FP w1=new FP(a);
+		FP w2=new FP(b);
+
+		w1.sqr();
+		w2.sqr();
+		w1.add(w2);
+		w1.inverse();
+		a.mul(w1);
+		w1.neg();
+		w1.norm();
+		b.mul(w1);
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+/* this*=sqrt(-1) */
+	public void times_i()
+	{
+		FP z=new FP(a);
+		a.copy(b); a.neg();
+		b.copy(z);
+	}
+
+/* w*=(1+sqrt(-1)) */
+/* where X*2-(1+sqrt(-1)) is irreducible for FP4, assumes p=3 mod 8 */
+	public void mul_ip()
+	{
+		FP2 t=new FP2(this);
+		FP z=new FP(a);
+		a.copy(b);
+		a.neg();
+		b.copy(z);
+		add(t);
+	}
+
+	public void div_ip2()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+	}
+
+/* w/=(1+sqrt(-1)) */
+	public void div_ip()
+	{
+		FP2 t=new FP2(0);
+		norm();
+		t.a.copy(a); t.a.add(b);
+		t.b.copy(b); t.b.sub(a);
+		copy(t);
+		norm();
+		div2();
+	}
+/*
+	public FP2 pow(BIG e)
+	{
+		int bt;
+		FP2 r=new FP2(1);
+		e.norm();
+		norm();
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(this);
+			if (e.iszilch()) break;
+			sqr();
+		}
+
+		r.reduce();
+		return r;
+	}
+
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(27);
+		BIG pp1=new BIG(m);
+		BIG pm1=new BIG(m);
+		BIG a=new BIG(1);
+		BIG b=new BIG(1);
+		FP2 w=new FP2(a,b);
+		FP2 z=new FP2(w);
+
+		byte[] RAW=new byte[100];
+
+		RAND rng=new RAND();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+	//	for (int i=0;i<100;i++)
+	//	{
+			a.randomnum(rng);
+			b.randomnum(rng);
+
+			w=new FP2(a,b);
+			System.out.println("w="+w.toString());
+
+			z=new FP2(w);
+			z.inverse();
+			System.out.println("z="+z.toString());
+
+			z.inverse();
+			if (!z.equals(w)) System.out.println("Error");
+	//	}
+
+//		System.out.println("m="+m.toString());
+//		w.sqr();
+//		w.mul(z);
+
+		System.out.println("w="+w.toString());
+
+
+		pp1.inc(1); pp1.norm();
+		pm1.dec(1); pm1.norm();
+		System.out.println("p+1="+pp1.toString());
+		System.out.println("p-1="+pm1.toString());
+		w=w.pow(pp1);
+		w=w.pow(pm1);
+		System.out.println("w="+w.toString());
+	}
+*/
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/FP4.java b/src/main/java/org/apache/milagro/amcl/FP512BN/FP4.java
new file mode 100644
index 0000000..97fa39f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/FP4.java
@@ -0,0 +1,721 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic  Fp^4 functions */
+
+/* FP4 elements are of the form a+ib, where i is sqrt(-1+sqrt(-1))  */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class FP4 {
+	private final FP2 a;
+	private final FP2 b;
+/* reduce all components of this mod Modulus */
+	public void reduce()
+	{
+		a.reduce();
+		b.reduce();
+	}
+/* normalise all components of this mod Modulus */
+	public void norm()
+	{
+		a.norm();
+		b.norm();
+	}
+/* test this==0 ? */
+	public boolean iszilch() {
+		//reduce();
+		return (a.iszilch() && b.iszilch());
+	}
+
+	public void cmove(FP4 g,int d)
+	{
+		a.cmove(g.a,d);
+		b.cmove(g.b,d);
+	}
+
+/* test this==1 ? */
+	public boolean isunity() {
+		FP2 one=new FP2(1);
+		return (a.equals(one) && b.iszilch());
+	}
+
+/* test is w real? That is in a+ib test b is zero */
+	public boolean isreal()
+	{
+		return b.iszilch();
+	}
+/* extract real part a */
+	public FP2 real()
+	{
+		return a;
+	}
+
+	public FP2 geta()
+	{
+		return a;
+	}
+/* extract imaginary part b */
+	public FP2 getb()
+	{
+		return b;
+	}
+/* test this=x? */
+	public boolean equals(FP4 x)
+	{
+		return (a.equals(x.a) && b.equals(x.b));
+	}
+/* constructors */
+	public FP4(int c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+
+	public FP4(FP4 x)
+	{
+		a=new FP2(x.a);
+		b=new FP2(x.b);
+	}
+
+	public FP4(FP2 c,FP2 d)
+	{
+		a=new FP2(c);
+		b=new FP2(d);
+	}
+
+	public FP4(FP2 c)
+	{
+		a=new FP2(c);
+		b=new FP2(0);
+	}
+/* copy this=x */
+	public void copy(FP4 x)
+	{
+		a.copy(x.a);
+		b.copy(x.b);
+	}
+/* set this=0 */
+	public void zero()
+	{
+		a.zero();
+		b.zero();
+	}
+/* set this=1 */
+	public void one()
+	{
+		a.one();
+		b.zero();
+	}
+/* set this=-this */
+	public void neg()
+	{
+		norm();
+		FP2 m=new FP2(a);
+		FP2 t=new FP2(0);
+		m.add(b);
+//	m.norm();
+		m.neg();
+	//	m.norm();
+		t.copy(m); t.add(b);
+		b.copy(m);
+		b.add(a);
+		a.copy(t);
+	norm();
+	}
+/* this=conjugate(this) */
+	public void conj()
+	{
+		b.neg(); norm();
+	}
+/* this=-conjugate(this) */
+	public void nconj()
+	{
+		a.neg(); norm();
+	}
+/* this+=x */
+	public void add(FP4 x)
+	{
+		a.add(x.a);
+		b.add(x.b);
+	}
+/* this-=x */
+	public void sub(FP4 x)
+	{
+		FP4 m=new FP4(x);
+		m.neg();
+		add(m);
+	}
+
+/* this*=s where s is FP2 */
+	public void pmul(FP2 s)
+	{
+		a.mul(s);
+		b.mul(s);
+	}
+
+/* this=x-this */
+	public void rsub(FP4 x)
+	{
+		neg();
+		add(x);
+	}
+
+
+/* this*=c where c is int */
+	public void imul(int c)
+	{
+		a.imul(c);
+		b.imul(c);
+	}
+/* this*=this */	
+	public void sqr()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(a);
+
+		t3.mul(b);
+		t1.add(b);
+		t2.mul_ip();
+
+		t2.add(a);
+
+		t1.norm();
+		t2.norm();
+
+		a.copy(t1);
+
+		a.mul(t2);
+
+		t2.copy(t3);
+		t2.mul_ip();
+		t2.add(t3);
+		t2.norm();
+		t2.neg();
+		a.add(t2);
+
+		b.copy(t3);
+		b.add(t3);
+
+		norm();
+	}
+/* this*=y */
+	public void mul(FP4 y)
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+		FP2 t3=new FP2(0);
+		FP2 t4=new FP2(b);
+
+		t1.mul(y.a);
+		t2.mul(y.b);
+		t3.copy(y.b);
+		t3.add(y.a);
+		t4.add(a);
+
+	t3.norm();
+	t4.norm();
+
+		t4.mul(t3);
+
+	t3.copy(t1);
+	t3.neg();
+	t4.add(t3);
+	t4.norm();
+
+	//	t4.sub(t1);
+	//	t4.norm();
+
+	t3.copy(t2);
+	t3.neg();
+	b.copy(t4);
+	b.add(t3);
+
+	//	b.copy(t4);
+	//	b.sub(t2);
+
+		t2.mul_ip();
+		a.copy(t2);
+		a.add(t1);
+
+		norm();
+	}
+/* convert this to hex string */
+	public String toString() 
+	{
+		return ("["+a.toString()+","+b.toString()+"]");
+	}
+
+	public String toRawString() 
+	{
+		return ("["+a.toRawString()+","+b.toRawString()+"]");
+	}
+
+/* this=1/this */
+	public void inverse()
+	{
+//		norm();
+
+		FP2 t1=new FP2(a);
+		FP2 t2=new FP2(b);
+
+		t1.sqr();
+		t2.sqr();
+		t2.mul_ip();
+	t2.norm();
+		t1.sub(t2);
+		t1.inverse();
+		a.mul(t1);
+		t1.neg();
+	t1.norm();
+		b.mul(t1);
+	}
+
+
+/* this*=i where i = sqrt(-1+sqrt(-1)) */
+	public void times_i()
+	{
+//		norm();
+		FP2 s=new FP2(b);
+		FP2 t=new FP2(b);
+		s.times_i();
+		t.add(s);
+	//	t.norm();
+		b.copy(a);
+		a.copy(t);
+		norm();
+	}
+
+/* this=this^p using Frobenius */
+	public void frob(FP2 f)
+	{
+		a.conj();
+		b.conj();
+		b.mul(f);
+	}
+
+/* this=this^e */
+	public FP4 pow(BIG e)
+	{
+		norm();
+		e.norm();
+		FP4 w=new FP4(this);
+		BIG z=new BIG(e);
+		FP4 r=new FP4(1);
+		while (true)
+		{
+			int bt=z.parity();
+			z.fshr(1);
+			if (bt==1) r.mul(w);
+			if (z.iszilch()) break;
+			w.sqr();
+		}
+		r.reduce();
+		return r;
+	}
+/* XTR xtr_a function */
+	public void xtr_A(FP4 w,FP4 y,FP4 z) 
+	{
+		FP4 r=new FP4(w);
+		FP4 t=new FP4(w);
+	//y.norm();
+		r.sub(y);
+	r.norm();
+		r.pmul(a);
+		t.add(y);
+	t.norm();
+		t.pmul(b);
+		t.times_i();
+
+		copy(r);
+		add(t);
+		add(z);
+
+		norm();
+	}
+
+/* XTR xtr_d function */
+	public void xtr_D() {
+		FP4 w=new FP4(this);
+		sqr(); w.conj();
+		w.add(w);
+	w.norm();
+		sub(w);
+		reduce();
+	}
+
+/* r=x^n using XTR method on traces of FP12s */
+	public FP4 xtr_pow(BIG n) {
+		FP4 a=new FP4(3);
+		FP4 b=new FP4(this);
+		FP4 c=new FP4(b);
+		c.xtr_D();
+		FP4 t=new FP4(0);
+		FP4 r=new FP4(0);
+
+		n.norm();
+		int par=n.parity();
+		BIG v=new BIG(n); v.fshr(1);
+		if (par==0) {v.dec(1); v.norm();}
+
+		int nb=v.nbits();
+		for (int i=nb-1;i>=0;i--)
+		{
+			if (v.bit(i)!=1)
+			{
+				t.copy(b);
+				conj();
+				c.conj();
+				b.xtr_A(a,this,c);
+				conj();
+				c.copy(t);
+				c.xtr_D();
+				a.xtr_D();
+			}
+			else
+			{
+				t.copy(a); t.conj();
+				a.copy(b);
+				a.xtr_D();
+				b.xtr_A(c,this,t);
+				c.xtr_D();
+			}
+		}
+		if (par==0) r.copy(c);
+		else r.copy(b);
+		r.reduce();
+		return r;
+	}
+
+/* r=ck^a.cl^n using XTR double exponentiation method on traces of FP12s. See Stam thesis. */
+	public FP4 xtr_pow2(FP4 ck,FP4 ckml,FP4 ckm2l,BIG a,BIG b)
+	{
+		a.norm(); b.norm();
+		BIG e=new BIG(a);
+		BIG d=new BIG(b);
+		BIG w=new BIG(0);
+
+		FP4 cu=new FP4(ck);  // can probably be passed in w/o copying
+		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);
+
+		int f2=0;
+		while (d.parity()==0 && e.parity()==0)
+		{
+			d.fshr(1);
+			e.fshr(1);
+			f2++;
+		}
+
+		while (BIG.comp(d,e)!=0)
+		{
+			if (BIG.comp(d,e)>0)
+			{
+				w.copy(e); w.imul(4); w.norm();
+				if (BIG.comp(d,w)<=0)
+				{
+					w.copy(d); d.copy(e);
+					e.rsub(w); e.norm();
+
+					t.copy(cv); 
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv); 
+					cum2v.conj();
+					cumv.copy(cv);
+					cv.copy(cu);
+					cu.copy(t);
+
+				}
+				else if (d.parity()==0)
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+				else if (e.parity()==1)
+				{
+					d.sub(e); d.norm();
+					d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cu.xtr_D();
+					cum2v.copy(cv);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cv.copy(t);
+				}
+				else
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+			}
+			if (BIG.comp(d,e)<0)
+			{
+				w.copy(d); w.imul(4); w.norm();
+				if (BIG.comp(e,w)<=0)
+				{
+					e.sub(d); e.norm();
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cum2v.copy(cumv);
+					cumv.copy(cu);
+					cu.copy(t);
+				}
+				else if (e.parity()==0)
+				{
+					w.copy(d);
+					d.copy(e); d.fshr(1);
+					e.copy(w);
+					t.copy(cumv);
+					t.xtr_D();
+					cumv.copy(cum2v); cumv.conj();
+					cum2v.copy(t); cum2v.conj();
+					t.copy(cv);
+					t.xtr_D();
+					cv.copy(cu);
+					cu.copy(t);
+				}
+				else if (d.parity()==1)
+				{
+					w.copy(e);
+					e.copy(d);
+					w.sub(d); w.norm();
+					d.copy(w); d.fshr(1);
+					t.copy(cv);
+					t.xtr_A(cu,cumv,cum2v);
+					cumv.conj();
+					cum2v.copy(cu);
+					cum2v.xtr_D();
+					cum2v.conj();
+					cu.copy(cv);
+					cu.xtr_D();
+					cv.copy(t);
+				}
+				else
+				{
+					d.fshr(1);
+					r.copy(cum2v); r.conj();
+					t.copy(cumv);
+					t.xtr_A(cu,cv,r);
+					cum2v.copy(cumv);
+					cum2v.xtr_D();
+					cumv.copy(t);
+					cu.xtr_D();
+				}
+			}
+		}
+		r.copy(cv);
+		r.xtr_A(cu,cumv,cum2v);
+		for (int i=0;i<f2;i++)
+			r.xtr_D();
+		r=r.xtr_pow(d);
+		return r;
+	}
+
+/* this/=2 */
+	public void div2()
+	{
+		a.div2();
+		b.div2();
+	}
+
+	public void div_i()
+	{
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip();
+		a.copy(v);
+		b.copy(u);
+	}
+
+	public void div_2i() {
+		FP2 u=new FP2(a);
+		FP2 v=new FP2(b);
+		u.div_ip2();
+		v.add(v); v.norm();
+		a.copy(v);
+		b.copy(u);
+	}
+
+
+/* sqrt(a+ib) = sqrt(a+sqrt(a*a-n*b*b)/2)+ib/(2*sqrt(a+sqrt(a*a-n*b*b)/2)) */
+/* returns true if this is QR */
+	public boolean sqrt()
+	{
+		if (iszilch()) return true;
+		FP2 wa=new FP2(a);
+		FP2 ws=new FP2(b);
+		FP2 wt=new FP2(a);
+		
+		if (ws.iszilch())
+		{
+			if (wt.sqrt())
+			{
+				a.copy(wt);
+				b.zero();
+			} else {
+				wt.div_ip();
+				wt.sqrt();
+				b.copy(wt);
+				a.zero();
+			}
+			return true;
+		}
+
+		ws.sqr();
+		wa.sqr();
+		ws.mul_ip();
+		ws.norm();
+		wa.sub(ws);
+
+		ws.copy(wa);
+		if (!ws.sqrt()) {
+			return false;
+		}
+
+		wa.copy(wt); wa.add(ws); wa.norm(); wa.div2();
+
+		if (!wa.sqrt()) {
+			wa.copy(wt); wa.sub(ws); wa.norm(); wa.div2();
+			if (!wa.sqrt()) {
+				return false;
+			}
+		}
+		wt.copy(b);
+		ws.copy(wa); ws.add(wa);
+		ws.inverse();
+
+		wt.mul(ws);
+		a.copy(wa);
+		b.copy(wt);
+
+		return true;
+	}
+
+/* this*=s where s is FP */
+	public void qmul(FP s)
+	{
+		a.pmul(s);
+		b.pmul(s);
+	}
+
+
+
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG e=new BIG(12);
+		BIG a=new BIG(0);
+		BIG b=new BIG(0);
+		
+		a.inc(27); b.inc(45);
+
+		FP2 w0=new FP2(a,b);
+
+		a.zero(); b.zero();
+		a.inc(33); b.inc(54);
+
+		FP2 w1=new FP2(a,b);
+
+
+		FP4 w=new FP4(w0,w1);
+		FP4 t=new FP4(w);
+
+		a=new BIG(ROM_ZZZ.CURVE_Fra);
+		b=new BIG(ROM_ZZZ.CURVE_Frb);
+
+		FP2 f=new FP2(a,b);
+
+		System.out.println("w= "+w.toString());
+
+		w=w.pow(m);
+
+		System.out.println("w^p= "+w.toString());
+
+		t.frob(f);
+
+
+		System.out.println("w^p= "+t.toString());
+
+		w=w.pow(m);
+		w=w.pow(m);
+		w=w.pow(m);
+		System.out.println("w^p4= "+w.toString());
+
+
+	System.out.println("Test Inversion");
+
+		w=new FP4(w0,w1);
+
+		w.inverse();
+
+		System.out.println("1/w mod p^4 = "+w.toString());
+
+		w.inverse();
+
+		System.out.println("1/(1/w) mod p^4 = "+w.toString());
+
+		FP4 ww=new FP4(w);
+
+		w=w.xtr_pow(e);
+		System.out.println("w^e= "+w.toString());
+
+
+		a.zero(); b.zero();
+		a.inc(37); b.inc(17);
+		w0=new FP2(a,b);
+		a.zero(); b.zero();
+		a.inc(49); b.inc(31);
+		w1=new FP2(a,b);
+
+		FP4 c1=new FP4(w0,w1);
+		FP4 c2=new FP4(w0,w1);
+		FP4 c3=new FP4(w0,w1);
+
+		BIG e1=new BIG(3331);
+		BIG e2=new BIG(3372);
+
+		FP4 cr=w.xtr_pow2(c1,c2,c3,e1,e2);
+
+		System.out.println("c^e= "+cr.toString()); 
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/MPIN.java b/src/main/java/org/apache/milagro/amcl/FP512BN/MPIN.java
new file mode 100644
index 0000000..6f43fba
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/MPIN.java
@@ -0,0 +1,823 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* MPIN API Functions */
+
+package org.apache.milagro.amcl.FP512BN;
+
+import java.util.Date;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public class MPIN
+{
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int PAS=16;
+	public static final int INVALID_POINT=-14;
+	public static final int BAD_PARAMS=-11;
+	public static final int WRONG_ORDER=-18;
+	public static final int BAD_PIN=-19;
+
+/* Configure your PIN here */
+
+	public static final int MAXPIN=10000;  /* PIN less than this */
+	public static final int PBLEN=14;      /* Number of bits in PIN */
+	public static final int TS=10;         /* 10 for 4 digit PIN, 14 for 6-digit PIN - 2^TS/TS approx = sqrt(MAXPIN) */
+	public static final int TRAP=200;      /* 200 for 4 digit PIN, 2000 for 6-digit PIN  - approx 2*sqrt(MAXPIN) */
+
+//	public static final int HASH_TYPE=SHA256;
+
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,int n,byte[] B,int len)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (n>0) H.process_num(n);
+
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (n>0) H.process_num(n);
+			H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+		byte[] W=new byte[len];
+
+		if (sha>=len)
+			for (int i=0;i<len;i++) W[i]=R[i];
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+len-sha]=R[i];
+            for (int i=0;i<len-sha;i++) W[i]=0;
+
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<len;i++) W[i]=0;
+		}
+		return W;
+	}
+
+	/* return time in slots since epoch */
+	public static int today() {
+		Date date=new Date();
+		return (int) (date.getTime()/(1000*60*1440));
+	}
+
+	public static byte[] HASH_ID(int sha,byte[] ID,int len)
+	{
+		return hashit(sha,0,ID,len);
+	}
+
+/* Hash the M-Pin transcript - new */
+
+	public static byte[] HASH_ALL(int sha,byte[] HID,byte[] xID,byte[] xCID,byte[] SEC,byte[] Y,byte[] R,byte[] W,int len)
+	{
+		int i,ilen,tlen=0;
+
+		ilen=HID.length+SEC.length+Y.length+R.length+W.length;
+		if (xCID!=null) ilen+=xCID.length;
+		else ilen+=xID.length;
+
+		byte[] T = new byte[ilen];
+
+		for (i=0;i<HID.length;i++) T[i]=HID[i];
+		tlen+=HID.length;
+		if (xCID!=null)
+		{
+			for (i=0;i<xCID.length;i++) T[i+tlen]=xCID[i];
+			tlen+=xCID.length;
+		}	
+		else
+		{
+			for (i=0;i<xID.length;i++) T[i+tlen]=xID[i];
+			tlen+=xID.length;
+		}	
+		for (i=0;i<SEC.length;i++) T[i+tlen]=SEC[i];
+		tlen+=SEC.length;		
+		for (i=0;i<Y.length;i++) T[i+tlen]=Y[i];
+		tlen+=Y.length;	
+		for (i=0;i<R.length;i++) T[i+tlen]=R[i];
+		tlen+=R.length;		
+		for (i=0;i<W.length;i++) T[i+tlen]=W[i];
+		tlen+=W.length;		
+
+		return hashit(sha,0,T,len);
+	}
+
+/* return time since epoch */
+	public static int GET_TIME() {
+		Date date=new Date();
+		return (int) (date.getTime()/1000);
+	}
+
+	public static byte[] mpin_hash(int sha,FP4 c,ECP U)
+	{
+		byte[] w=new byte[EFS];
+		byte[] t=new byte[6*EFS];
+		byte[] h=null;
+		c.geta().getA().toBytes(w); for (int i=0;i<EFS;i++) t[i]=w[i];
+		c.geta().getB().toBytes(w); for (int i=EFS;i<2*EFS;i++) t[i]=w[i-EFS];
+		c.getb().getA().toBytes(w); for (int i=2*EFS;i<3*EFS;i++) t[i]=w[i-2*EFS];
+		c.getb().getB().toBytes(w); for (int i=3*EFS;i<4*EFS;i++) t[i]=w[i-3*EFS];
+
+		U.getX().toBytes(w); for (int i=4*EFS;i<5*EFS;i++) t[i]=w[i-4*EFS];
+		U.getY().toBytes(w); for (int i=5*EFS;i<6*EFS;i++) t[i]=w[i-5*EFS];
+		
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(t);
+			h=H.hash();
+		}
+		if (h==null) return null;
+		byte[] R=new byte[ECP.AESKEY];
+		for (int i=0;i<ECP.AESKEY;i++) R[i]=h[i];
+		return R;
+	}
+
+/* these next two functions help to implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* maps a random u to a point on the curve */
+	public static ECP map(BIG u,int cb)
+	{
+		ECP P;
+		BIG x=new BIG(u);
+		BIG p=new BIG(ROM.Modulus);
+		x.mod(p);
+		while (true)
+		{
+			P=new ECP(x,cb);
+			if (!P.is_infinity()) break;
+			x.inc(1);  x.norm();
+		}
+		return P;
+	}
+
+/* returns u derived from P. Random value in range 1 to return value should then be added to u */
+	public static int unmap(BIG u,ECP P)
+	{
+		int s=P.getS();
+		ECP R;
+		int r=0;
+		BIG x=P.getX();
+		u.copy(x);
+		while (true)
+		{
+			u.dec(1); u.norm();
+			r++;
+			R=new ECP(u,s);
+			if (!R.is_infinity()) break;
+		}
+		return r;
+	}
+
+
+
+/* these next two functions implement elligator squared - http://eprint.iacr.org/2014/043 */
+/* Elliptic curve point E in format (0x04,x,y} is converted to form {0x0-,u,v} */
+/* Note that u and v are indistinguisible from random strings */
+	public static int ENCODING(RAND rng,byte[] E)
+	{
+		int rn,m,su,sv;
+		byte[] T=new byte[EFS];
+
+		for (int i=0;i<EFS;i++) T[i]=E[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=E[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+		
+		ECP P=new ECP(u,v);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG p=new BIG(ROM.Modulus);
+		u=BIG.randomnum(p,rng);
+
+		su=rng.getByte(); /*if (su<0) su=-su;*/ su%=2;
+		
+		ECP W=map(u,su);
+		P.sub(W); //P.affine();
+		sv=P.getS();
+		rn=unmap(v,P);
+		m=rng.getByte(); /*if (m<0) m=-m;*/ m%=rn;
+		v.inc(m+1);
+		E[0]=(byte)(su+2*sv);
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) E[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+	public static int DECODING(byte[] D)
+	{
+		int su,sv;
+		byte[] T=new byte[EFS];
+
+		if ((D[0]&0x04)!=0) return INVALID_POINT;
+
+		for (int i=0;i<EFS;i++) T[i]=D[i+1];
+		BIG u=BIG.fromBytes(T);
+		for (int i=0;i<EFS;i++) T[i]=D[i+EFS+1];
+		BIG v=BIG.fromBytes(T);
+
+		su=D[0]&1;
+		sv=(D[0]>>1)&1;
+		ECP W=map(u,su);
+		ECP P=map(v,sv);
+		P.add(W); //P.affine();
+		u=P.getX();
+		v=P.getY();
+		D[0]=0x04;
+		u.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+1]=T[i];
+		v.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i+EFS+1]=T[i];		
+		
+		return 0;
+	}
+
+/* R=R1+R2 in group G1 */
+	public static int RECOMBINE_G1(byte[] R1,byte[] R2,byte[] R)
+	{
+		ECP P=ECP.fromBytes(R1);
+		ECP Q=ECP.fromBytes(R2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+
+		P.toBytes(R,false);
+		return 0;
+	}
+
+/* W=W1+W2 in group G2 */
+	public static int RECOMBINE_G2(byte[] W1,byte[] W2,byte[] W)
+	{
+		ECP2 P=ECP2.fromBytes(W1);
+		ECP2 Q=ECP2.fromBytes(W2);
+
+		if (P.is_infinity() || Q.is_infinity()) return INVALID_POINT;
+
+		P.add(Q); //P.affine();
+	
+		P.toBytes(W);
+		return 0;
+	}
+	
+/* create random secret S */
+	public static int RANDOM_GENERATE(RAND rng,byte[] S)
+	{
+		BIG s;
+		BIG r=new BIG(ROM.CURVE_Order);
+		s=BIG.randomnum(r,rng);
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+		return 0;
+	}
+
+/* Extract PIN from TOKEN for identity CID */
+	public static int EXTRACT_PIN(int sha,byte[] CID,int pin,byte[] TOKEN)
+	{
+		ECP P=ECP.fromBytes(TOKEN);
+		if (P.is_infinity()) return INVALID_POINT;
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R=ECP.mapit(h);
+
+
+		pin%=MAXPIN;
+
+		R=R.pinmul(pin,PBLEN);
+		P.sub(R); //P.affine();
+
+		P.toBytes(TOKEN,false);
+
+		return 0;
+	}
+
+/* Implement step 2 on client side of MPin protocol */
+	public static int CLIENT_2(byte[] X,byte[] Y,byte[] SEC)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		ECP P=ECP.fromBytes(SEC);
+		if (P.is_infinity()) return INVALID_POINT;
+
+		BIG px=BIG.fromBytes(X);
+		BIG py=BIG.fromBytes(Y);
+		px.add(py);
+		px.mod(r);
+	//	px.rsub(r);
+
+		P=PAIR.G1mul(P,px);
+		P.neg();
+		P.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Implement step 1 on client side of MPin protocol */
+	public static int CLIENT_1(int sha,int date,byte[] CLIENT_ID,RAND rng,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT)
+	{
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG x;
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P,T,W;
+		BIG px;
+//		byte[] t=new byte[EFS];
+
+		byte[] h=hashit(sha,0,CLIENT_ID,EFS);
+		P=ECP.mapit(h);
+	
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT;
+
+		pin%=MAXPIN;
+		W=P.pinmul(pin,PBLEN);
+		T.add(W);
+		if (date!=0)
+		{
+			W=ECP.fromBytes(PERMIT);
+			if (W.is_infinity()) return INVALID_POINT;
+			T.add(W);
+			h=hashit(sha,date,h,EFS);
+			W=ECP.mapit(h);
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+				W=PAIR.G1mul(W,x);
+				P.add(W);
+				//P.affine();
+			}
+			else
+			{
+				P.add(W); //P.affine();
+				P=PAIR.G1mul(P,x);
+			}
+			if (xCID!=null) P.toBytes(xCID,false);
+		}
+		else
+		{
+			if (xID!=null)
+			{
+				P=PAIR.G1mul(P,x);
+				P.toBytes(xID,false);
+			}
+		}
+
+		//T.affine();
+		T.toBytes(SEC,false);
+		return 0;
+	}
+
+/* Extract Server Secret SST=S*Q where Q is fixed generator in G2 and S is master secret */
+	public static int GET_SERVER_SECRET(byte[] S,byte[] SST)
+	{
+		ECP2 Q=ECP2.generator();
+		BIG s=BIG.fromBytes(S);
+		Q=PAIR.G2mul(Q,s);
+		Q.toBytes(SST);
+		return 0;
+	}
+
+/*
+ W=x*H(G);
+ if RNG == NULL then X is passed in 
+ if RNG != NULL the X is passed out 
+ if type=0 W=x*G where G is point on the curve, else W=x*M(G), where M(G) is mapping of octet G to point on the curve
+*/
+	public static int GET_G1_MULTIPLE(RAND rng, int type,byte[] X,byte[] G,byte[] W)
+	{
+		BIG x;
+		BIG r=new BIG(ROM.CURVE_Order);
+		if (rng!=null)
+		{
+			x=BIG.randomnum(r,rng);
+			//if (ROM.AES_S>0)
+			//{
+			//	x.mod2m(2*ROM.AES_S);
+			//}
+			x.toBytes(X);
+		}
+		else
+		{
+			x=BIG.fromBytes(X);
+		}
+		ECP P;
+		if (type==0)
+		{
+			P=ECP.fromBytes(G);
+			if (P.is_infinity()) return INVALID_POINT;
+		}
+		else
+			P=ECP.mapit(G);
+
+		PAIR.G1mul(P,x).toBytes(W,false);
+		return 0;
+	}
+
+/* Client secret CST=S*H(CID) where CID is client ID and S is master secret */
+/* CID is hashed externally */
+	public static int GET_CLIENT_SECRET(byte[] S,byte[] CID,byte[] CST)
+	{
+		return GET_G1_MULTIPLE(null,1,S,CID,CST);
+	}
+
+/* Time Permit CTT=S*(date|H(CID)) where S is master secret */
+	public static int GET_CLIENT_PERMIT(int sha,int date,byte[] S,byte[] CID,byte[] CTT)
+	{
+		byte[] h=hashit(sha,date,CID,EFS);
+		ECP P=ECP.mapit(h);
+
+		BIG s=BIG.fromBytes(S);
+		ECP OP=PAIR.G1mul(P,s);
+
+		OP.toBytes(CTT,false);
+		return 0;
+	}
+
+/* Outputs H(CID) and H(T|H(CID)) for time permits. If no time permits set HID=HTID */
+	public static void SERVER_1(int sha,int date,byte[] CID,byte[] HID,byte[] HTID)
+	{
+		byte[] h=hashit(sha,0,CID,EFS);
+		ECP R,P=ECP.mapit(h);
+
+		P.toBytes(HID,false);   // new
+		if (date!=0)
+		{
+	//		if (HID!=null) P.toBytes(HID);
+			h=hashit(sha,date,h,EFS);
+			R=ECP.mapit(h);
+			P.add(R); //P.affine();
+			P.toBytes(HTID,false);
+		}
+	//	else P.toBytes(HID,false);
+	}
+
+/* Implement step 2 of MPin protocol on server side */
+	public static int SERVER_2(int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] mSEC,byte[] E,byte[] F)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		ECP2 Q=ECP2.generator();
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT;	
+
+		ECP R;
+		if (date!=0)
+			R=ECP.fromBytes(xCID);
+		else 
+		{
+			if (xID==null) return BAD_PARAMS;
+			R=ECP.fromBytes(xID);
+		}
+		if (R.is_infinity()) return INVALID_POINT;
+
+		BIG y=BIG.fromBytes(Y);
+		ECP P;
+		if (date!=0) P=ECP.fromBytes(HTID);
+		else 
+		{
+			if (HID==null) return BAD_PARAMS;
+			P=ECP.fromBytes(HID);
+		}
+	
+		if (P.is_infinity()) return INVALID_POINT;
+
+		P=PAIR.G1mul(P,y);
+		P.add(R); //P.affine();
+		R=ECP.fromBytes(mSEC);
+		if (R.is_infinity()) return INVALID_POINT;
+
+		FP12 g;
+
+		g=PAIR.ate2(Q,R,sQ,P);
+		g=PAIR.fexp(g);
+
+		if (!g.isunity())
+		{
+			if (HID!=null && xID!=null && E!=null && F!=null)
+			{
+				g.toBytes(E);
+				if (date!=0)
+				{
+					P=ECP.fromBytes(HID);
+					if (P.is_infinity()) return INVALID_POINT;
+					R=ECP.fromBytes(xID);
+					if (R.is_infinity()) return INVALID_POINT;
+
+					P=PAIR.G1mul(P,y);
+					P.add(R); //P.affine();
+				}
+				g=PAIR.ate(Q,P);
+				g=PAIR.fexp(g);
+				g.toBytes(F);
+			}
+			return BAD_PIN;
+		}
+
+		return 0;
+	}
+
+/* Pollards kangaroos used to return PIN error */
+	public static int KANGAROO(byte[] E,byte[] F)
+	{
+		FP12 ge=FP12.fromBytes(E);
+		FP12 gf=FP12.fromBytes(F);
+		int[] distance = new int[TS];
+		FP12 t=new FP12(gf);
+		FP12[] table=new FP12[TS];
+		int i,j,m,s,dn,dm,res,steps;
+
+		s=1;
+		for (m=0;m<TS;m++)
+		{
+			distance[m]=s;
+			table[m]=new FP12(t);
+			s*=2;
+			t.usqr();
+		}
+		t.one();
+		dn=0;
+		for (j=0;j<TRAP;j++)
+		{
+			i=t.geta().geta().getA().lastbits(20)%TS;
+			t.mul(table[i]);
+			dn+=distance[i];
+		}
+		gf.copy(t); gf.conj();
+		steps=0; dm=0;
+		res=0;
+		while (dm-dn<MAXPIN)
+		{
+			steps++;
+			if (steps>4*TRAP) break;
+			i=ge.geta().geta().getA().lastbits(20)%TS;
+			ge.mul(table[i]);
+			dm+=distance[i];
+			if (ge.equals(t))
+			{
+				res=dm-dn;
+				break;
+			}
+			if (ge.equals(gf))
+			{
+				res=dn-dm;
+				break;
+			}
+
+		}
+		if (steps>4*TRAP || dm-dn>=MAXPIN) {res=0; }    // Trap Failed  - probable invalid token
+		return res;
+	}
+
+/* Functions to support M-Pin Full */
+
+	public static int PRECOMPUTE(byte[] TOKEN,byte[] CID,byte[] G1,byte[] G2)
+	{
+		ECP P,T;
+		FP12 g;
+
+		T=ECP.fromBytes(TOKEN);
+		if (T.is_infinity()) return INVALID_POINT; 
+
+		P=ECP.mapit(CID);
+
+		ECP2 Q=ECP2.generator();
+
+		g=PAIR.ate(Q,T);
+		g=PAIR.fexp(g);
+		g.toBytes(G1);
+
+		g=PAIR.ate(Q,P);
+		g=PAIR.fexp(g);
+		g.toBytes(G2);
+
+		return 0;
+	}
+
+
+
+/* calculate common key on client side */
+/* wCID = w.(A+AT) */
+	public static int CLIENT_KEY(int sha,byte[] G1,byte[] G2,int pin,byte[] R,byte[] X,byte[] H,byte[] wCID,byte[] CK)
+	{
+		byte[] t;
+
+		FP12 g1=FP12.fromBytes(G1);
+		FP12 g2=FP12.fromBytes(G2);
+		BIG z=BIG.fromBytes(R);
+		BIG x=BIG.fromBytes(X);
+		BIG h=BIG.fromBytes(H);
+
+		ECP W=ECP.fromBytes(wCID);
+		if (W.is_infinity()) return INVALID_POINT; 
+
+		W=PAIR.G1mul(W,x);
+
+//		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG r=new BIG(ROM.CURVE_Order);
+//		BIG q=new BIG(ROM.Modulus);
+
+		z.add(h);	//new
+		z.mod(r);
+
+		g2.pinpow(pin,PBLEN);
+		g1.mul(g2);
+
+		FP4 c=g1.compow(z,r);
+/*
+		BIG m=new BIG(q);
+		m.mod(r);
+
+		BIG a=new BIG(z);
+		a.mod(m);
+
+		BIG b=new BIG(z);
+		b.div(m);
+
+
+		FP4 c=g1.trace();
+		g2.copy(g1);
+		g2.frob(f);
+		FP4 cp=g2.trace();
+		g1.conj();
+		g2.mul(g1);
+		FP4 cpm1=g2.trace();
+		g2.mul(g1);
+		FP4 cpm2=g2.trace();
+
+		c=c.xtr_pow2(cp,cpm1,cpm2,a,b);
+*/
+		t=mpin_hash(sha,c,W);
+
+		for (int i=0;i<ECP.AESKEY;i++) CK[i]=t[i];
+
+		return 0;
+	}
+
+/* calculate common key on server side */
+/* Z=r.A - no time permits involved */
+
+	public static int SERVER_KEY(int sha,byte[] Z,byte[] SST,byte[] W,byte[] H,byte[] HID,byte[] xID,byte[] xCID,byte[] SK)
+	{
+		byte[] t;
+
+		ECP2 sQ=ECP2.fromBytes(SST);
+		if (sQ.is_infinity()) return INVALID_POINT; 
+		ECP R=ECP.fromBytes(Z);
+		if (R.is_infinity()) return INVALID_POINT; 
+		ECP A=ECP.fromBytes(HID);
+		if (A.is_infinity()) return INVALID_POINT; 
+
+		ECP U;
+		if (xCID!=null)
+			U=ECP.fromBytes(xCID);
+		else
+			U=ECP.fromBytes(xID);
+		if (U.is_infinity()) return INVALID_POINT; 
+
+		BIG w=BIG.fromBytes(W);
+		BIG h=BIG.fromBytes(H);
+		A=PAIR.G1mul(A,h);	// new
+		R.add(A); //R.affine();
+
+		U=PAIR.G1mul(U,w);
+		FP12 g=PAIR.ate(sQ,R);
+		g=PAIR.fexp(g);
+
+		FP4 c=g.trace();
+
+		t=mpin_hash(sha,c,U);
+
+		for (int i=0;i<ECP.AESKEY;i++) SK[i]=t[i];
+
+		return 0;
+	}
+
+/* Generate Y = H(epoch, xCID/xID) */
+	public static void GET_Y(int sha,int TimeValue,byte[] xCID,byte[] Y)
+	{
+		byte[] h = hashit(sha,TimeValue,xCID,EFS);
+		BIG y = BIG.fromBytes(h);
+		BIG q=new BIG(ROM.CURVE_Order);
+		y.mod(q);
+		//if (ROM.AES_S>0)
+		//{
+		//	y.mod2m(2*ROM.AES_S);
+		//}
+		y.toBytes(Y);
+	}
+        
+/* One pass MPIN Client */
+	public static int CLIENT(int sha,int date,byte[] CLIENT_ID,RAND RNG,byte[] X,int pin,byte[] TOKEN,byte[] SEC,byte[] xID,byte[] xCID,byte[] PERMIT, int TimeValue, byte[] Y)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		rtn = CLIENT_1(sha,date,CLIENT_ID,RNG,X,pin,TOKEN,SEC,xID,xCID,PERMIT);
+		if (rtn != 0)
+			return rtn;
+        
+		GET_Y(sha,TimeValue,pID,Y);
+        
+		rtn = CLIENT_2(X,Y,SEC);
+		if (rtn != 0)
+		return rtn;
+        
+		return 0;
+	}
+        
+/* One pass MPIN Server */
+	public static int SERVER(int sha,int date,byte[] HID,byte[] HTID,byte[] Y,byte[] SST,byte[] xID,byte[] xCID,byte[] SEC,byte[] E,byte[] F,byte[] CID, int TimeValue)
+	{
+		int rtn=0;
+        
+		byte[] pID;
+		if (date == 0)
+			pID = xID;
+		else
+			pID = xCID;
+          
+		SERVER_1(sha,date,CID,HID,HTID);
+        
+		GET_Y(sha,TimeValue,pID,Y);
+          
+		rtn = SERVER_2(date,HID,HTID,Y,SST,xID,xCID,SEC,E,F);
+		if (rtn != 0)
+			return rtn;
+        
+		return 0;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/PAIR.java b/src/main/java/org/apache/milagro/amcl/FP512BN/PAIR.java
new file mode 100644
index 0000000..fecf81d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/PAIR.java
@@ -0,0 +1,817 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BN Curve Pairing functions */
+
+package org.apache.milagro.amcl.FP512BN;
+
+public final class PAIR {
+
+	public static final boolean USE_GLV =true;
+	public static final boolean USE_GS_G2 =true;
+	public static final boolean USE_GS_GT =true;	
+	public static final boolean GT_STRONG=false;
+
+
+/* Line function */
+	public static FP12 line(ECP2 A,ECP2 B,FP Qx,FP Qy)
+	{
+//System.out.println("Into line");
+		FP4 a,b,c;                            // Edits here
+//		c=new FP4(0);
+		if (A==B)
+		{ // Doubling
+			FP2 XX=new FP2(A.getx());  //X
+			FP2 YY=new FP2(A.gety());  //Y
+			FP2 ZZ=new FP2(A.getz());  //Z
+			FP2 YZ=new FP2(YY);        //Y 
+			YZ.mul(ZZ);                //YZ
+			XX.sqr();	               //X^2
+			YY.sqr();	               //Y^2
+			ZZ.sqr();			       //Z^2
+			
+			YZ.imul(4);
+			YZ.neg(); YZ.norm();       //-2YZ
+			YZ.pmul(Qy);               //-2YZ.Ys
+
+			XX.imul(6);                //3X^2
+			XX.pmul(Qx);               //3X^2.Xs
+
+			int sb=3*ROM.CURVE_B_I;
+			ZZ.imul(sb); 	
+			
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				ZZ.div_ip2();
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				ZZ.mul_ip();
+				ZZ.add(ZZ);
+				YZ.mul_ip();
+				YZ.norm();
+			}
+			
+			ZZ.norm(); // 3b.Z^2 
+
+			YY.add(YY);
+			ZZ.sub(YY); ZZ.norm();     // 3b.Z^2-Y^2
+
+			a=new FP4(YZ,ZZ);          // -2YZ.Ys | 3b.Z^2-Y^2 | 3X^2.Xs 
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{			
+				b=new FP4(XX);             // L(0,1) | L(0,0) | L(1,0)
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(XX); c.times_i();
+			}
+			A.dbl();
+		}
+		else
+		{ // Addition - assume B is affine
+
+			FP2 X1=new FP2(A.getx());    // X1
+			FP2 Y1=new FP2(A.gety());    // Y1
+			FP2 T1=new FP2(A.getz());    // Z1
+			FP2 T2=new FP2(A.getz());    // Z1
+			
+			T1.mul(B.gety());    // T1=Z1.Y2 
+			T2.mul(B.getx());    // T2=Z1.X2
+
+			X1.sub(T2); X1.norm();  // X1=X1-Z1.X2
+			Y1.sub(T1); Y1.norm();  // Y1=Y1-Z1.Y2
+
+			T1.copy(X1);            // T1=X1-Z1.X2
+			X1.pmul(Qy);            // X1=(X1-Z1.X2).Ys
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				X1.mul_ip();
+				X1.norm();
+			}
+
+			T1.mul(B.gety());       // T1=(X1-Z1.X2).Y2
+
+			T2.copy(Y1);            // T2=Y1-Z1.Y2
+			T2.mul(B.getx());       // T2=(Y1-Z1.Y2).X2
+			T2.sub(T1); T2.norm();          // T2=(Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2
+			Y1.pmul(Qx);  Y1.neg(); Y1.norm(); // Y1=-(Y1-Z1.Y2).Xs
+
+			a=new FP4(X1,T2);       // (X1-Z1.X2).Ys  |  (Y1-Z1.Y2).X2 - (X1-Z1.X2).Y2  | - (Y1-Z1.Y2).Xs
+			if (ECP.SEXTIC_TWIST==ECP.D_TYPE)
+			{
+				b=new FP4(Y1);
+				c=new FP4(0);
+			}
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				b=new FP4(0);
+				c=new FP4(Y1); c.times_i();
+			}
+			A.add(B);
+		}
+//System.out.println("Out of line");
+		return new FP12(a,b,c);
+	}
+
+/* Optimal R-ate pairing */
+	public static FP12 ate(ECP2 P1,ECP Q1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+// P is needed in affine form for line function, Q for (Qx,Qy) extraction
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+		
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+
+		ECP2 A=new ECP2();
+		FP12 r=new FP12(1);
+		A.copy(P);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg();
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				//r.conj();
+				A.neg();
+			}
+			K.copy(P);
+			K.frob(f);
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		} 
+		return r;
+	}
+
+/* Optimal R-ate double pairing e(P,Q).e(R,S) */
+	public static FP12 ate2(ECP2 P1,ECP Q1,ECP2 R1,ECP S1)
+	{
+		FP2 f;
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		BIG n=new BIG(x);
+		ECP2 K=new ECP2();
+		FP12 lv;
+		int bt;
+
+		ECP2 P=new ECP2(P1);
+		ECP Q=new ECP(Q1);
+
+		P.affine();
+		Q.affine();
+
+		ECP2 R=new ECP2(R1);
+		ECP S=new ECP(S1);
+
+		R.affine();
+		S.affine();
+
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+			n.pmul(6); 
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				n.inc(2);
+			} else {
+				n.dec(2);
+			}
+		}
+		else
+			n.copy(x);
+		n.norm();
+
+		BIG n3=new BIG(n);
+		n3.pmul(3);
+		n3.norm();
+
+		FP Qx=new FP(Q.getx());
+		FP Qy=new FP(Q.gety());
+		FP Sx=new FP(S.getx());
+		FP Sy=new FP(S.gety());
+
+		ECP2 A=new ECP2();
+		ECP2 B=new ECP2();
+		FP12 r=new FP12(1);
+
+		A.copy(P);
+		B.copy(R);
+
+		ECP2 MP=new ECP2();
+		MP.copy(P); MP.neg();
+		ECP2 MR=new ECP2();
+		MR.copy(R); MR.neg();
+
+
+		int nb=n3.nbits();
+
+		for (int i=nb-2;i>=1;i--)
+		{
+			r.sqr();
+			lv=line(A,A,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			lv=line(B,B,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+
+			bt=n3.bit(i)-n.bit(i); // bt=n.bit(i);
+			if (bt==1)
+			{
+				lv=line(A,P,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				lv=line(B,R,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+			}
+			if (bt==-1)
+			{
+				//P.neg(); 
+				lv=line(A,MP,Qx,Qy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//P.neg(); 
+				//R.neg();
+				lv=line(B,MR,Sx,Sy);
+				r.smul(lv,ECP.SEXTIC_TWIST);
+				//R.neg();
+			}
+		}
+
+		if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+		{
+			r.conj();
+		}
+
+/* R-ate fixup required for BN curves */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+			//	r.conj();
+				A.neg();
+				B.neg();
+			}
+
+			K.copy(P);
+			K.frob(f);
+
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(A,K,Qx,Qy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.copy(R);
+			K.frob(f);
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+			K.frob(f);
+			K.neg();
+			lv=line(B,K,Sx,Sy);
+			r.smul(lv,ECP.SEXTIC_TWIST);
+		}
+		return r;
+	}
+
+/* final exponentiation - keep separate for multi-pairings and to avoid thrashing stack */
+	public static FP12 fexp(FP12 m)
+	{
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+		BIG x=new BIG(ROM.CURVE_Bnx);
+		FP12 r=new FP12(m);
+
+/* Easy part of final exp */
+		FP12 lv=new FP12(r);
+		lv.inverse();
+		r.conj();
+
+		r.mul(lv);
+		lv.copy(r);
+		r.frob(f);
+		r.frob(f);
+		r.mul(lv);
+/* Hard part of final exp */
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			FP12 x0,x1,x2,x3,x4,x5;			
+			lv.copy(r);
+			lv.frob(f);
+			x0=new FP12(lv);
+			x0.frob(f);
+			lv.mul(r);
+			x0.mul(lv);
+			x0.frob(f);
+			x1=new FP12(r);
+			x1.conj();
+			x4=r.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x4.conj();
+			}
+
+			x3=new FP12(x4);
+			x3.frob(f);
+
+			x2=x4.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				x2.conj();
+			}
+			x5=new FP12(x2); x5.conj();
+			lv=x2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.POSITIVEX)
+			{
+				lv.conj();
+			}
+			x2.frob(f);
+			r.copy(x2); r.conj();
+
+			x4.mul(r);
+			x2.frob(f);
+
+			r.copy(lv);
+			r.frob(f);
+			lv.mul(r);
+
+			lv.usqr();
+			lv.mul(x4);
+			lv.mul(x5);
+			r.copy(x3);
+			r.mul(x5);
+			r.mul(lv);
+			lv.mul(x2);
+			r.usqr();
+			r.mul(lv);
+			r.usqr();
+			lv.copy(r);
+			lv.mul(x1);
+			r.mul(x0);
+			lv.usqr();
+			r.mul(lv);
+			r.reduce();
+		}
+		else
+		{
+
+			FP12 y0,y1,y2,y3;
+// Ghamman & Fouotsa Method
+			y0=new FP12(r); y0.usqr();
+			y1=y0.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y1.conj();
+			}
+			x.fshr(1); y2=y1.pow(x); 
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}			
+			
+			x.fshl(1);
+			y3=new FP12(r); y3.conj();
+			y1.mul(y3);
+
+			y1.conj();
+			y1.mul(y2);
+
+			y2=y1.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y3=y2.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y3.conj();
+			}
+			y1.conj();
+			y3.mul(y1);
+
+			y1.conj();
+			y1.frob(f); y1.frob(f); y1.frob(f);
+			y2.frob(f); y2.frob(f);
+			y1.mul(y2);
+
+			y2=y3.pow(x);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				y2.conj();
+			}
+			y2.mul(y0);
+			y2.mul(r);
+
+			y1.mul(y2);
+			y2.copy(y3); y2.frob(f);
+			y1.mul(y2);
+			r.copy(y1);
+			r.reduce();
+		}
+		
+		return r;
+	}
+
+/* GLV method */
+	public static BIG[] glv(BIG e)
+	{
+		BIG[] u=new BIG[2];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+
+			BIG[] v=new BIG[2];
+			for (i=0;i<2;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_W[i]));  // why not just t=new BIG(ROM.CURVE_W[i]); 
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<2;i++)
+				for (j=0;j<2;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_SB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{ // -(x^2).P = (Beta.x,y)
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG x2=BIG.smul(x,x);
+			u[0]=new BIG(e);
+			u[0].mod(x2);
+			u[1]=new BIG(e);
+			u[1].div(x2);
+			u[1].rsub(q);
+		}
+		return u;
+	}
+
+/* Galbraith & Scott Method */
+	public static BIG[] gs(BIG e)
+	{
+		BIG[] u=new BIG[4];
+		if (ECP.CURVE_PAIRING_TYPE==ECP.BN)
+		{
+			int i,j;
+			BIG t=new BIG(0);
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] v=new BIG[4];
+			for (i=0;i<4;i++)
+			{
+				t.copy(new BIG(ROM.CURVE_WB[i]));
+				DBIG d=BIG.mul(t,e);
+				v[i]=new BIG(d.div(q));
+				u[i]=new BIG(0);
+			}
+			u[0].copy(e);
+			for (i=0;i<4;i++)
+				for (j=0;j<4;j++)
+				{
+					t.copy(new BIG(ROM.CURVE_BB[j][i]));
+					t.copy(BIG.modmul(v[j],t,q));
+					u[i].add(q);
+					u[i].sub(t);
+					u[i].mod(q);
+				}
+		}
+		else
+		{
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			BIG w=new BIG(e);
+			for (int i=0;i<3;i++)
+			{
+				u[i]=new BIG(w);
+				u[i].mod(x);
+				w.div(x);
+			}
+			u[3]=new BIG(w);
+			if (ECP.SIGN_OF_X==ECP.NEGATIVEX)
+			{
+				u[1].copy(BIG.modneg(u[1],q));
+				u[3].copy(BIG.modneg(u[3],q));
+			}
+		}
+		return u;
+	}	
+
+/* Multiply P by e in group G1 */
+	public static ECP G1mul(ECP P,BIG e)
+	{
+		ECP R;
+		if (USE_GLV)
+		{
+			//P.affine();
+			R=new ECP();
+			R.copy(P);
+			int i,np,nn;
+			ECP Q=new ECP();
+			Q.copy(P); Q.affine();
+			BIG q=new BIG(ROM.CURVE_Order);
+			FP cru=new FP(new BIG(ROM.CURVE_Cru));
+			BIG t=new BIG(0);
+			BIG[] u=glv(e);
+			Q.getx().mul(cru);
+
+			np=u[0].nbits();
+			t.copy(BIG.modneg(u[0],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[0].copy(t);
+				R.neg();
+			}
+
+			np=u[1].nbits();
+			t.copy(BIG.modneg(u[1],q));
+			nn=t.nbits();
+			if (nn<np)
+			{
+				u[1].copy(t);
+				Q.neg();
+			}
+			u[0].norm();
+			u[1].norm();
+			R=R.mul2(u[0],Q,u[1]);
+			
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* Multiply P by e in group G2 */
+	public static ECP2 G2mul(ECP2 P,BIG e)
+	{
+		ECP2 R;
+		if (USE_GS_G2)
+		{
+			ECP2[] Q=new ECP2[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+			if (ECP.SEXTIC_TWIST==ECP.M_TYPE)
+			{
+				f.inverse();
+				f.norm();
+			}
+
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG[] u=gs(e);
+
+			BIG t=new BIG(0);
+			int i,np,nn;
+			//P.affine();
+
+			Q[0]=new ECP2(); Q[0].copy(P);
+			for (i=1;i<4;i++)
+			{
+				Q[i]=new ECP2(); Q[i].copy(Q[i-1]);
+				Q[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					Q[i].neg();
+				}
+				u[i].norm();	
+				//Q[i].affine();
+			}
+
+			R=ECP2.mul4(Q,u);
+		}
+		else
+		{
+			R=P.mul(e);
+		}
+		return R;
+	}
+
+/* f=f^e */
+/* Note that this method requires a lot of RAM! Better to use compressed XTR method, see FP4.java */
+	public static FP12 GTpow(FP12 d,BIG e)
+	{
+		FP12 r;
+		if (USE_GS_GT)
+		{
+			FP12[] g=new FP12[4];
+			FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+			BIG q=new BIG(ROM.CURVE_Order);
+			BIG t=new BIG(0);
+			int i,np,nn;
+			BIG[] u=gs(e);
+
+			g[0]=new FP12(d);
+			for (i=1;i<4;i++)
+			{
+				g[i]=new FP12(0); g[i].copy(g[i-1]);
+				g[i].frob(f);
+			}
+			for (i=0;i<4;i++)
+			{
+				np=u[i].nbits();
+				t.copy(BIG.modneg(u[i],q));
+				nn=t.nbits();
+				if (nn<np)
+				{
+					u[i].copy(t);
+					g[i].conj();
+				}
+				u[i].norm();
+			}
+			r=FP12.pow4(g,u);
+		}
+		else
+		{
+			r=d.pow(e);
+		}
+		return r;
+	}
+
+/* test group membership - no longer needed */
+/* with GT-Strong curve, now only check that m!=1, conj(m)*m==1, and m.m^{p^4}=m^{p^2} */
+/*
+	public static boolean GTmember(FP12 m)
+	{
+		if (m.isunity()) return false;
+		FP12 r=new FP12(m);
+		r.conj();
+		r.mul(m);
+		if (!r.isunity()) return false;
+
+		FP2 f=new FP2(new BIG(ROM.Fra),new BIG(ROM.Frb));
+
+		r.copy(m); r.frob(f); r.frob(f);
+		FP12 w=new FP12(r); w.frob(f); w.frob(f);
+		w.mul(m);
+		if (!ROM.GT_STRONG)
+		{
+			if (!w.equals(r)) return false;
+			BIG x=new BIG(ROM.CURVE_Bnx);
+			r.copy(m); w=r.pow(x); w=w.pow(x);
+			r.copy(w); r.sqr(); r.mul(w); r.sqr();
+			w.copy(m); w.frob(f);
+		}
+		return w.equals(r);
+	}
+*/
+/*
+	public static void main(String[] args) {
+		ECP Q=new ECP(new BIG(ROM.CURVE_Gx),new BIG(ROM.CURVE_Gy));
+		ECP2 P=new ECP2(new FP2(new BIG(ROM.CURVE_Pxa),new BIG(ROM.CURVE_Pxb)),new FP2(new BIG(ROM.CURVE_Pya),new BIG(ROM.CURVE_Pyb)));
+
+		BIG r=new BIG(ROM.CURVE_Order);
+		BIG xa=new BIG(ROM.CURVE_Pxa);
+
+		System.out.println("P= "+P.toString());
+		System.out.println("Q= "+Q.toString());
+
+		BIG m=new BIG(17);
+
+		FP12 e=ate(P,Q);
+		System.out.println("\ne= "+e.toString());
+
+		e=fexp(e);
+
+		for (int i=1;i<1000;i++)
+		{
+			e=ate(P,Q);
+			e=fexp(e);
+		}
+	//	e=GTpow(e,m);
+
+		System.out.println("\ne= "+e.toString());
+
+		BIG [] GLV=glv(r);
+
+		System.out.println("GLV[0]= "+GLV[0].toString());
+		System.out.println("GLV[0]= "+GLV[1].toString());
+
+		ECP G=new ECP(); G.copy(Q);
+		ECP2 R=new ECP2(); R.copy(P);
+
+
+		e=ate(R,Q);
+		e=fexp(e);
+
+		e=GTpow(e,xa);
+		System.out.println("\ne= "+e.toString()); 
+
+
+		R=G2mul(R,xa);
+		e=ate(R,G);
+		e=fexp(e);
+
+		System.out.println("\ne= "+e.toString());
+
+		G=G1mul(G,xa);
+		e=ate(P,G);
+		e=fexp(e);
+		System.out.println("\ne= "+e.toString()); 
+	} */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/FP512BN/ROM.java b/src/main/java/org/apache/milagro/amcl/FP512BN/ROM.java
new file mode 100644
index 0000000..0d2db45
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/FP512BN/ROM.java
@@ -0,0 +1,56 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.FP512BN;
+
+public class ROM
+{
+
+// Base Bits= 60
+public static final long[] Modulus= {0x4EB280922ADEF33L,0x6A55CE5F4C6467BL,0xC65DEAB236FE191L,0xCF1EACBE98B8E48L,0x3C111B0EF455146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+public static final long[] R2modp= {0x1FA6DCEF99812E9L,0xAB3452895A0B74EL,0xC53EA988C079E1EL,0x1E90E033BA630B9L,0xF1EA41C0714D8B0L,0xE72785387509E28L,0xD86794F834DAB00L,0x9757C2ACCD342A1L,0x44ECB079L};
+public static final long MConst= 0x692A189FCCC5C05L;
+
+public static final int CURVE_A= 0;
+public static final int CURVE_B_I= 3;
+public static final int CURVE_Cof_I= 1;
+public static final long[] CURVE_B= {0x3L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0x6A64A5F519A09EDL,0x10313E04F9A2B40L,0xC65DEAB2679A34AL,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+public static final long[] CURVE_Gx= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Gy= {0x2L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+
+public static final long[] Fra= {0x49617B1F4B73AB2L,0x71514F6202AED1FL,0xF6080D3BD8681E1L,0xF8AA9E852CBBB59L,0xC8CF2E2068398E9L,0x8A5296F791AB26BL,0x196A8C7C68B4EA1L,0xCF5BBF9095A1B79L,0x1EF71AA9L};
+public static final long[] Frb= {0x5510572DF6B481L,0xF9047EFD49B595CL,0xD055DD765E95FAFL,0xD6740E396BFD2EEL,0x7341ECEE8C1B85CL,0x1786345B7615952L,0xE695124B876776AL,0x30A4406F6A5E486L,0xE108E556L};
+public static final long[] CURVE_Bnx= {0xB306BB5E1BD80FL,0x82F5C030B0F7F01L,0x68L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Cru= {0xB0716209C79298AL,0xCEE6799B8B17C14L,0x78966BE526092AEL,0x20089C27507ACD8L,0xF8EF7611FA3074BL,0x6146B86B378EA2CL,0xFFFF9EC7DC83D2AL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+public static final long[] CURVE_Pxa= {0xF07A96E0DB646B5L,0x18F87319072FFE8L,0x7BE21BCBBC78F22L,0x537863514DC6DC5L,0xDA57CC78CD0B024L,0xD29B358F0DB9B57L,0x7412F3CEA1E4BBBL,0xE138648958801BAL,0x3B165339L};
+public static final long[] CURVE_Pxb= {0xDB5CBEFDA8AE0E9L,0xCA411CD88911B3L,0xD6E1383D5ADCE4L,0x227285526E0D5E5L,0xB02566B94D9781EL,0x56DC6C6EF2476A8L,0x680ABE8B4825EA6L,0xF85067E6C89B4C4L,0x481C13CBL};
+public static final long[] CURVE_Pya= {0x2480312ADDE67A1L,0xDA17AD615EFB85EL,0x312542808B7BC5CL,0x18BDEC153E8EDD2L,0xE5C158699D4B6CDL,0xB1DF660AFCDD03EL,0xB0CBA374F277085L,0xC827C7B8292EF5AL,0x6F01EC84L};
+public static final long[] CURVE_Pyb= {0x58B7186C84F8E8BL,0xF05C2224BF76168L,0x10AD7EE279C08DFL,0x7FC3E2E50714A43L,0x3D04961941DA289L,0x38C118867B0C9B6L,0xC315F75D91F0214L,0x8B04E7831AC3640L,0x51A3BCECL};
+public static final long[][] CURVE_W= {{0x110F89749834583L,0x65FB911D16A173FL,0xFFFFFFFFCF63FE9L,0xFFFFFFFFFFFFFFFL,0xFFFFL,0x0L,0x0L,0x0L,0x0L},{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_SB= {{{0xFAAEB208D4B9564L,0x601010BBB4B193CL,0xFFFFFFFFCF63F18L,0xFFFFFFFFFFFFFFFL,0xFFFFL,0x0L,0x0L,0x0L,0x0L},{0x5403CE8956259CEL,0xA45BDA397B2D3EL,0xC65DEAB2679A279L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL}},{{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x110F89749834583L,0x65FB911D16A173FL,0xFFFFFFFFCF63FE9L,0xFFFFFFFFFFFFFFFL,0xFFFFL,0x0L,0x0L,0x0L,0x0L}}};
+public static final long[][] CURVE_WB= {{0x6DAB36AB55A29F0L,0xFC42C60583D30C1L,0x5555555545215FBL,0x555555555555555L,0x5555L,0x0L,0x0L,0x0L,0x0L},{0xEEB012BA2355D4BL,0xF20FC1FD7F84F17L,0x892FA9DE2BB5E5CL,0x74B96064DAD40F5L,0xD76BC3535163152L,0x806161EFE021660L,0xD105EBL,0x0L,0x0L},{0x7CF03F380289AADL,0xBA82C117183E70CL,0xC497D4EF15DAF62L,0x3A5CB0326D6A07AL,0x6BB5E1A9A8B18A9L,0xC030B0F7F010B30L,0x6882F5L,0x0L,0x0L},{0x574A5F3F92279D1L,0xF65745A421E32BFL,0x55555555452152AL,0x555555555555555L,0x5555L,0x0L,0x0L,0x0L,0x0L}};
+public static final long[][][] CURVE_BB= {{{0xB306BB5E1BD810L,0x82F5C030B0F7F01L,0x68L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0xB306BB5E1BD80FL,0x82F5C030B0F7F01L,0x68L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0xB306BB5E1BD80FL,0x82F5C030B0F7F01L,0x68L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x5403CE8956259CFL,0xA45BDA397B2D3EL,0xC65DEAB2679A279L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL}},{{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x5F343A3F37E31DEL,0x8D3B7DD448AAC3FL,0xC65DEAB2679A2E1L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL},{0x5F343A3F37E31DDL,0x8D3B7DD448AAC3FL,0xC65DEAB2679A2E1L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL},{0x5F343A3F37E31DEL,0x8D3B7DD448AAC3FL,0xC65DEAB2679A2E1L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL}},{{0x1660D76BC37B01EL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x1660D76BC37B01FL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L}},{{0x5F343A3F37E31DFL,0x8D3B7DD448AAC3FL,0xC65DEAB2679A2E1L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL},{0x3DA2F71D92AA9AFL,0x45A3D4235C2F3CL,0xC65DEAB2679A1A8L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL},{0x1660D76BC37B01DL,0x5EB806161EFE02L,0xD1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L},{0x5F343A3F37E31DFL,0x8D3B7DD448AAC3FL,0xC65DEAB2679A2E1L,0xCF1EACBE98B8E48L,0x3C111B0EF445146L,0xA1D8CB5307C0BBEL,0xFFFF9EC7F01C60BL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL}}};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/GCM.java b/src/main/java/org/apache/milagro/amcl/GCM.java
new file mode 100644
index 0000000..3cafa82
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GCM.java
@@ -0,0 +1,376 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+
+/*
+ * Implementation of the AES-GCM Encryption/Authentication
+ *
+ * Some restrictions.. 
+ * 1. Only for use with AES
+ * 2. Returned tag is always 128-bits. Truncate at your own risk.
+ * 3. The order of function calls must follow some rules
+ *
+ * Typical sequence of calls..
+ * 1. call GCM_init
+ * 2. call GCM_add_header any number of times, as long as length of header is multiple of 16 bytes (block size)
+ * 3. call GCM_add_header one last time with any length of header
+ * 4. call GCM_add_cipher any number of times, as long as length of cipher/plaintext is multiple of 16 bytes
+ * 5. call GCM_add_cipher one last time with any length of cipher/plaintext
+ * 6. call GCM_finish to extract the tag.
+ *
+ * See http://www.mindspring.com/~dmcgrew/gcm-nist-6.pdf
+ */
+
+package org.apache.milagro.amcl;
+
+public class GCM {
+	public static final int NB=4;
+	public static final int GCM_ACCEPTING_HEADER=0;
+	public static final int GCM_ACCEPTING_CIPHER=1;
+	public static final int GCM_NOT_ACCEPTING_MORE=2;
+	public static final int GCM_FINISHED=3;
+	public static final int GCM_ENCRYPTING=0;
+	public static final int GCM_DECRYPTING=1;
+
+	private int[][] table=new int[128][4]; /* 2k bytes */
+	private byte[] stateX=new byte[16];
+	private byte[]Y_0=new byte[16];
+	private int counter;
+	private int[] lenA=new int[2];
+	private int[] lenC=new int[2];
+	private int status;
+	private AES a=new AES();
+
+	private static int pack(byte[] b)
+	{ /* pack bytes into a 32-bit Word */
+		return ((((int)b[0])&0xff)<<24)|(((int)b[1]&0xff)<<16)|(((int)b[2]&0xff)<<8)|((int)b[3]&0xff);
+	}
+
+	private static byte[] unpack(int a)
+	{ /* unpack bytes from a word */
+		byte [] b=new byte[4];
+		b[3]=(byte)(a);
+		b[2]=(byte)(a>>>8);
+		b[1]=(byte)(a>>>16);
+		b[0]=(byte)(a>>>24);
+		return b;
+	}
+
+	private void precompute(byte[] H)
+	{
+		int i,j,c;
+		byte[] b=new byte[4];
+
+		for (i=j=0;i<NB;i++,j+=4) 
+		{
+			b[0]=H[j]; b[1]=H[j+1]; b[2]=H[j+2]; b[3]=H[j+3];
+			table[0][i]=pack(b);
+		}
+		for (i=1;i<128;i++)
+		{
+			c=0;
+			for (j=0;j<NB;j++) {table[i][j]=c|(table[i-1][j])>>>1; c=table[i-1][j]<<31;}
+			if (c!=0) table[i][0]^=0xE1000000; /* irreducible polynomial */
+		}
+	}
+
+	private void gf2mul()
+	{ /* gf2m mul - Z=H*X mod 2^128 */
+		int i,j,m,k;
+		int[] P=new int[4];
+		int c;
+		byte[] b;//=new byte[4];
+
+		P[0]=P[1]=P[2]=P[3]=0;
+		j=8; m=0;
+		for (i=0;i<128;i++)
+		{
+			c=(stateX[m]>>>(--j))&1; c=~c+1;
+			for (k=0;k<NB;k++) P[k]^=(table[i][k]&c);
+			if (j==0)
+			{
+				j=8; m++;
+				if (m==16) break;
+			}
+		}
+		for (i=j=0;i<NB;i++,j+=4) 
+		{
+			b=unpack(P[i]);
+			stateX[j]=b[0]; stateX[j+1]=b[1]; stateX[j+2]=b[2]; stateX[j+3]=b[3];
+		}
+	}
+
+	private void wrap()
+	{ /* Finish off GHASH */
+		int i,j;
+		int[] F=new int[4];
+		byte[] L=new byte[16];
+		byte[] b;//=new byte[4];
+
+/* convert lengths from bytes to bits */
+		F[0]=(lenA[0]<<3)|(lenA[1]&0xE0000000)>>>29;
+		F[1]=lenA[1]<<3;
+		F[2]=(lenC[0]<<3)|(lenC[1]&0xE0000000)>>>29;
+		F[3]=lenC[1]<<3;
+		for (i=j=0;i<NB;i++,j+=4)
+		{
+			b=unpack(F[i]);
+			L[j]=b[0]; L[j+1]=b[1]; L[j+2]=b[2]; L[j+3]=b[3];
+		}
+		for (i=0;i<16;i++) stateX[i]^=L[i];
+		gf2mul();
+	}
+
+/* Initialize GCM mode */
+	public void init(int nk,byte[] key,int niv,byte[] iv)
+	{ /* iv size niv is usually 12 bytes (96 bits). AES key size nk can be 16,24 or 32 bytes */
+		int i;
+		byte[] H=new byte[16];
+		byte[] b;//=new byte[4];
+
+		for (i=0;i<16;i++) {H[i]=0; stateX[i]=0;}
+
+		a.init(AES.ECB,nk,key,iv);
+		a.ecb_encrypt(H);     /* E(K,0) */
+		precompute(H);
+	
+		lenA[0]=lenC[0]=lenA[1]=lenC[1]=0;
+		if (niv==12)
+		{
+			for (i=0;i<12;i++) a.f[i]=iv[i];
+			b=unpack((int)1);
+			a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3];  /* initialise IV */
+			for (i=0;i<16;i++) Y_0[i]=a.f[i];
+		}
+		else
+		{
+			status=GCM_ACCEPTING_CIPHER;
+			ghash(iv,niv); /* GHASH(H,0,IV) */
+			wrap();
+			for (i=0;i<16;i++) {a.f[i]=stateX[i];Y_0[i]=a.f[i];stateX[i]=0;}
+			lenA[0]=lenC[0]=lenA[1]=lenC[1]=0;
+		}
+		status=GCM_ACCEPTING_HEADER;
+	}
+
+/* Add Header data - included but not encrypted */
+	public boolean add_header(byte[] header,int len)
+	{ /* Add some header. Won't be encrypted, but will be authenticated. len is length of header */
+		int i,j=0;
+		if (status!=GCM_ACCEPTING_HEADER) return false;
+
+		while (j<len)
+		{
+			for (i=0;i<16 && j<len;i++)
+			{
+				stateX[i]^=header[j++];
+				lenA[1]++; if (lenA[1]==0) lenA[0]++;
+			}
+			gf2mul();
+		}
+		if (len%16!=0) status=GCM_ACCEPTING_CIPHER;
+		return true;
+	}
+
+	private boolean ghash(byte[] plain,int len)
+	{
+		int i,j=0;
+		int counter;
+	//	byte[] B=new byte[16];
+	//	byte[] b=new byte[4];
+
+		if (status==GCM_ACCEPTING_HEADER) status=GCM_ACCEPTING_CIPHER;
+		if (status!=GCM_ACCEPTING_CIPHER) return false;
+		
+		while (j<len)
+		{
+			for (i=0;i<16 && j<len;i++)
+			{
+				stateX[i]^=plain[j++];
+				lenC[1]++; if (lenC[1]==0) lenC[0]++;
+			}
+			gf2mul();
+		}
+		if (len%16!=0) status=GCM_NOT_ACCEPTING_MORE;
+		return true;
+	}
+
+/* Add Plaintext - included and encrypted */
+	public byte[] add_plain(byte[] plain,int len)
+	{
+		int i,j=0;
+		int counter;
+		byte[] B=new byte[16];
+		byte[] b=new byte[4];
+		byte[] cipher=new byte[len];
+
+		if (status==GCM_ACCEPTING_HEADER) status=GCM_ACCEPTING_CIPHER;
+		if (status!=GCM_ACCEPTING_CIPHER) return new byte[0];
+		
+		while (j<len)
+		{
+
+			b[0]=a.f[12]; b[1]=a.f[13]; b[2]=a.f[14]; b[3]=a.f[15];
+			counter=pack(b);
+			counter++;
+			b=unpack(counter);
+			a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3]; /* increment counter */
+			for (i=0;i<16;i++) B[i]=a.f[i];
+			a.ecb_encrypt(B);        /* encrypt it  */
+		
+			for (i=0;i<16 && j<len;i++)
+			{
+				cipher[j]=(byte)(plain[j]^B[i]);
+				stateX[i]^=cipher[j++];
+				lenC[1]++; if (lenC[1]==0) lenC[0]++;
+			}
+			gf2mul();
+		}
+		if (len%16!=0) status=GCM_NOT_ACCEPTING_MORE;
+		return cipher;
+	}
+
+/* Add Ciphertext - decrypts to plaintext */
+	public byte[] add_cipher(byte[] cipher,int len)
+	{
+		int i,j=0;
+		int counter;
+		byte[] B=new byte[16];
+		byte[] b=new byte[4];
+		byte[] plain=new byte[len];
+
+		if (status==GCM_ACCEPTING_HEADER) status=GCM_ACCEPTING_CIPHER;
+		if (status!=GCM_ACCEPTING_CIPHER) return new byte[0];
+	
+		while (j<len)
+		{
+
+			b[0]=a.f[12]; b[1]=a.f[13]; b[2]=a.f[14]; b[3]=a.f[15];
+			counter=pack(b);
+			counter++;
+			b=unpack(counter);
+			a.f[12]=b[0]; a.f[13]=b[1]; a.f[14]=b[2]; a.f[15]=b[3]; /* increment counter */
+			for (i=0;i<16;i++) B[i]=a.f[i];
+			a.ecb_encrypt(B);        /* encrypt it  */
+			for (i=0;i<16 && j<len;i++)
+			{
+				byte oc=cipher[j];
+				plain[j]=(byte)(cipher[j]^B[i]);
+				stateX[i]^=oc; j++;
+				lenC[1]++; if (lenC[1]==0) lenC[0]++;
+			}
+			gf2mul();
+		}
+		if (len%16!=0) status=GCM_NOT_ACCEPTING_MORE;
+		return plain;
+	}
+
+/* Finish and extract Tag */
+	public byte[] finish(boolean extract)
+	{ /* Finish off GHASH and extract tag (MAC) */
+		int i;
+		byte[] tag=new byte[16];
+
+		wrap();
+/* extract tag */
+		if (extract)
+		{
+			a.ecb_encrypt(Y_0);        /* E(K,Y0) */
+			for (i=0;i<16;i++) Y_0[i]^=stateX[i];
+			for (i=0;i<16;i++) {tag[i]=Y_0[i];Y_0[i]=stateX[i]=0;}
+		}
+		status=GCM_FINISHED;
+		a.end();
+		return tag;
+	}
+
+	public static byte[] hex2bytes(String s) {
+		int len = s.length();
+		byte[] data = new byte[len / 2];
+		for (int i = 0; i < len; i += 2) {
+			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+                             + Character.digit(s.charAt(i+1), 16));
+		}
+		return data;
+	}
+/*
+	public static void main(String[] args) {
+		int i;
+
+		String KT="feffe9928665731c6d6a8f9467308308";
+		String MT="d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39";
+		String HT="feedfacedeadbeeffeedfacedeadbeefabaddad2";
+//	char* NT="cafebabefacedbaddecaf888";
+// Tag should be 5bc94fbc3221a5db94fae95ae7121a47
+		String NT="9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b";
+// Tag should be 619cc5aefffe0bfa462af43c1699d050
+
+
+		byte[] T=new byte[16];   // Tag
+		byte[] K=new byte[16];   // AES Key
+		byte[] H=new byte[64];   // Header - to be included in Authentication, but not encrypted
+		byte[] N=new byte[100];   // IV - Initialisation vector
+		byte[] M=new byte[100];  // Plaintext to be encrypted/authenticated
+		byte[] C=new byte[100];  // Ciphertext
+		byte[] P=new byte[100];  // Recovered Plaintext 
+
+		GCM g=new GCM();
+
+		M=hex2bytes(MT);
+		H=hex2bytes(HT);
+		N=hex2bytes(NT);
+		K=hex2bytes(KT);
+
+		int len=M.length;
+		int lenH=H.length;
+		int lenK=K.length;
+		int lenIV=N.length;
+
+ 		System.out.format("Plaintext=\n");
+		for (i=0;i<len;i++) System.out.format("%02x",M[i]);
+		System.out.format("\n");
+
+		g.init(16,K,lenIV,N);
+		g.add_header(H,lenH);
+		C=g.add_plain(M,len);
+		T=g.finish(true);
+
+		System.out.format("Ciphertext=\n");
+		for (i=0;i<len;i++) System.out.format("%02x",C[i]);
+		System.out.format("\n");
+        
+		System.out.format("Tag=\n");
+		for (i=0;i<16;i++) System.out.format("%02x",T[i]);
+		System.out.format("\n");
+
+		g.init(16,K,lenIV,N);
+		g.add_header(H,lenH);
+		P=g.add_cipher(C,len);
+		T=g.finish(true);
+
+ 		System.out.format("Plaintext=\n");
+		for (i=0;i<len;i++) System.out.format("%02x",P[i]);
+		System.out.format("\n");
+
+		System.out.format("Tag=\n");
+		for (i=0;i<16;i++) System.out.format("%02x",T[i]);
+		System.out.format("\n");
+	}
+*/	
+}
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/BIG.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/BIG.java
new file mode 100644
index 0000000..4ffc2d0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=56; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/DBIG.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/DBIG.java
new file mode 100644
index 0000000..e6d8fa3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECDH.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECDH.java
new file mode 100644
index 0000000..1f41b34
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECP.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECP.java
new file mode 100644
index 0000000..e2f80b2
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/FP.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/FP.java
new file mode 100644
index 0000000..58a7bb4
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=448; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=GENERALISED_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<16);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ROM.java b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ROM.java
new file mode 100644
index 0000000..b402de7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/GOLDILOCKS/ROM.java
@@ -0,0 +1,44 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.GOLDILOCKS;
+
+public class ROM
+{
+
+// Base Bits= 58
+public static final long[] Modulus= {0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FBFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFL};
+public static final long[] R2modp= {0x200000000L,0x0L,0x0L,0x0L,0x3000000L,0x0L,0x0L,0x0L};
+public static final long MConst= 0x1L;
+
+
+public static final int CURVE_Cof_I= 4;
+public static final long[] CURVE_Cof= {0x4L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+public static final int CURVE_A= 1;
+public static final int CURVE_B_I= -39081;
+public static final long[] CURVE_B= {0x3FFFFFFFFFF6756L,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FBFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFL};
+public static final long[] CURVE_Order= {0x378C292AB5844F3L,0x3309CA37163D548L,0x1B49AED63690216L,0x3FDF3288FA7113BL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0xFFFFFFFFFFL};
+public static final long[] CURVE_Gx= {0x155555555555555L,0x155555555555555L,0x155555555555555L,0x2A5555555555555L,0x2AAAAAAAAAAAAAAL,0x2AAAAAAAAAAAAAAL,0x2AAAAAAAAAAAAAAL,0x2AAAAAAAAAAL};
+public static final long[] CURVE_Gy= {0x2EAFBCDEA9386EDL,0x32CAFB473681AF6L,0x25833A2A3098BBBL,0x1CA2B6312E03595L,0x35884DD7B7E36DL,0x21B0AC00DBB5E8L,0x17048DB359D6205L,0x2B817A58D2BL};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/HASH256.java b/src/main/java/org/apache/milagro/amcl/HASH256.java
new file mode 100644
index 0000000..915642e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HASH256.java
@@ -0,0 +1,218 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ * Implementation of the Secure Hashing Algorithm (SHA-256)
+ *
+ * Generates a 256 bit message digest. It should be impossible to come
+ * come up with two messages that hash to the same value ("collision free").
+ *
+ * For use with byte-oriented messages only. 
+ */
+
+package org.apache.milagro.amcl;
+
+public class HASH256 {
+	private int[] length=new int[2];
+	private int[] h=new int[8];
+	private int[] w=new int[80];
+
+	public static final int H0=0x6A09E667;
+	public static final int H1=0xBB67AE85;
+	public static final int H2=0x3C6EF372;
+	public static final int H3=0xA54FF53A;
+	public static final int H4=0x510E527F;
+	public static final int H5=0x9B05688C;
+	public static final int H6=0x1F83D9AB;
+	public static final int H7=0x5BE0CD19;
+
+	public static final int len=32;
+
+	public static final int[] K={
+	0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
+	0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
+	0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
+	0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
+	0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
+	0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
+	0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
+	0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};
+
+
+/* functions */
+	private static int S(int n,int x)
+	{
+		return (((x)>>>n) | ((x)<<(32-n)));
+	}
+
+	private static int R(int n,int x)
+	{
+		return ((x)>>>n);
+	}
+
+	private static int Ch(int x,int y,int z)
+	{
+		return ((x&y)^(~(x)&z));
+	}
+
+	private static int Maj(int x,int y,int z)
+	{
+		return ((x&y)^(x&z)^(y&z));
+	}
+
+	private static int Sig0(int x)
+	{
+		return (S(2,x)^S(13,x)^S(22,x));
+	}
+
+	private static int Sig1(int x)
+	{
+		return (S(6,x)^S(11,x)^S(25,x));
+	}
+
+	private static int theta0(int x)
+	{
+		return (S(7,x)^S(18,x)^R(3,x));
+	}
+
+	private static int theta1(int x)
+	{
+		return (S(17,x)^S(19,x)^R(10,x));
+	}
+
+
+	private void transform()
+	{ /* basic transformation step */
+		int a,b,c,d,e,f,g,hh,t1,t2;
+		int j;
+		for (j=16;j<64;j++) 
+			w[j]=theta1(w[j-2])+w[j-7]+theta0(w[j-15])+w[j-16];
+		a=h[0]; b=h[1]; c=h[2]; d=h[3]; 
+		e=h[4]; f=h[5]; g=h[6]; hh=h[7];
+
+		for (j=0;j<64;j++)
+		{ /* 64 times - mush it up */
+			t1=hh+Sig1(e)+Ch(e,f,g)+K[j]+w[j];
+			t2=Sig0(a)+Maj(a,b,c);
+			hh=g; g=f; f=e;
+			e=d+t1;
+			d=c;
+			c=b;
+			b=a;
+			a=t1+t2;   
+		
+		}
+		h[0]+=a; h[1]+=b; h[2]+=c; h[3]+=d; 
+		h[4]+=e; h[5]+=f; h[6]+=g; h[7]+=hh; 
+	} 
+
+/* Initialise Hash function */
+	public void init()
+	{ /* initialise */
+		int i;
+		for (i=0;i<64;i++) w[i]=0;
+		length[0]=length[1]=0;
+		h[0]=H0;
+		h[1]=H1;
+		h[2]=H2;
+		h[3]=H3;
+		h[4]=H4;
+		h[5]=H5;
+		h[6]=H6;
+		h[7]=H7;
+	}
+
+/* Constructor */
+	public HASH256()
+	{
+		init();
+	}
+
+/* process a single byte */
+	public void process(int byt)
+	{ /* process the next message byte */
+		int cnt;
+		cnt=(length[0]/32)%16;
+    
+		w[cnt]<<=8;
+		w[cnt]|=(byt&0xFF);
+		length[0]+=8;
+		if (length[0]==0) { length[1]++; length[0]=0; }
+		if ((length[0]%512)==0) transform();
+	}
+
+/* process an array of bytes */	
+	public void process_array(byte[] b)
+	{
+		for (int i=0;i<b.length;i++) process((int)b[i]);
+	}
+
+/* process a 32-bit integer */
+	public void process_num(int n)
+	{
+		process((n>>24)&0xff);
+		process((n>>16)&0xff);
+		process((n>>8)&0xff);
+		process(n&0xff);
+	}
+
+/* Generate 32-byte Hash */
+	public byte[] hash()
+	{ /* pad message and finish - supply digest */
+		int i;
+		byte[] digest=new byte[32];
+		int len0,len1;
+		len0=length[0];
+		len1=length[1];
+		process(0x80);
+		while ((length[0]%512)!=448) process(0);
+		w[14]=len1;
+		w[15]=len0;    
+		transform();
+		for (i=0;i<len;i++)
+		{ /* convert to bytes */
+			digest[i]=(byte)((h[i/4]>>(8*(3-i%4))) & 0xff);
+		}
+		init();
+		return digest;
+	}
+
+/* test program: should produce digest */
+
+//248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
+
+	public static void main(String[] args) {
+		byte[] test="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".getBytes();
+		byte[] digest;
+		int i;
+		HASH256 sh=new HASH256();
+  
+		for (i=0;i<test.length;i++)
+			sh.process(test[i]);
+		
+		digest=sh.hash();    
+		for (i=0;i<32;i++) System.out.format("%02x",digest[i]);
+
+	//	for (i=0;i<32;i++) System.out.format("%d ",digest[i]);
+
+		System.out.println("");
+	} 
+}
+
+
diff --git a/src/main/java/org/apache/milagro/amcl/HASH384.java b/src/main/java/org/apache/milagro/amcl/HASH384.java
new file mode 100644
index 0000000..6fc50fc
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HASH384.java
@@ -0,0 +1,229 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ * Implementation of the Secure Hashing Algorithm (SHA-512)
+ *
+ * Generates a 512 bit message digest. It should be impossible to come
+ * come up with two messages that hash to the same value ("collision free").
+ *
+ * For use with byte-oriented messages only. 
+ */
+
+package org.apache.milagro.amcl;
+
+public class HASH384 {
+	private long[] length=new long[2];
+	private long[] h=new long[8];
+	private long[] w=new long[80];
+
+	public static final long H0=0xcbbb9d5dc1059ed8L;
+	public static final long H1=0x629a292a367cd507L;
+	public static final long H2=0x9159015a3070dd17L;
+	public static final long H3=0x152fecd8f70e5939L;
+	public static final long H4=0x67332667ffc00b31L;
+	public static final long H5=0x8eb44a8768581511L;
+	public static final long H6=0xdb0c2e0d64f98fa7L;
+	public static final long H7=0x47b5481dbefa4fa4L;
+
+	public static final int len=48;
+
+	public static final long[] K=
+	{0x428a2f98d728ae22L,0x7137449123ef65cdL,0xb5c0fbcfec4d3b2fL,0xe9b5dba58189dbbcL,
+	0x3956c25bf348b538L,0x59f111f1b605d019L,0x923f82a4af194f9bL,0xab1c5ed5da6d8118L,
+	0xd807aa98a3030242L,0x12835b0145706fbeL,0x243185be4ee4b28cL,0x550c7dc3d5ffb4e2L,
+	0x72be5d74f27b896fL,0x80deb1fe3b1696b1L,0x9bdc06a725c71235L,0xc19bf174cf692694L,
+	0xe49b69c19ef14ad2L,0xefbe4786384f25e3L,0x0fc19dc68b8cd5b5L,0x240ca1cc77ac9c65L,
+	0x2de92c6f592b0275L,0x4a7484aa6ea6e483L,0x5cb0a9dcbd41fbd4L,0x76f988da831153b5L,
+	0x983e5152ee66dfabL,0xa831c66d2db43210L,0xb00327c898fb213fL,0xbf597fc7beef0ee4L,
+	0xc6e00bf33da88fc2L,0xd5a79147930aa725L,0x06ca6351e003826fL,0x142929670a0e6e70L,
+	0x27b70a8546d22ffcL,0x2e1b21385c26c926L,0x4d2c6dfc5ac42aedL,0x53380d139d95b3dfL,
+	0x650a73548baf63deL,0x766a0abb3c77b2a8L,0x81c2c92e47edaee6L,0x92722c851482353bL,
+	0xa2bfe8a14cf10364L,0xa81a664bbc423001L,0xc24b8b70d0f89791L,0xc76c51a30654be30L,
+	0xd192e819d6ef5218L,0xd69906245565a910L,0xf40e35855771202aL,0x106aa07032bbd1b8L,
+	0x19a4c116b8d2d0c8L,0x1e376c085141ab53L,0x2748774cdf8eeb99L,0x34b0bcb5e19b48a8L,
+	0x391c0cb3c5c95a63L,0x4ed8aa4ae3418acbL,0x5b9cca4f7763e373L,0x682e6ff3d6b2b8a3L,
+	0x748f82ee5defb2fcL,0x78a5636f43172f60L,0x84c87814a1f0ab72L,0x8cc702081a6439ecL,
+	0x90befffa23631e28L,0xa4506cebde82bde9L,0xbef9a3f7b2c67915L,0xc67178f2e372532bL,
+	0xca273eceea26619cL,0xd186b8c721c0c207L,0xeada7dd6cde0eb1eL,0xf57d4f7fee6ed178L,
+	0x06f067aa72176fbaL,0x0a637dc5a2c898a6L,0x113f9804bef90daeL,0x1b710b35131c471bL,
+	0x28db77f523047d84L,0x32caab7b40c72493L,0x3c9ebe0a15c9bebcL,0x431d67c49c100d4cL,
+	0x4cc5d4becb3e42b6L,0x597f299cfc657e2aL,0x5fcb6fab3ad6faecL,0x6c44198c4a475817L};
+
+/* functions */
+	private static long S(int n,long x)
+	{
+		return (((x)>>>n) | ((x)<<(64-n)));
+	}
+
+	private static long R(int n,long x)
+	{
+		return ((x)>>>n);
+	}
+
+	private static long Ch(long x,long y,long z)
+	{
+		return ((x&y)^(~(x)&z));
+	}
+
+	private static long Maj(long x,long y,long z)
+	{
+		return ((x&y)^(x&z)^(y&z));
+	}
+
+	private static long Sig0(long x)
+	{
+		return (S(28,x)^S(34,x)^S(39,x));
+	}
+
+	private static long Sig1(long x)
+	{
+		return (S(14,x)^S(18,x)^S(41,x));
+	}
+
+	private static long theta0(long x)
+	{
+		return (S(1,x)^S(8,x)^R(7,x));
+	}
+
+	private static long theta1(long x)
+	{
+		return (S(19,x)^S(61,x)^R(6,x));
+	}
+
+	private void transform()
+	{ /* basic transformation step */
+		long a,b,c,d,e,f,g,hh,t1,t2;
+		int j;
+		for (j=16;j<80;j++) 
+			w[j]=theta1(w[j-2])+w[j-7]+theta0(w[j-15])+w[j-16];
+		a=h[0]; b=h[1]; c=h[2]; d=h[3]; 
+		e=h[4]; f=h[5]; g=h[6]; hh=h[7];
+
+		for (j=0;j<80;j++)
+		{ /* 80 times - mush it up */
+			t1=hh+Sig1(e)+Ch(e,f,g)+K[j]+w[j];
+			t2=Sig0(a)+Maj(a,b,c);
+			hh=g; g=f; f=e;
+			e=d+t1;
+			d=c;
+			c=b;
+			b=a;
+			a=t1+t2;   
+		
+		}
+		h[0]+=a; h[1]+=b; h[2]+=c; h[3]+=d; 
+		h[4]+=e; h[5]+=f; h[6]+=g; h[7]+=hh; 
+	} 
+
+/* Initialise Hash function */
+	public void init()
+	{ /* initialise */
+		int i;
+		for (i=0;i<80;i++) w[i]=0L;
+		length[0]=length[1]=0L;
+		h[0]=H0;
+		h[1]=H1;
+		h[2]=H2;
+		h[3]=H3;
+		h[4]=H4;
+		h[5]=H5;
+		h[6]=H6;
+		h[7]=H7;
+	}
+
+/* Constructor */
+	public HASH384()
+	{
+		init();
+	}
+
+/* process a single byte */
+	public void process(int byt)
+	{ /* process the next message byte */
+		int cnt;
+		cnt=(int)(length[0]/64)%16;
+    
+		w[cnt]<<=8;
+		w[cnt]|=(byt&0xFF);
+		length[0]+=8;
+		if (length[0]==0L) { length[1]++; length[0]=0L; }
+		if ((length[0]%1024)==0) transform();
+	}
+
+/* process an array of bytes */	
+	public void process_array(byte[] b)
+	{
+		for (int i=0;i<b.length;i++) process((int)b[i]);
+	}
+
+/* process a 32-bit integer */
+	public void process_num(int n)
+	{
+		process((n>>24)&0xff);
+		process((n>>16)&0xff);
+		process((n>>8)&0xff);
+		process(n&0xff);
+	}
+
+/* Generate 48-byte Hash */
+	public byte[] hash()
+	{ /* pad message and finish - supply digest */
+		int i;
+		byte[] digest=new byte[48];
+		long len0,len1;
+		len0=length[0];
+		len1=length[1];
+		process(0x80);
+		while ((length[0]%1024)!=896) process(0);
+		w[14]=len1;
+		w[15]=len0;    
+		transform();
+		for (i=0;i<len;i++)
+		{ /* convert to bytes */
+			digest[i]=(byte)((h[i/8]>>(8*(7-i%8))) & 0xffL);
+		}
+		init();
+		return digest;
+	}
+
+/* test program: should produce digest */
+
+//09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712 fcc7c71a557e2db9 66c3e9fa91746039
+
+	public static void main(String[] args) {
+
+		byte[] test="abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".getBytes();
+		byte[] digest;
+		int i;
+		HASH384 sh=new HASH384();
+  
+		for (i=0;i<test.length;i++)
+			sh.process(test[i]);
+		
+		digest=sh.hash();    
+		for (i=0;i<48;i++) System.out.format("%02x",digest[i]);
+
+	//	for (i=0;i<32;i++) System.out.format("%d ",digest[i]);
+
+		System.out.println("");
+
+	} 
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/HASH512.java b/src/main/java/org/apache/milagro/amcl/HASH512.java
new file mode 100644
index 0000000..686ab22
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HASH512.java
@@ -0,0 +1,232 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ * Implementation of the Secure Hashing Algorithm (SHA-512)
+ *
+ * Generates a 512 bit message digest. It should be impossible to come
+ * come up with two messages that hash to the same value ("collision free").
+ *
+ * For use with byte-oriented messages only. 
+ */
+
+
+package org.apache.milagro.amcl;
+
+public class HASH512 {
+
+	private long[] length=new long[2];
+	private long[] h=new long[8];
+	private long[] w=new long[80];
+
+	public static final long H0=0x6a09e667f3bcc908L;
+	public static final long H1=0xbb67ae8584caa73bL;
+	public static final long H2=0x3c6ef372fe94f82bL;
+	public static final long H3=0xa54ff53a5f1d36f1L;
+	public static final long H4=0x510e527fade682d1L;
+	public static final long H5=0x9b05688c2b3e6c1fL;
+	public static final long H6=0x1f83d9abfb41bd6bL;
+	public static final long H7=0x5be0cd19137e2179L;
+
+	public static final int len=64;
+
+	public static final long[] K=
+	{0x428a2f98d728ae22L,0x7137449123ef65cdL,0xb5c0fbcfec4d3b2fL,0xe9b5dba58189dbbcL,
+	0x3956c25bf348b538L,0x59f111f1b605d019L,0x923f82a4af194f9bL,0xab1c5ed5da6d8118L,
+	0xd807aa98a3030242L,0x12835b0145706fbeL,0x243185be4ee4b28cL,0x550c7dc3d5ffb4e2L,
+	0x72be5d74f27b896fL,0x80deb1fe3b1696b1L,0x9bdc06a725c71235L,0xc19bf174cf692694L,
+	0xe49b69c19ef14ad2L,0xefbe4786384f25e3L,0x0fc19dc68b8cd5b5L,0x240ca1cc77ac9c65L,
+	0x2de92c6f592b0275L,0x4a7484aa6ea6e483L,0x5cb0a9dcbd41fbd4L,0x76f988da831153b5L,
+	0x983e5152ee66dfabL,0xa831c66d2db43210L,0xb00327c898fb213fL,0xbf597fc7beef0ee4L,
+	0xc6e00bf33da88fc2L,0xd5a79147930aa725L,0x06ca6351e003826fL,0x142929670a0e6e70L,
+	0x27b70a8546d22ffcL,0x2e1b21385c26c926L,0x4d2c6dfc5ac42aedL,0x53380d139d95b3dfL,
+	0x650a73548baf63deL,0x766a0abb3c77b2a8L,0x81c2c92e47edaee6L,0x92722c851482353bL,
+	0xa2bfe8a14cf10364L,0xa81a664bbc423001L,0xc24b8b70d0f89791L,0xc76c51a30654be30L,
+	0xd192e819d6ef5218L,0xd69906245565a910L,0xf40e35855771202aL,0x106aa07032bbd1b8L,
+	0x19a4c116b8d2d0c8L,0x1e376c085141ab53L,0x2748774cdf8eeb99L,0x34b0bcb5e19b48a8L,
+	0x391c0cb3c5c95a63L,0x4ed8aa4ae3418acbL,0x5b9cca4f7763e373L,0x682e6ff3d6b2b8a3L,
+	0x748f82ee5defb2fcL,0x78a5636f43172f60L,0x84c87814a1f0ab72L,0x8cc702081a6439ecL,
+	0x90befffa23631e28L,0xa4506cebde82bde9L,0xbef9a3f7b2c67915L,0xc67178f2e372532bL,
+	0xca273eceea26619cL,0xd186b8c721c0c207L,0xeada7dd6cde0eb1eL,0xf57d4f7fee6ed178L,
+	0x06f067aa72176fbaL,0x0a637dc5a2c898a6L,0x113f9804bef90daeL,0x1b710b35131c471bL,
+	0x28db77f523047d84L,0x32caab7b40c72493L,0x3c9ebe0a15c9bebcL,0x431d67c49c100d4cL,
+	0x4cc5d4becb3e42b6L,0x597f299cfc657e2aL,0x5fcb6fab3ad6faecL,0x6c44198c4a475817L};
+
+/* functions */
+	private static long S(int n,long x)
+	{
+		return (((x)>>>n) | ((x)<<(64-n)));
+	}
+
+	private static long R(int n,long x)
+	{
+		return ((x)>>>n);
+	}
+
+	private static long Ch(long x,long y,long z)
+	{
+		return ((x&y)^(~(x)&z));
+	}
+
+	private static long Maj(long x,long y,long z)
+	{
+		return ((x&y)^(x&z)^(y&z));
+	}
+
+	private static long Sig0(long x)
+	{
+		return (S(28,x)^S(34,x)^S(39,x));
+	}
+
+	private static long Sig1(long x)
+	{
+		return (S(14,x)^S(18,x)^S(41,x));
+	}
+
+	private static long theta0(long x)
+	{
+		return (S(1,x)^S(8,x)^R(7,x));
+	}
+
+	private static long theta1(long x)
+	{
+		return (S(19,x)^S(61,x)^R(6,x));
+	}
+
+
+	private void transform()
+	{ /* basic transformation step */
+		long a,b,c,d,e,f,g,hh,t1,t2;
+		int j;
+		for (j=16;j<80;j++) 
+			w[j]=theta1(w[j-2])+w[j-7]+theta0(w[j-15])+w[j-16];
+		a=h[0]; b=h[1]; c=h[2]; d=h[3]; 
+		e=h[4]; f=h[5]; g=h[6]; hh=h[7];
+
+		for (j=0;j<80;j++)
+		{ /* 80 times - mush it up */
+			t1=hh+Sig1(e)+Ch(e,f,g)+K[j]+w[j];
+			t2=Sig0(a)+Maj(a,b,c);
+			hh=g; g=f; f=e;
+			e=d+t1;
+			d=c;
+			c=b;
+			b=a;
+			a=t1+t2;   
+		
+		}
+		h[0]+=a; h[1]+=b; h[2]+=c; h[3]+=d; 
+		h[4]+=e; h[5]+=f; h[6]+=g; h[7]+=hh; 
+	} 
+
+/* Initialise Hash function */
+	public void init()
+	{ /* initialise */
+		int i;
+		for (i=0;i<80;i++) w[i]=0L;
+		length[0]=length[1]=0L;
+		h[0]=H0;
+		h[1]=H1;
+		h[2]=H2;
+		h[3]=H3;
+		h[4]=H4;
+		h[5]=H5;
+		h[6]=H6;
+		h[7]=H7;
+	}
+
+/* Constructor */
+	public HASH512()
+	{
+		init();
+	}
+
+/* process a single byte */
+	public void process(int byt)
+	{ /* process the next message byte */
+		int cnt;
+		cnt=(int)(length[0]/64)%16;
+    
+		w[cnt]<<=8;
+		w[cnt]|=(byt&0xFF);
+		length[0]+=8;
+		if (length[0]==0L) { length[1]++; length[0]=0L; }
+		if ((length[0]%1024)==0) transform();
+	}
+
+/* process an array of bytes */	
+	public void process_array(byte[] b)
+	{
+		for (int i=0;i<b.length;i++) process((int)b[i]);
+	}
+
+/* process a 32-bit integer */
+	public void process_num(int n)
+	{
+		process((n>>24)&0xff);
+		process((n>>16)&0xff);
+		process((n>>8)&0xff);
+		process(n&0xff);
+	}
+
+/* Generate 64-byte Hash */
+	public byte[] hash()
+	{ /* pad message and finish - supply digest */
+		int i;
+		byte[] digest=new byte[64];
+		long len0,len1;
+		len0=length[0];
+		len1=length[1];
+		process(0x80);
+		while ((length[0]%1024)!=896) process(0);
+		w[14]=len1;
+		w[15]=len0;    
+		transform();
+		for (i=0;i<len;i++)
+		{ /* convert to bytes */
+			digest[i]=(byte)((h[i/8]>>(8*(7-i%8))) & 0xffL);
+		}
+		init();
+		return digest;
+	}
+
+/* test program: should produce digest */
+
+//8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018 501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909
+
+	public static void main(String[] args) {
+
+		byte[] test="abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".getBytes();
+		byte[] digest;
+		int i;
+		HASH512 sh=new HASH512();
+  
+		for (i=0;i<test.length;i++)
+			sh.process(test[i]);
+		
+		digest=sh.hash();    
+		for (i=0;i<64;i++) System.out.format("%02x",digest[i]);
+
+	//	for (i=0;i<32;i++) System.out.format("%d ",digest[i]);
+
+		System.out.println("");
+
+	} 
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/BIG.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/BIG.java
new file mode 100644
index 0000000..ed52f3e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.HIFIVE;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=42; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/DBIG.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/DBIG.java
new file mode 100644
index 0000000..446cff6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.HIFIVE;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/ECDH.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/ECDH.java
new file mode 100644
index 0000000..4acdf2e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.HIFIVE;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/ECP.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/ECP.java
new file mode 100644
index 0000000..a39665f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.HIFIVE;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=48;
+	public static final int AESKEY=24;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/FP.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/FP.java
new file mode 100644
index 0000000..c6017f1
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.HIFIVE;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=336; /* Number of bits in Modulus */
+	public static final int MOD8=5;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/HIFIVE/ROM.java b/src/main/java/org/apache/milagro/amcl/HIFIVE/ROM.java
new file mode 100644
index 0000000..bed83e6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/HIFIVE/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.HIFIVE;
+
+public class ROM
+{
+
+// Base Bits= 60
+	public static final long[] Modulus= {0xFFFFFFFFFFFFFFDL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFL};
+	public static final long[] R2modp= {0x9000000000000L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x3L;
+
+	public static final int CURVE_Cof_I= 8;
+	public static final long[] CURVE_Cof= {0x8L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= 1;
+	public static final int CURVE_B_I= 11111;
+	public static final long[] CURVE_B= {0x2B67L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0xB2F95973E9FA805L,0xC0BD6B87F93BAA7L,0x71415FA9850L,0x0L,0x0L,0x200000000L};
+	public static final long[] CURVE_Gx= {0xCL,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Gy= {0x2BEC68505FE8632L,0x5D5650CA0365DB1L,0x3811C7EF435B6DBL,0x7853D1B14B46CL,0x56502E18E1C161DL,0xC0DC616BL};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NHS.java b/src/main/java/org/apache/milagro/amcl/NHS.java
new file mode 100644
index 0000000..66b764e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NHS.java
@@ -0,0 +1,577 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* NewHope API high-level functions  */
+
+//import amcl.SHA3;
+//import amcl.RAND;
+
+package org.apache.milagro.amcl;
+
+public final class NHS {
+
+	public static final int RLWE_PRIME=0x3001;	// q in Hex
+	public final static int RLWE_LGN=10;		// Degree n=2^LGN
+	public final static long RLWE_ND=0xF7002FFFL;	// 1/(R-q) mod R
+	public final static int RLWE_ONE=0x2AC8;		// R mod q
+	public final static int RLWE_R2MODP=0x1620;	// R^2 mod q
+
+	public final static int DEGREE=(1<<RLWE_LGN);
+	public final static int WL=32;
+
+	public final static int[] roots ={0x2ac8,0x2baf,0x299b,0x685,0x2f04,0x158d,0x2d49,0x24b5,0x1edc,0xab3,0x2a95,0x24d,0x3cb,0x6a8,0x12f9,0x15ba,0x1861,0x2a89,0x1c5c,0xbe6,0xc1e,0x2024,0x207,0x19ce,0x2710,0x1744,0x18bc,0x2cd7,0x396,0x18d5,0x1c45,0xc4,0x21a6,0xe03,0x2b3c,0x2d91,0xc5d,0x432,0x1fbc,0xcae,0x2512,0x2979,0x3b2,0x714,0xb2e,0x1a97,0x1a03,0x1bcd,0x2216,0x2701,0xa,0x263c,0x1179,0x200c,0x2d08,0x1c34,0x291,0x2c99,0x2a5a,0x723,0xb1d,0x1ccc,0x1fb6,0x2f58,0x2bfe,0x1cda,0x2a0,0x5f1,0x2de,0x1fc7,0x1ea8,0x1719,0x2fa7,0x27ec,0x20ff,0x12c0,0x1ac1,0x2232,0x2f9b,0xd3e,0x2aed,0x15f0,0x11e8,0xed0,0x26a,0x1de5,0xa3f,0xf43,0xebf,0x204e,0xac7,0x2d9c,0x5ea,0x25d1,0xb6,0x49c,0x995,0x2555,0x26e2,0x100,0x1878,0x5aa,0x2e10,0x271c,0xcb,0x1b4c,0x2fb8,0x25b7,0x1543,0x2c7b,0x241a,0x2223,0x20ca,0x24ed,0x137,0x1b65,0x1dc2,0x7c7,0x2ec3,0xd0c,0x1169,0x1c7a,0x1ea1,0xf89,0x2199,0x291d,0x1088,0x2046,0x256d,0x2bc7,0x2e9b,0x41f,0x1b55,0x2b38,0xd0,0x2e6a,0x1755,0x6bc,0x2724,0x3ba,0x222e,0x2c5c,0x2da5,0x213c,0x10fe,0x169a,0x1552,0x5d3,0x300,0x1b5d,0x1342,0x2004,0x256f,0x2039,0x667,0x23b5,0x1123,0xdb,0x2da0,0xe1e,0x2f54,0x2767,0x154a,0x40a,0x11d3,0x2821,0xc09,0x974,0x694,0xfbf,0x27ba,0x132,0x83f,0x2d06,0x10e,0x183f,0x29ae,0x28c3,0x2dc9,0x1144,0x2c70,0x2a4a,0xf3c,0x1e32,0x1171,0x1e43,0xdd4,0x2ddf,0x28d2,0xfac,0x3c4,0x2f19,0x10a6,0x2f7,0xe1d,0x828,0x138f,0x1332,0xfab,0xcf6,0x13f8,0x24a0,0x112d,0x2717,0x6e7,0x1044,0x36e,0xfe8,0x6a,0xba7,0x1d69,0x29ec,0x23b2,0xaee,0x16df,0x1068,0x1a7e,0x253f,0x24c,0xb33,0x2683,0x15ce,0x1ad3,0x1a36,0xc96,0xaea,0x260a,0xce,0x28b1,0xe4f,0x2b11,0x5f8,0x1fc4,0xe77,0x2366,0x11f9,0x153c,0x24eb,0x20cd,0x1398,0x22,0x2b97,0x249b,0x8eb,0x12b2,0x2fe3,0x29c1,0x1b00,0x2663,0xeaa,0x2e06,0xe0,0x1569,0x10f5,0x284e,0xa38,0x201d,0x1c53,0x1681,0x1f6f,0x2f95,0x2fe8,0xacb,0x1680,0x17fd,0x2c39,0x165a,0x10bb,0x29d8,0x2622,0x1196,0x884,0x2a79,0x140e,0x2d80,0x6fa,0x11b2,0x26c4,0x355,0x1054,0x29e9,0x23ed,0xbe3,0x24fa,0x1fb3,0x10ac,0x2919,0x2584,0x10a4,0xe85,0x650,0x1893,0x1dc1,0xd8e,0x12dc,0x2d42,0x284d,0xfff,0x250f,0xacd,0x13c3,0x6cc,0x1a79,0x1221,0x2614,0x270a,0x1ea,0x155,0x2818,0x222c,0x2e5b,0x25d8,0x1dbf,0x191c,0xb0f,0xdac,0x1082,0x12ef,0x11b6,0xfa8,0x2b72,0x159d,0x209e,0x31b,0x2c7c,0x14f7,0xe09,0x1bb2,0x1ec7,0x2404,0x20ae,0x6ad,0xed6,0x2b70,0x1c7b,0x18d1,0x2732,0x12da,0xd56,0x5c1,0x1648,0x18b7,0x1605,0x1bc4,0x280,0x2ece,0xc,0x1aae,0x1c4,0x1cdb,0x22d6,0x21d8,0x257c,0x51f,0x211b,0xff,0x2ee0,0x2585,0xe1,0x2c35,0x26db,0x2971,0x2208,0x17e1,0x21be,0x135e,0x28d6,0x2891,0x1689,0x2138,0xb86,0x2e3a,0x1204,0x2d10,0x2324,0xf3f,0x2508,0x33d,0xcb2,0x292a,0xe27,0x2e64,0x29f8,0x2d46,0x9b7,0x20eb,0x1b7c,0x9eb,0x2b2a,0x58c,0x27d0,0x121b,0x272e,0x29f6,0x2dbd,0x2697,0x2aac,0xd6f,0x1c67,0x2c5b,0x108d,0x363,0x249d,0x2d5e,0x2fd,0x2cb2,0x1f8f,0x20a4,0xa19,0x2ac9,0x19b1,0x1581,0x17a2,0x29eb,0x1b72,0x13b0,0xee4,0xa8f,0x2315,0x5e6,0x951,0x2e29,0xdad,0x1f2b,0x224e,0x37f,0x1a72,0xa91,0x1407,0x2df9,0x3ad,0x23f7,0x1a24,0x1d2a,0x234b,0x1df3,0x1143,0x7ff,0x1a6d,0x2774,0x2690,0x2ab5,0x586,0x2781,0x2009,0x2fdd,0x2881,0x399,0x2fb6,0x144,0x137f,0xfa0,0x2e4c,0x1c7f,0x2fac,0xb09,0x1264,0x127b,0x198c,0x2b40,0x230,0x1cf4,0x180b,0xb58,0x144a,0x2aec,0xfb,0x2602,0x14ee,0x783,0x1098,0x23d8,0x203,0xe9,0x108a,0x14b8,0xeec,0xc58,0x1248,0x243c,0x28aa,0x6bf,0x27c4,0x276e,0x19b8,0x1d11,0x2e16,0x472,0x1464,0x24b9,0x662,0x1097,0x2067,0x20d6,0x171c,0x4,0x682,0x17bb,0x1186,0x4f2,0x3ff,0x2a43,0x1dc7,0x1ae5,0x8cc,0x2e7c,0x2ef8,0x2ae0,0x2904,0xed4,0x6c5,0x14ae,0xb72,0x11c3,0x337,0x2da3,0x2916,0x6d8,0x1cf9,0x10ee,0x1800,0x1ae4,0xa0d,0x101b,0x1a8d,0x2e98,0x24cd,0x813,0x1aa4,0x9b9,0x680,0x2349,0x24d1,0x20f8,0xe31,0x249f,0x216b,0x12d9,0x1d21,0x19db,0x191a,0x1dd0,0x5df,0x55c,0x2b86,0x213,0xe9e,0x1ef1,0x268a,0x1d5e,0x1e20,0x28c1,0x1379,0x249,0x19de,0x18b,0x1e41,0x2a1e,0x2612,0x297,0x2e96,0x2102,0x46,0x1b9f,0x1a4d,0x2050,0x1b32,0x568,0x11f7,0x1829,0x870,0x1f4,0x1dca,0x990,0x1df6,0x2b62,0x13ec,0x9f2,0x1260,0x2997,0x1412,0x1e6d,0x1694,0x11ac,0x2d8b,0x276f,0x26f5,0x233e,0x2b44,0x2f5a,0x2d37,0x2cb1,0xc75,0x98d,0x1d56,0x7ae,0x10e6,0x113f,0x17b8,0xad3,0x737,0x221e,0x1b70,0x1f3e,0x2966,0x18b2,0x4fa,0x2044,0x1312,0x154e,0x2029,0x700,0x1b45,0x27a6,0x226a,0x21bf,0x58d,0x2f11,0x2e02,0x17fc,0x4d2,0x1757,0xcb1,0x2ef1,0x2582,0x1276,0x881,0x2fc0,0x104a,0x670,0x274f,0x2b53,0x19dd,0x752,0x1663,0xcbd,0x2b2b,0x2fc6,0x13b6,0x21e6,0x15f6,0x126b,0x2637,0x1cd9,0x2f50,0xe82,0x5b0,0x24e0,0x1350,0x2f24,0x21f7,0x1a16,0x2f3e,0x167e,0x1f7d,0x28a0,0x16f0,0xe33,0x53b,0x28c5,0x1500,0x2f88,0x26cc,0x2018,0x1604,0x218b,0x2cd1,0x9ee,0x17f3,0x5fd,0x1f5a,0x2d0,0x2b46,0x23cc,0x503,0x1c46,0x1cc3,0x28e2,0x243e,0x122b,0x2e0c,0xe37,0x2611,0x85e,0x9b8,0x1b24,0x762,0x19b6,0x3bc,0x2d50,0x2079,0x18da,0x170a,0x800,0xaa2,0x135a,0x1a15,0x13d1,0xca,0x2113,0x2db9,0xdb2,0x1a5c,0x29a9,0x1488,0x14c1,0x2c9,0x917,0x28e7,0x265c,0xdab,0x2ab9,0x2bc6,0x105b,0x1839,0x219c,0x50,0x11da,0x1802,0xf56,0x2e6,0x2190,0xddb,0x56e,0x9d9,0x1c81,0x1016,0x12d6,0x296f,0x14b4,0x1014,0x1e64,0x1d90,0x89f,0x2bc2,0x2777,0x2819,0x1c65,0x1a41,0x5a2,0x2cd2,0x427,0xd71,0x29c8,0x1e58,0x53f,0x7c5,0x1dcd,0x4a1,0x1268,0x2597,0x2926,0xee,0x111b,0x1038,0xe6c,0x22dc,0x2f2f,0x441,0x2cfd,0x1cb0,0x6a4,0x2224,0x620,0x5dc,0x16b1,0x2a1d,0x1787,0x20c7,0x641,0xd84,0x1c05,0x2d0d,0x2f52,0x1b8c,0xd7d,0x17e8,0x1589,0xc73,0x151b,0x4e2,0x1ae9,0x1b18,0xb9b,0x949,0x2c60,0x1e7a,0xd5,0x1bdc,0x1f57,0x1753,0x124a,0x559,0xb76,0x2334,0x12d1,0x1de1,0x14b2,0x2faa,0x1697,0x147a,0x5a1,0x2c30,0x1c02,0x1043,0x2ee1,0x2402,0x1cc8,0x2a16,0xff7,0x1364,0x1b9a,0x2a53,0x2f94,0x294c,0x1ee5,0x1a87,0x2141,0xd66,0x953,0x28a3,0x2f30,0x2477,0x18e3,0x1035,0x1fc1,0x1d68,0x2fb3,0x138c,0x2487,0x1bf8,0xd96,0x1018,0x748,0x244e,0x15bd,0x175e,0x2be,0x23d,0x1da,0x176d,0xc17,0x24be,0x2ebb,0x7d8,0x100a,0x759,0x1db4,0x2259,0x23f4,0x2d59,0x2847,0xbf5,0x1cfe,0xa20,0x258,0x1180,0x279c,0x54,0x2abf,0xc5c,0x9f9,0x3d5,0x2ce4,0x165f,0x23d9,0x27b9,0x6f9,0x281a,0x169e,0x627,0x156d,0x1ff8,0x211,0x2e34,0x1724,0x2c2e,0x2790,0x2dd5,0x2bf2,0xdbc,0x2884,0x20a9,0x2390,0x1e1a,0x1b6a,0x5f7,0xab7,0x1333,0x16ab,0x28dd,0x20,0x30f,0x24b6,0x5c2,0x1ce4,0x1400,0x2669,0x60,0x156c,0xe20,0x26d4,0x26ab,0x1ebb,0x223d,0x5b4,0x2025,0x1e1c,0xaae,0x2e08,0x6cd,0x1677,0x13d9,0x17b5,0x1046,0x1d8c,0x14eb,0x18d8,0x1ce5,0x2478,0x16ae,0xb79,0x23d4,0x684,0x156b,0x567,0x1a,0x29ce,0x83a,0x19e8,0x58e,0x294a,0x1136,0x2319,0x2fba,0x1a29,0x1d,0x1879,0x291b,0x19f6,0x2c2f,0x21c9,0x19bb,0xbbc,0x26f9,0xc22,0x708,0x11a1,0x18d3,0x7f8,0x28f8,0x2427,0x1deb,0xaed,0x26aa,0x2482,0x203b,0x2f05,0x2b82,0x192f,0x2df4,0x8dc,0x2877,0xd5e,0x240e,0x775,0x2dae,0x1d3e,0x20ba,0x215b,0x22d1,0xeba,0xf50,0xaa8,0x184a,0x1f67,0x2e04,0xc6e,0x6dd,0x1a09,0x27f,0x494,0x1426,0xae3,0xe15,0x65f,0x13c4,0x105,0x872,0x2667,0x1ff6,0xd9f,0x2ca1,0x2f39,0x2657,0x23fd,0x2405,0xb73,0x2294,0x1f1e,0x2eba,0x110a,0x2cae,0x141f,0x22cd,0x25d6,0x11c1,0x1c,0x2d8e,0x161a,0x1aa8,0x229e,0x1bf9,0x7cf,0x106d,0x2c40,0xd93,0x255e,0x28c2,0xc1a,0x2f17,0x7ca,0x2f63,0xbf};
+	public final static int[] iroots= {0x2ac8,0x452,0x297c,0x666,0xb4c,0x2b8,0x1a74,0xfd,0x1a47,0x1d08,0x2959,0x2c36,0x2db4,0x56c,0x254e,0x1125,0x2f3d,0x13bc,0x172c,0x2c6b,0x32a,0x1745,0x18bd,0x8f1,0x1633,0x2dfa,0xfdd,0x23e3,0x241b,0x13a5,0x578,0x17a0,0xa9,0x104b,0x1335,0x24e4,0x28de,0x5a7,0x368,0x2d70,0x13cd,0x2f9,0xff5,0x1e88,0x9c5,0x2ff7,0x900,0xdeb,0x1434,0x15fe,0x156a,0x24d3,0x28ed,0x2c4f,0x688,0xaef,0x2353,0x1045,0x2bcf,0x23a4,0x270,0x4c5,0x21fe,0xe5b,0xfbb,0x1f79,0x6e4,0xe68,0x2078,0x1160,0x1387,0x1e98,0x22f5,0x13e,0x283a,0x123f,0x149c,0x2eca,0xb14,0xf37,0xdde,0xbe7,0x386,0x1abe,0xa4a,0x49,0x14b5,0x2f36,0x8e5,0x1f1,0x2a57,0x1789,0x2f01,0x91f,0xaac,0x266c,0x2b65,0x2f4b,0xa30,0x2a17,0x265,0x253a,0xfb3,0x2142,0x20be,0x25c2,0x121c,0x2d97,0x2131,0x1e19,0x1a11,0x514,0x22c3,0x66,0xdcf,0x1540,0x1d41,0xf02,0x815,0x5a,0x18e8,0x1159,0x103a,0x2d23,0x2a10,0x2d61,0x1327,0x403,0x25c9,0x7b3,0x1f0c,0x1a98,0x2f21,0x1fb,0x2157,0x99e,0x1501,0x640,0x1e,0x1d4f,0x2716,0xb66,0x46a,0x2fdf,0x1c69,0xf34,0xb16,0x1ac5,0x1e08,0xc9b,0x218a,0x103d,0x2a09,0x4f0,0x21b2,0x750,0x2f33,0x9f7,0x2517,0x236b,0x15cb,0x152e,0x1a33,0x97e,0x24ce,0x2db5,0xac2,0x1583,0x1f99,0x1922,0x2513,0xc4f,0x615,0x1298,0x245a,0x2f97,0x2019,0x2c93,0x1fbd,0x291a,0x8ea,0x1ed4,0xb61,0x1c09,0x230b,0x2056,0x1ccf,0x1c72,0x27d9,0x21e4,0x2d0a,0x1f5b,0xe8,0x2c3d,0x2055,0x72f,0x222,0x222d,0x11be,0x1e90,0x11cf,0x20c5,0x5b7,0x391,0x1ebd,0x238,0x73e,0x653,0x17c2,0x2ef3,0x2fb,0x27c2,0x2ecf,0x847,0x2042,0x296d,0x268d,0x23f8,0x7e0,0x1e2e,0x2bf7,0x1ab7,0x89a,0xad,0x21e3,0x261,0x2f26,0x1ede,0xc4c,0x299a,0xfc8,0xa92,0xffd,0x1cbf,0x14a4,0x2d01,0x2a2e,0x1aaf,0x1967,0x1f03,0xec5,0x25c,0x3a5,0xdd3,0x2c47,0x8dd,0x2945,0x18ac,0x197,0x2f31,0x4c9,0x14ac,0x2be2,0x166,0x43a,0xa94,0x1b53,0x293c,0x212d,0x6fd,0x521,0x109,0x185,0x2735,0x151c,0x123a,0x5be,0x2c02,0x2b0f,0x1e7b,0x1846,0x297f,0x2ffd,0x18e5,0xf2b,0xf9a,0x1f6a,0x299f,0xb48,0x1b9d,0x2b8f,0x1eb,0x12f0,0x1649,0x893,0x83d,0x2942,0x757,0xbc5,0x1db9,0x23a9,0x2115,0x1b49,0x1f77,0x2f18,0x2dfe,0xc29,0x1f69,0x287e,0x1b13,0x9ff,0x2f06,0x515,0x1bb7,0x24a9,0x17f6,0x130d,0x2dd1,0x4c1,0x1675,0x1d86,0x1d9d,0x24f8,0x55,0x1382,0x1b5,0x2061,0x1c82,0x2ebd,0x4b,0x2c68,0x780,0x24,0xff8,0x880,0x2a7b,0x54c,0x971,0x88d,0x1594,0x2802,0x1ebe,0x120e,0xcb6,0x12d7,0x15dd,0xc0a,0x2c54,0x208,0x1bfa,0x2570,0x158f,0x2c82,0xdb3,0x10d6,0x2254,0x1d8,0x26b0,0x2a1b,0xcec,0x2572,0x211d,0x1c51,0x148f,0x616,0x185f,0x1a80,0x1650,0x538,0x25e8,0xf5d,0x1072,0x34f,0x2d04,0x2a3,0xb64,0x2c9e,0x1f74,0x3a6,0x139a,0x2292,0x555,0x96a,0x244,0x60b,0x8d3,0x1de6,0x831,0x2a75,0x4d7,0x2616,0x1485,0xf16,0x264a,0x2bb,0x609,0x19d,0x21da,0x6d7,0x234f,0x2cc4,0xaf9,0x20c2,0xcdd,0x2f1,0x1dfd,0x1c7,0x247b,0xec9,0x1978,0x770,0x72b,0x1ca3,0xe43,0x1820,0xdf9,0x690,0x926,0x3cc,0x2f20,0xa7c,0x121,0x2f02,0xee6,0x2ae2,0xa85,0xe29,0xd2b,0x1326,0x2e3d,0x1553,0x2ff5,0x133,0x2d81,0x143d,0x19fc,0x174a,0x19b9,0x2a40,0x22ab,0x1d27,0x8cf,0x1730,0x1386,0x491,0x212b,0x2954,0xf53,0xbfd,0x113a,0x144f,0x21f8,0x1b0a,0x385,0x2ce6,0xf63,0x1a64,0x48f,0x2059,0x1e4b,0x1d12,0x1f7f,0x2255,0x24f2,0x16e5,0x1242,0xa29,0x1a6,0xdd5,0x7e9,0x2eac,0x2e17,0x8f7,0x9ed,0x1de0,0x1588,0x2935,0x1c3e,0x2534,0xaf2,0x2002,0x7b4,0x2bf,0x1d25,0x2273,0x1240,0x176e,0x29b1,0x217c,0x1f5d,0xa7d,0x6e8,0x1f55,0x104e,0xb07,0x241e,0xc14,0x618,0x1fad,0x2cac,0x93d,0x1e4f,0x2907,0x281,0x1bf3,0x588,0x277d,0x1e6b,0x9df,0x629,0x1f46,0x19a7,0x3c8,0x1804,0x1981,0x2536,0x19,0x6c,0x1092,0x1980,0x13ae,0xfe4,0x2f42,0x9e,0x2837,0xea,0x23e7,0x73f,0xaa3,0x226e,0x3c1,0x1f94,0x2832,0x1408,0xd63,0x1559,0x19e7,0x273,0x2fe5,0x1e40,0xa2b,0xd34,0x1be2,0x353,0x1ef7,0x147,0x10e3,0xd6d,0x248e,0xbfc,0xc04,0x9aa,0xc8,0x360,0x2262,0x100b,0x99a,0x278f,0x2efc,0x1c3d,0x29a2,0x21ec,0x251e,0x1bdb,0x2b6d,0x2d82,0x15f8,0x2924,0x2393,0x1fd,0x109a,0x17b7,0x2559,0x20b1,0x2147,0xd30,0xea6,0xf47,0x12c3,0x253,0x288c,0xbf3,0x22a3,0x78a,0x2725,0x20d,0x16d2,0x47f,0xfc,0xfc6,0xb7f,0x957,0x2514,0x1216,0xbda,0x709,0x2809,0x172e,0x1e60,0x28f9,0x23df,0x908,0x2445,0x1646,0xe38,0x3d2,0x160b,0x6e6,0x1788,0x2fe4,0x15d8,0x47,0xce8,0x1ecb,0x6b7,0x2a73,0x1619,0x27c7,0x633,0x2fe7,0x2a9a,0x1a96,0x297d,0xc2d,0x2488,0x1953,0xb89,0x131c,0x1729,0x1b16,0x1275,0x1fbb,0x184c,0x1c28,0x198a,0x2934,0x1f9,0x2553,0x11e5,0xfdc,0x2a4d,0xdc4,0x1146,0x956,0x92d,0x21e1,0x1a95,0x2fa1,0x998,0x1c01,0x131d,0x2a3f,0xb4b,0x2cf2,0x2fe1,0x724,0x1956,0x1cce,0x254a,0x2a0a,0x1497,0x11e7,0xc71,0xf58,0x77d,0x2245,0x40f,0x22c,0x871,0x3d3,0x18dd,0x1cd,0x2df0,0x1009,0x1a94,0x29da,0x1963,0x7e7,0x2908,0x848,0xc28,0x19a2,0x31d,0x2c2c,0x2608,0x23a5,0x542,0x2fad,0x865,0x1e81,0x2da9,0x25e1,0x1303,0x240c,0x7ba,0x2a8,0xc0d,0xda8,0x124d,0x28a8,0x1ff7,0x2829,0x146,0xb43,0x23ea,0x1894,0x2e27,0x2dc4,0x2d43,0x18a3,0x1a44,0xbb3,0x28b9,0x1fe9,0x226b,0x1409,0xb7a,0x1c75,0x4e,0x1299,0x1040,0x1fcc,0x171e,0xb8a,0xd1,0x75e,0x26ae,0x229b,0xec0,0x157a,0x111c,0x6b5,0x6d,0x5ae,0x1467,0x1c9d,0x200a,0x5eb,0x1339,0xbff,0x120,0x1fbe,0x13ff,0x3d1,0x2a60,0x1b87,0x196a,0x57,0x1b4f,0x1220,0x1d30,0xccd,0x248b,0x2aa8,0x1db7,0x18ae,0x10aa,0x1425,0x2f2c,0x1187,0x3a1,0x26b8,0x2466,0x14e9,0x1518,0x2b1f,0x1ae6,0x238e,0x1a78,0x1819,0x2284,0x1475,0xaf,0x2f4,0x13fc,0x227d,0x29c0,0xf3a,0x187a,0x5e4,0x1950,0x2a25,0x29e1,0xddd,0x295d,0x1351,0x304,0x2bc0,0xd2,0xd25,0x2195,0x1fc9,0x1ee6,0x2f13,0x6db,0xa6a,0x1d99,0x2b60,0x1234,0x283c,0x2ac2,0x11a9,0x639,0x2290,0x2bda,0x32f,0x2a5f,0x15c0,0x139c,0x7e8,0x88a,0x43f,0x2762,0x1271,0x119d,0x1fed,0x1b4d,0x692,0x1d2b,0x1feb,0x1380,0x2628,0x2a93,0x2226,0xe71,0x2d1b,0x20ab,0x17ff,0x1e27,0x2fb1,0xe65,0x17c8,0x1fa6,0x43b,0x548,0x2256,0x9a5,0x71a,0x26ea,0x2d38,0x1b40,0x1b79,0x658,0x15a5,0x224f,0x248,0xeee,0x2f37,0x1c30,0x15ec,0x1ca7,0x255f,0x2801,0x18f7,0x1727,0xf88,0x2b1,0x2c45,0x164b,0x289f,0x14dd,0x2649,0x27a3,0x9f0,0x21ca,0x1f5,0x1dd6,0xbc3,0x71f,0x133e,0x13bb,0x2afe,0xc35,0x4bb,0x2d31,0x10a7,0x2a04,0x180e,0x2613,0x330,0xe76,0x19fd,0xfe9,0x935,0x79,0x1b01,0x73c,0x2ac6,0x21ce,0x1911,0x761,0x1084,0x1983,0xc3,0x15eb,0xe0a,0xdd,0x1cb1,0xb21,0x2a51,0x217f,0xb1,0x1328,0x9ca,0x1d96,0x1a0b,0xe1b,0x1c4b,0x3b,0x4d6,0x2344,0x199e,0x28af,0x1624,0x4ae,0x8b2,0x2991,0x1fb7,0x41,0x2780,0x1d8b,0xa7f,0x110,0x2350,0x18aa,0x2b2f,0x1805,0x1ff,0xf0,0x2a74,0xe42,0xd97,0x85b,0x14bc,0x2901,0xfd8,0x1ab3,0x1cef,0xfbd,0x2b07,0x174f,0x69b,0x10c3,0x1491,0xde3,0x28ca,0x252e,0x1849,0x1ec2,0x1f1b,0x2853,0x12ab,0x2674,0x238c,0x350,0x2ca,0xa7,0x4bd,0xcc3,0x90c,0x892,0x276,0x1e55,0x196d,0x1194,0x1bef,0x66a,0x1da1,0x260f,0x1c15,0x49f,0x120b,0x2671,0x1237,0x2e0d,0x2791,0x17d8,0x1e0a,0x2a99,0x14cf,0xfb1,0x15b4,0x1462,0x2fbb,0xeff,0x16b,0x2d6a,0x9ef,0x5e3,0x11c0,0x2e76,0x1623,0x2db8,0x1c88,0x740,0x11e1,0x12a3,0x977,0x1110,0x2163,0x2dee,0x47b,0x2aa5,0x2a22,0x1231,0x16e7,0x1626,0x12e0,0x1d28,0xe96,0xb62,0x21d0,0xf09,0xb30,0xcb8,0x2981,0x2648,0x155d,0x27ee,0xb34,0x169,0x1574,0x1fe6,0x25f4,0x151d,0x1801,0x1f13,0x1308,0x2929,0x6eb,0x25e,0x2cca,0x1e3e,0x248f};
+	public final static int inv= 0xeab;
+	public final static int invpr= 0x2c2a;
+
+	static int round(int a,int b)
+	{
+		return (a+b/2)/b;
+	}
+	
+/* constant time absolute vaue */
+	static int nabs(int x)
+	{
+		int mask=(x>>31);
+		return (x+mask)^mask;
+	}
+
+/* Montgomery stuff */
+
+	static int redc(long T)
+	{
+		long m=(T*RLWE_ND)&0xffffffffL;
+		return (int)((m*RLWE_PRIME+T)>>>WL);
+	}
+
+	static int nres(int x)
+	{
+		return redc((long)x*RLWE_R2MODP);
+	}
+
+	static int modmul(int a,int b)
+	{
+		return redc((long)a*b);
+	}
+
+/* NTT code */
+/* Cooley-Tukey NTT */
+
+	static void ntt(int[] x)
+	{
+		int m,i,j,k,t=DEGREE/2;
+		int S,U,V,W,q=RLWE_PRIME;
+
+/* Convert to Montgomery form */
+		for (j=0;j<DEGREE;j++)
+			x[j]=nres(x[j]);
+
+		m=1;
+		while (m<DEGREE)
+		{
+			k=0;
+			for (i=0;i<m;i++)
+			{
+				S=roots[m+i];
+				for (j=k;j<k+t;j++)
+				{
+					U=x[j];   
+					V=modmul(x[j+t],S);
+					x[j]=U+V;
+					x[j+t]=U+2*q-V;
+				}
+				k+=2*t;
+			}
+			t/=2;
+			m*=2;
+		}
+	}
+
+/* Gentleman-Sande INTT */
+
+	static void intt(int[] x)
+	{
+		int m,i,j,k,t=1;
+		int S,U,V,W,q=RLWE_PRIME;
+
+		m=DEGREE/2;
+		while (m>1)
+		{
+			k=0;
+			for (i=0;i<m;i++)
+			{
+				S=iroots[m+i];
+				for (j=k;j<k+t;j++)
+				{	
+					U=x[j]; 
+					V=x[j+t];
+					x[j]=U+V;	
+					W=U+DEGREE*q-V; 
+					x[j+t]=modmul(W,S); 
+				}
+				k+=2*t;
+			}
+			t*=2;
+			m/=2;
+		}
+
+/* Last iteration merged with n^-1 */
+
+		t=DEGREE/2;
+		for (j=0;j<t;j++)
+		{
+			U=x[j];
+			V=x[j+t];
+			W=U+DEGREE*q-V; 
+			x[j+t]=modmul(W,invpr); 
+			x[j]=modmul(U+V,inv);
+		}
+/* convert back from Montgomery to "normal" form */
+		for (j=0;j<DEGREE;j++)
+		{
+			x[j]=redc(x[j]);  
+			x[j]-=q;
+			x[j]+=(x[j]>>(WL-1))&q;
+		} 
+	}
+
+/* See https://eprint.iacr.org/2016/1157.pdf */ 
+
+	static void Encode(byte[] key,int[] poly)
+	{
+		int i,j,b,k,kj,q2;
+
+		q2=RLWE_PRIME/2;
+		for (i=j=0;i<256;)
+		{
+			kj=key[j++];
+			for (k=0;k<8;k++)
+			{
+				b=kj&1;
+				poly[i]=b*q2;
+				poly[i+256]=b*q2;
+				poly[i+512]=b*q2;
+				poly[i+768]=b*q2;
+				kj>>=1;
+				i++;
+			}
+		}		
+	}
+
+	static void Decode(int[] poly,byte[] key)
+	{
+		int i,j,k;
+		int b,t,q2;
+		q2=RLWE_PRIME/2;
+		for (i=0;i<32;i++)
+			key[i]=0;
+
+		for (i=j=0;i<256;)
+		{
+			for (k=0;k<8;k++)
+			{
+				t=nabs(poly[i]-q2)+nabs(poly[i+256]-q2)+nabs(poly[i+512]-q2)+nabs(poly[i+768]-q2);
+
+				b=t-RLWE_PRIME;
+				b=(b>>31)&1;
+				key[j]=(byte)((((int)key[j]&0xff)>>1) + (b<<7));
+				i++;
+			}
+			j++;
+		}
+	}
+
+/* convert 32-byte seed to random polynomial */
+
+	static void Parse(byte[] seed,int[] poly)
+	{
+		int i,j;
+		int n;
+		byte[] hash=new byte[4*DEGREE];
+		SHA3 sh=new SHA3(SHA3.SHAKE128);
+
+		for (i=0;i<32;i++)
+			sh.process(seed[i]);
+		sh.shake(hash,4*DEGREE);
+
+		for (i=j=0;i<DEGREE;i++)
+		{
+			n=(int)hash[j]&0x7f; n<<=8;
+			n+=(int)hash[j+1]&0xff; n<<=8;
+			n+=(int)hash[j+2]&0xff; n<<=8;
+			n+=(int)hash[j+3]&0xff; j+=4;
+			poly[i]=nres(n);
+			//poly[i]=modmul(n,RLWE_ONE); // reduce 31-bit random number mod q
+		}
+	} 
+
+/* Compress 14 bits polynomial coefficients into byte array */
+/* 7 bytes is 3x14 */
+	static void pack(int[] poly,byte[] array)
+	{
+		int i,j,k;
+		int a,b,c,d;
+
+		for (i=j=0;i<DEGREE; )
+		{
+			a=poly[i++]; b=poly[i++]; c=poly[i++]; d=poly[i++];
+			array[j++]=(byte)(a&0xff);
+			array[j++]=(byte)(((a>>8)|(b<<6))&0xff);
+			array[j++]=(byte)((b>>2)&0xff);
+			array[j++]=(byte)(((b>>10)|(c<<4))&0xff);
+			array[j++]=(byte)((c>>4)&0xff);
+			array[j++]=(byte)(((c>>12)|(d<<2))&0xff);
+			array[j++]=(byte)(d>>6);
+		}
+	}
+
+	static void unpack(byte[] array,int[] poly)
+	{
+		int i,j,k;
+		int a,b,c,d,e,f,g;
+
+		for (i=j=0;i<DEGREE; )
+		{
+			a=((int)array[j++])&0xff; b=((int)array[j++])&0xff; c=((int)array[j++])&0xff; d=((int)array[j++])&0xff; e=((int)array[j++])&0xff; f=((int)array[j++])&0xff; g=((int)array[j++])&0xff;
+			poly[i++]=a|((b&0x3f)<<8);
+			poly[i++]=(b>>6)|(c<<2)|((d&0xf)<<10);
+			poly[i++]=(d>>4)|(e<<4)|((f&3)<<12);
+			poly[i++]=(f>>2)|(g<<6);
+		}
+	}
+
+
+/* See https://eprint.iacr.org/2016/1157.pdf */ 
+
+	static void Compress(int[] poly,byte[] array)
+	{
+		int i,j,k,b;
+		int col=0;
+
+		for (i=j=0;i<DEGREE;)
+		{
+			for (k=0;k<8;k++)
+			{
+				b=round((poly[i]*8),RLWE_PRIME)&7; 
+				col=(col<<3)+b;
+				i++;
+			}
+			array[j]=(byte)(col&0xff);
+			array[j+1]=(byte)((col>>>8)&0xff);
+			array[j+2]=(byte)((col>>>16)&0xff);
+			j+=3; col=0;
+		}
+	}
+
+	static void Decompress(byte[] array,int[] poly)
+	{
+		int i,j,k,b;
+		int col=0;
+
+		for (i=j=0;i<DEGREE;)
+		{
+			col=(int)array[j+2]&0xff;
+			col=(col<<8)+((int)array[j+1]&0xff);
+			col=(col<<8)+((int)array[j]&0xff);
+			j+=3;
+			for (k=0;k<8;k++)
+			{
+				b=(col&0xe00000)>>>21; col<<=3;
+				poly[i]=round((b*RLWE_PRIME),8);
+				i++;
+			}
+		}
+	}
+
+/* generate centered binomial distribution */ 
+
+	static void Error(RAND RNG,int[] poly)
+	{
+		int i,j;
+		int n1,n2,r;
+		for (i=0;i<DEGREE;i++)
+		{
+			n1=RNG.getByte()+(RNG.getByte()<<8);
+			n2=RNG.getByte()+(RNG.getByte()<<8);
+			r=0;
+			for (j=0;j<16;j++)
+			{
+				r+=(n1&1)-(n2&1);
+				n1>>=1; n2>>=1;
+			}
+			poly[i]=(r+RLWE_PRIME);
+		}
+	}
+
+	static void redc_it(int[] p)
+	{
+		int i;
+		for (i=0;i<DEGREE;i++)
+			p[i]=redc(p[i]);
+	}
+
+	static void nres_it(int[] p)
+	{
+		int i;
+		for (i=0;i<DEGREE;i++)
+			p[i]=nres(p[i]);
+	}
+
+	static void poly_mul(int[] p1,int[] p2,int[] p3)
+	{
+		int i;
+		for (i=0;i<DEGREE;i++)
+			p1[i]=modmul(p2[i],p3[i]);
+	}
+
+	static void poly_add(int[] p1,int[] p2,int[] p3)
+	{
+		int i;
+		for (i=0;i<DEGREE;i++)
+			p1[i]=(p2[i]+p3[i]);
+	}
+
+	static void poly_sub(int[] p1,int[] p2,int[] p3)
+	{
+		int i;
+		for (i=0;i<DEGREE;i++)
+			p1[i]=(p2[i]+RLWE_PRIME-p3[i]);
+	}	
+
+/* reduces inputs < 2q */
+	static void poly_soft_reduce(int[] poly)
+	{
+		int i;
+		int e;
+		for (i=0;i<DEGREE;i++)
+		{
+			e=poly[i]-RLWE_PRIME;
+			poly[i]=e+((e>>(WL-1))&RLWE_PRIME);
+		}
+	}
+
+/* fully reduces modulo q */
+	static void poly_hard_reduce(int[] poly)
+	{
+		int i;
+		int e;
+		for (i=0;i<DEGREE;i++)
+		{
+			e=modmul(poly[i],RLWE_ONE);
+			e=e-RLWE_PRIME;
+			poly[i]=e+((e>>(WL-1))&RLWE_PRIME);
+		}
+	}
+
+/* API files */
+
+	public static void SERVER_1(RAND RNG,byte[] SB,byte[] S)
+	{
+		int i;
+		byte[] seed=new byte[32];
+		byte[] array=new byte[1792];
+
+		int[] s=new int[DEGREE];
+		int[] e=new int[DEGREE];
+		int[] b=new int[DEGREE];
+
+		for (i=0;i<32;i++)
+			seed[i]=(byte)RNG.getByte();
+
+		Parse(seed,b);
+
+		Error(RNG,e);
+		Error(RNG,s);
+
+		ntt(s);
+		ntt(e);
+		poly_mul(b,b,s);
+		poly_add(b,b,e);
+		poly_hard_reduce(b);
+
+		redc_it(b);
+		pack(b,array);
+		
+		for (i=0;i<32;i++)
+			SB[i]=seed[i];
+		for (i=0;i<1792;i++)
+			SB[i+32]=array[i];
+
+		poly_hard_reduce(s);
+
+		pack(s,array);
+
+		for (i=0;i<1792;i++)
+			S[i]=array[i];
+
+	}
+
+	public static void CLIENT(RAND RNG,byte[] SB,byte[] UC,byte[] KEY)
+	{
+		int i;
+		SHA3 sh=new SHA3(SHA3.HASH256);
+
+		byte[] seed=new byte[32];
+		byte[] array=new byte[1792];
+		byte[] key=new byte[32];
+		byte[] cc=new byte[384];
+
+		int[] sd=new int[DEGREE];
+		int[] ed=new int[DEGREE];
+		int[] u=new int[DEGREE];
+		int[] k=new int[DEGREE];
+		int[] c=new int[DEGREE];
+		
+		Error(RNG,sd);
+		Error(RNG,ed);
+
+		ntt(sd);
+		ntt(ed);
+
+		for (i=0;i<32;i++)
+			seed[i]=SB[i];
+
+		for (i=0;i<1792;i++)
+			array[i]=SB[i+32];
+
+		Parse(seed,u);
+
+		poly_mul(u,u,sd);
+		poly_add(u,u,ed);
+		poly_hard_reduce(u);
+
+		for (i=0;i<32;i++)
+			key[i]=(byte)RNG.getByte();
+
+		for (i=0;i<32;i++)
+			sh.process(key[i]);
+		sh.hash(key);
+
+		Encode(key,k);
+
+		unpack(array,c);
+		nres_it(c);
+
+		poly_mul(c,c,sd);
+		intt(c);
+		Error(RNG,ed);
+		poly_add(c,c,ed);
+		poly_add(c,c,k);
+
+		Compress(c,cc);
+
+		sh.init(SHA3.HASH256);
+		for (i=0;i<32;i++)
+			sh.process(key[i]);
+		sh.hash(key);
+
+		for (i=0;i<32;i++)
+			KEY[i]=key[i];
+
+		redc_it(u);
+		pack(u,array);
+
+		for (i=0;i<1792;i++)
+			UC[i]=array[i];
+		for (i=0;i<384;i++)
+			UC[i+1792]=cc[i];
+
+	}
+
+	public static void SERVER_2(byte[] S,byte[] UC,byte[] KEY)
+	{
+		int i;
+		SHA3 sh=new SHA3(SHA3.HASH256);
+
+		int[] c=new int[DEGREE];
+		int[] s=new int[DEGREE];
+		int[] k=new int[DEGREE];
+
+		byte[] array=new byte[1792];
+		byte[] key=new byte[32];
+		byte[] cc=new byte[384];
+
+		for (i=0;i<1792;i++)
+			array[i]=UC[i];
+
+		unpack(array,k);
+		nres_it(k);
+
+		for (i=0;i<384;i++)
+			cc[i]=UC[i+1792];
+
+		Decompress(cc,c);
+
+		for (i=0;i<1792;i++)
+			array[i]=S[i];
+
+		unpack(array,s);
+
+		poly_mul(k,k,s);
+		intt(k);
+		poly_sub(k,c,k);
+		poly_soft_reduce(k);
+
+		Decode(k,key);
+
+		for (i=0;i<32;i++)
+			sh.process(key[i]);
+		sh.hash(key);
+
+		for (i=0;i<32;i++)
+			KEY[i]=key[i];
+	}
+/*
+	public static void main(String[] args) {
+		int i;
+		byte[] RAW=new byte[100];
+		byte[] S=new byte[1792];
+		byte[] SB=new byte[1824];
+		byte[] UC=new byte[2176];
+		byte[] KEYA=new byte[32];
+		byte[] KEYB=new byte[32];
+
+		RAND SRNG=new RAND();
+		RAND CRNG=new RAND();
+		SRNG.clean(); CRNG.clean();
+
+		for (i=0;i<100;i++) RAW[i]=(byte)(i+1);
+		SRNG.seed(100,RAW);
+
+										for (i=0;i<100;i++) RAW[i]=(byte)(i+2);
+										CRNG.seed(100,RAW);
+
+// NewHope Simple key exchange
+
+		SERVER_1(SRNG,SB,S);
+										CLIENT(CRNG,SB,UC,KEYB);
+		SERVER_2(S,UC,KEYA);
+
+		System.out.printf("Alice key= 0x");
+		for (i=0;i<KEYA.length;i++)
+			System.out.printf("%02x", KEYA[i]);
+		System.out.println();
+
+
+										System.out.printf("Bob's key= 0x");
+										for (i=0;i<KEYA.length;i++)
+											System.out.printf("%02x", KEYB[i]);
+										System.out.println();
+	} */
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/BIG.java b/src/main/java/org/apache/milagro/amcl/NIST256/BIG.java
new file mode 100644
index 0000000..0e69f4f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NIST256;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/DBIG.java b/src/main/java/org/apache/milagro/amcl/NIST256/DBIG.java
new file mode 100644
index 0000000..cdaaf63
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NIST256;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/ECDH.java b/src/main/java/org/apache/milagro/amcl/NIST256/ECDH.java
new file mode 100644
index 0000000..1bf50e6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NIST256;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/ECP.java b/src/main/java/org/apache/milagro/amcl/NIST256/ECP.java
new file mode 100644
index 0000000..da0510a
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NIST256;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/FP.java b/src/main/java/org/apache/milagro/amcl/NIST256/FP.java
new file mode 100644
index 0000000..88e7a49
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NIST256;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST256/ROM.java b/src/main/java/org/apache/milagro/amcl/NIST256/ROM.java
new file mode 100644
index 0000000..6cbdddf
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST256/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NIST256;
+
+public class ROM
+{
+
+// Base Bits= 56
+	public static final long[] Modulus= {0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFL,0x0L,0x1000000L,0xFFFFFFFFL};
+	public static final long[] R2modp= {0x3000000050000L,0x0L,0xFFFFFBFFFFFFFAL,0xFFFAFFFFFFFEFFL,0x2FFFFL};
+	public static final long MConst= 0x1L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 0;
+	public static final long[] CURVE_B= {0xCE3C3E27D2604BL,0x6B0CC53B0F63BL,0x55769886BC651DL,0xAA3A93E7B3EBBDL,0x5AC635D8L};
+	public static final long[] CURVE_Order= {0xB9CAC2FC632551L,0xFAADA7179E84F3L,0xFFFFFFFFFFBCE6L,0xFFFFFFL,0xFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0xA13945D898C296L,0x7D812DEB33A0F4L,0xE563A440F27703L,0xE12C4247F8BCE6L,0x6B17D1F2L};
+	public static final long[] CURVE_Gy= {0xB6406837BF51F5L,0x33576B315ECECBL,0x4A7C0F9E162BCEL,0xFE1A7F9B8EE7EBL,0x4FE342E2L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/BIG.java b/src/main/java/org/apache/milagro/amcl/NIST384/BIG.java
new file mode 100644
index 0000000..dab1864
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NIST384;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/DBIG.java b/src/main/java/org/apache/milagro/amcl/NIST384/DBIG.java
new file mode 100644
index 0000000..29a403d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NIST384;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/ECDH.java b/src/main/java/org/apache/milagro/amcl/NIST384/ECDH.java
new file mode 100644
index 0000000..93ef59c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NIST384;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/ECP.java b/src/main/java/org/apache/milagro/amcl/NIST384/ECP.java
new file mode 100644
index 0000000..c3bcfbd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NIST384;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=48;
+	public static final int AESKEY=24;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/FP.java b/src/main/java/org/apache/milagro/amcl/NIST384/FP.java
new file mode 100644
index 0000000..cd56e35
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NIST384;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=384; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<8);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST384/ROM.java b/src/main/java/org/apache/milagro/amcl/NIST384/ROM.java
new file mode 100644
index 0000000..94ca0e7
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST384/ROM.java
@@ -0,0 +1,44 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NIST384;
+
+public class ROM
+{
+
+// Base Bits= 56
+	public static final long[] Modulus= {0xFFFFFFFFL,0xFFFF0000000000L,0xFFFFFFFFFEFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] R2modp= {0xFE000000010000L,0xFFFFFFL,0x2L,0xFFFFFFFE00L,0x1000000020000L,0x0L,0x0L};
+	public static final long MConst= 0x100000001L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 0;
+	public static final long[] CURVE_B= {0x85C8EDD3EC2AEFL,0x398D8A2ED19D2AL,0x8F5013875AC656L,0xFE814112031408L,0xF82D19181D9C6EL,0xE7E4988E056BE3L,0xB3312FA7E23EL};
+	public static final long[] CURVE_Order= {0xEC196ACCC52973L,0xDB248B0A77AECL,0x81F4372DDF581AL,0xFFFFFFFFC7634DL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x545E3872760AB7L,0xF25DBF55296C3AL,0xE082542A385502L,0x8BA79B9859F741L,0x20AD746E1D3B62L,0x5378EB1C71EF3L,0xAA87CA22BE8BL};
+	public static final long[] CURVE_Gy= {0x431D7C90EA0E5FL,0xB1CE1D7E819D7AL,0x13B5F0B8C00A60L,0x289A147CE9DA31L,0x92DC29F8F41DBDL,0x2C6F5D9E98BF92L,0x3617DE4A9626L};
+
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/BIG.java b/src/main/java/org/apache/milagro/amcl/NIST521/BIG.java
new file mode 100644
index 0000000..1626fd9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NIST521;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=66; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/DBIG.java b/src/main/java/org/apache/milagro/amcl/NIST521/DBIG.java
new file mode 100644
index 0000000..08599a4
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NIST521;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/ECDH.java b/src/main/java/org/apache/milagro/amcl/NIST521/ECDH.java
new file mode 100644
index 0000000..8f58017
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NIST521;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/ECP.java b/src/main/java/org/apache/milagro/amcl/NIST521/ECP.java
new file mode 100644
index 0000000..80f3e05
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NIST521;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/FP.java b/src/main/java/org/apache/milagro/amcl/NIST521/FP.java
new file mode 100644
index 0000000..fa36640
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NIST521;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=521; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<19);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NIST521/ROM.java b/src/main/java/org/apache/milagro/amcl/NIST521/ROM.java
new file mode 100644
index 0000000..a7b4e42
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NIST521/ROM.java
@@ -0,0 +1,44 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NIST521;
+
+public class ROM
+{
+
+// Base Bits= 60
+	public static final long[] Modulus= {0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0x1FFFFFFFFFFL};
+	public static final long[] R2modp= {0x4000000000L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x1L;
+
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 0;
+	public static final long[] CURVE_B= {0xF451FD46B503F00L,0x73DF883D2C34F1EL,0x2C0BD3BB1BF0735L,0x3951EC7E937B165L,0x9918EF109E15619L,0x5B99B315F3B8B48L,0xB68540EEA2DA72L,0x8E1C9A1F929A21AL,0x51953EB961L};
+	public static final long[] CURVE_Order= {0xB6FB71E91386409L,0xB5C9B8899C47AEBL,0xC0148F709A5D03BL,0x8783BF2F966B7FCL,0xFFFFFFFFFFA5186L,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0x1FFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x97E7E31C2E5BD66L,0x48B3C1856A429BFL,0xDC127A2FFA8DE33L,0x5E77EFE75928FE1L,0xF606B4D3DBAA14BL,0x39053FB521F828AL,0x62395B4429C6481L,0x404E9CD9E3ECB6L,0xC6858E06B7L};
+	public static final long[] CURVE_Gy= {0x8BE94769FD16650L,0x3C7086A272C2408L,0xB9013FAD076135L,0x72995EF42640C55L,0xD17273E662C97EEL,0x49579B446817AFBL,0x42C7D1BD998F544L,0x9A3BC0045C8A5FBL,0x11839296A78L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/BIG.java
new file mode 100644
index 0000000..19f3da3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS256E;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/DBIG.java
new file mode 100644
index 0000000..0d7bec3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS256E;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/ECDH.java
new file mode 100644
index 0000000..32d8fa0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS256E;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/ECP.java
new file mode 100644
index 0000000..be85c68
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS256E;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/FP.java
new file mode 100644
index 0000000..1d61675
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS256E;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256E/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS256E/ROM.java
new file mode 100644
index 0000000..dada8b2
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256E/ROM.java
@@ -0,0 +1,42 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS256E;
+
+public class ROM
+{
+	public static final long[] Modulus= {0xFFFFFFFFFFFF43L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] R2modp= {0x89000000000000L,0x8BL,0x0L,0x0L,0x0L};
+	public static final long MConst= 0xBDL;
+
+	public static final int CURVE_Cof_I= 4;
+	public static final long[] CURVE_Cof= {0x4L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= 1;
+	public static final int CURVE_B_I= -15342;
+	public static final long[] CURVE_B= {0xFFFFFFFFFFC355L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] CURVE_Order= {0x47B190EEDD4AF5L,0x5AA52F59439B1AL,0x4195L,0x0L,0x40000000L};
+	public static final long[] CURVE_Gx= {0xDEC0902EED13DAL,0x8A0EE3083586A0L,0x5F69209BD60C39L,0x6AEA237DCD1E3DL,0x8A7514FBL};
+	public static final long[] CURVE_Gy= {0xA616E7798A89E6L,0x61D810856ED32FL,0xD9A64B8010715FL,0xD9D925C7CE9665L,0x44D53E9FL};
+
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/BIG.java
new file mode 100644
index 0000000..fd66263
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS256W;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/DBIG.java
new file mode 100644
index 0000000..96e3e03
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS256W;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/ECDH.java
new file mode 100644
index 0000000..19c3104
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS256W;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/ECP.java
new file mode 100644
index 0000000..20dd2f2
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS256W;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/FP.java
new file mode 100644
index 0000000..25d10bc
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS256W;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS256W/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS256W/ROM.java
new file mode 100644
index 0000000..1fa94d6
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS256W/ROM.java
@@ -0,0 +1,45 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS256W;
+
+public class ROM
+{
+
+// Modulus
+	public static final long[] Modulus= {0xFFFFFFFFFFFF43L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] R2modp= {0x89000000000000L,0x8BL,0x0L,0x0L,0x0L};
+	public static final long MConst= 0xBDL;
+
+// Curve
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 152961;
+	public static final long[] CURVE_B= {0x25581L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0xAB20294751A825L,0x8275EA265C6020L,0xFFFFFFFFFFE43CL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x52EE1EB21AACB1L,0x9B0903D4C73ABCL,0xA04F42CB098357L,0x5AAADB61297A95L,0xBC9ED6B6L};
+	public static final long[] CURVE_Gy= {0xB5B9CB2184DE9FL,0xC3D115310FBB80L,0xF77E04E035C955L,0x3399B6A673448BL,0xD08FC0F1L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/BIG.java
new file mode 100644
index 0000000..d8dfbb3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS384E;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/DBIG.java
new file mode 100644
index 0000000..88896bd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS384E;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/ECDH.java
new file mode 100644
index 0000000..23a4236
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS384E;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/ECP.java
new file mode 100644
index 0000000..f37a4c5
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS384E;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=48;
+	public static final int AESKEY=24;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/FP.java
new file mode 100644
index 0000000..45db06f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS384E;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=384; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<8);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384E/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS384E/ROM.java
new file mode 100644
index 0000000..54f142d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384E/ROM.java
@@ -0,0 +1,40 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS384E;
+
+public class ROM
+{
+// Base Bits= 56
+	public static final long[] Modulus= {0xFFFFFFFFFFFEC3L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] R2modp= {0x188890000L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x13DL;
+
+	public static final int CURVE_Cof_I= 4;
+	public static final long[] CURVE_Cof= {0x4L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= 1;
+	public static final int CURVE_B_I= -11556;
+	public static final long[] CURVE_B= {0xFFFFFFFFFFD19FL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] CURVE_Order= {0xB9DCC4E6A3897DL,0x555AAB35C87920L,0x1CB46BE1CF61E4L,0xFFFFFFFFE2471AL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0x3FFFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0xD540E46C206BDEL,0x92B16545941350L,0xA8F33163406FF2L,0xE5BE4C005763FFL,0xE55DB5B30BF446L,0x266CC0B6A2129AL,0x61B111FB45A9L};
+	public static final long[] CURVE_Gy= {0x8D03E1F0729392L,0xB0F946EC48DC9DL,0xF7F645964B0072L,0xF1425F56830F98L,0xB10DD716AD8274L,0xEEB08738B1A423L,0x82983E67B9A6L};
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/BIG.java
new file mode 100644
index 0000000..0f87234
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS384W;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/DBIG.java
new file mode 100644
index 0000000..fcc04fe
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS384W;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/ECDH.java
new file mode 100644
index 0000000..49b9ed1
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS384W;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/ECP.java
new file mode 100644
index 0000000..d9bce92
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS384W;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=48;
+	public static final int AESKEY=24;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/FP.java
new file mode 100644
index 0000000..5fbb4c3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS384W;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=384; /* Number of bits in Modulus */
+	public static final int MOD8=3;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<22);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS384W/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS384W/ROM.java
new file mode 100644
index 0000000..314efd0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS384W/ROM.java
@@ -0,0 +1,55 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS384W;
+
+public class ROM
+{
+/*
+// Base Bits= 56
+	public static final long[] Modulus= {0xFFFFFFFFFFFEC3L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] R2modp= {0x188890000L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x13DL;
+
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= -34568;
+	public static final long[] CURVE_B= {0xFFFFFFFFFF77BBL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] CURVE_Order= {0x4D81F67B0E61B9L,0x9D3D4C37E27A60L,0x1EEB5D6881BEDAL,0xFFFFFFFFD61EAFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x9CBA042098152AL,0xED100F61C47BEBL,0x1B2A6CC742522EL,0xFB81F9F4F3BD29L,0x5F1A60225C1CDL,0x181C4880CA2241L,0x757956F0B16FL};
+	public static final long[] CURVE_Gy= {0x74B8EC66180716L,0xB4DBBFF4AD265CL,0x7D121A837EBCD6L,0xF87F739CB92083L,0x84CF7EB0046977L,0x8E38D7E33D3005L,0xACDEE368E19BL};
+*/
+// Base Bits= 58
+	public static final long[] Modulus= {0x3FFFFFFFFFFFEC3L,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0xFFFFFFFFFL};
+	public static final long[] R2modp= {0x88900000000000L,0x6L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x13DL;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= -34568;
+	public static final long[] CURVE_B= {0x3FFFFFFFFFF77BBL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0xFFFFFFFFFL};
+	public static final long[] CURVE_Order= {0x4D81F67B0E61B9L,0x2A74F530DF89E98L,0x2F1EEB5D6881BEDL,0x3FFFFFFFFFF587AL,0x3FFFFFFFFFFFFFFL,0x3FFFFFFFFFFFFFFL,0xFFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0x39CBA042098152AL,0x3BB4403D8711EFAL,0x291B2A6CC742522L,0x337EE07E7D3CEF4L,0x24105F1A60225C1L,0x5BC60712203288L,0x757956F0BL};
+	public static final long[] CURVE_Gy= {0x74B8EC66180716L,0x1AD36EFFD2B4997L,0x37D121A837EBCDL,0x1DFE1FDCE72E482L,0x584CF7EB00469L,0x66E38E35F8CF4CL,0xACDEE368EL};
+
+
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/BIG.java
new file mode 100644
index 0000000..fc4e029
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS512E;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=64; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/DBIG.java
new file mode 100644
index 0000000..4a4547c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS512E;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/ECDH.java
new file mode 100644
index 0000000..7f59cc8
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS512E;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/ECP.java
new file mode 100644
index 0000000..73a5515
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS512E;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=EDWARDS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/FP.java
new file mode 100644
index 0000000..1914efe
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS512E;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=512; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<30);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512E/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS512E/ROM.java
new file mode 100644
index 0000000..32f63a3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512E/ROM.java
@@ -0,0 +1,40 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS512E;
+
+public class ROM
+{
+// Base Bits= 56
+	public static final long[] Modulus= {0xFFFFFFFFFFFDC7L,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFL};
+	public static final long[] R2modp= {0x0L,0xF0B10000000000L,0x4L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x239L;
+
+	public static final int CURVE_Cof_I= 4;
+	public static final long[] CURVE_Cof= {0x4L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= 1;
+	public static final int CURVE_B_I= -78296;
+	public static final long[] CURVE_B= {0xFFFFFFFFFECBEFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFL};
+	public static final long[] CURVE_Order= {0x468CF51BEED46DL,0x5786DEFECFF67L,0xC970B686F52A46L,0x2FCF91BA9E3FD8L,0xFFFFFFB4F0636DL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0x3FL};
+	public static final long[] CURVE_Gx= {0xB9AB2999EC57FEL,0x25427CC4F015C5L,0x92568904AD0FE5L,0xEE46730F78BDC9L,0x3B81474621C14EL,0xA38227A17EBE27L,0x332FD1E79F4DC4L,0x7A18CB7888D3C5L,0x8E316D128DB69CL,0xDFL};
+	public static final long[] CURVE_Gy= {0x6DDEC0C1E2F5E1L,0xD38A9BF1D01F32L,0x862AECC1FD0266L,0xE9963562601A06L,0x9E834120CA53F2L,0x9D22A92B6B9590L,0x6EE476F726D825L,0x98B0F577A82A25L,0x9BFF39D49CA71L,0x6DL};
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/BIG.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/BIG.java
new file mode 100644
index 0000000..1ab5814
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.NUMS512W;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=64; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/DBIG.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/DBIG.java
new file mode 100644
index 0000000..c515656
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.NUMS512W;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/ECDH.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/ECDH.java
new file mode 100644
index 0000000..8d59730
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.NUMS512W;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/ECP.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/ECP.java
new file mode 100644
index 0000000..7cbac93
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.NUMS512W;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=64;
+	public static final int AESKEY=32;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/FP.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/FP.java
new file mode 100644
index 0000000..053b739
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.NUMS512W;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=512; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=PSEUDO_MERSENNE;
+
+	public static final int FEXCESS =((int)1<<28);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/NUMS512W/ROM.java b/src/main/java/org/apache/milagro/amcl/NUMS512W/ROM.java
new file mode 100644
index 0000000..ef267dc
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/NUMS512W/ROM.java
@@ -0,0 +1,41 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.NUMS512W;
+
+public class ROM
+{
+
+// Base Bits= 60
+	public static final long[] Modulus= {0xFFFFFFFFFFFFDC7L,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] R2modp= {0x100000000000000L,0x4F0BL,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long MConst= 0x239L;
+
+	public static final int CURVE_Cof_I= 1;
+	public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final int CURVE_A= -3;
+	public static final int CURVE_B_I= 121243;
+	public static final long[] CURVE_B= {0x1D99BL,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L,0x0L};
+	public static final long[] CURVE_Order= {0xE153F390433555DL,0x568B36607CD243CL,0x258ED97D0BDC63BL,0xA4FB94E7831B4FCL,0xFFFFFFFFFFF5B3CL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+	public static final long[] CURVE_Gx= {0xC8287958CABAE57L,0x5D60137D6F5DE2DL,0x94286255615831DL,0xA151076B359E937L,0xC25306D9F95021L,0x3BB501F6854506EL,0x2A03D3B5298CAD8L,0x141D0A93DA2B700L,0x3AC03447L};
+	public static final long[] CURVE_Gy= {0x3A08760383527A6L,0x2B5C1E4CFD0FE92L,0x1A840B25A5602CFL,0x15DA8B0EEDE9C12L,0x60C7BD14F14A284L,0xDEABBCBB8C8F4B2L,0xC63EBB1004B97DBL,0x29AD56B3CE0EEEDL,0x943A54CAL};
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RAND.java b/src/main/java/org/apache/milagro/amcl/RAND.java
new file mode 100644
index 0000000..7ba7064
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RAND.java
@@ -0,0 +1,163 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ *   Cryptographic strong random number generator 
+ *
+ *   Unguessable seed -> SHA -> PRNG internal state -> SHA -> random numbers
+ *   Slow - but secure
+ *
+ *   See ftp://ftp.rsasecurity.com/pub/pdfs/bull-1.pdf for a justification
+ */
+
+/* Marsaglia & Zaman Random number generator constants */
+
+
+package org.apache.milagro.amcl;
+
+public class RAND {
+/* Cryptographically strong pseudo-random number generator */
+
+	private static final int NK=21;
+	private static final int NJ=6;
+	private static final int NV=8;
+	private int[] ira=new int[NK];  /* random number...   */
+	private int rndptr;   /* ...array & pointer */
+	private int borrow;
+	private int pool_ptr;
+	private byte[] pool=new byte[32];    /* random pool */
+
+	public RAND()
+	{
+		clean();
+	}
+
+	private int sbrand()
+	{ /* Marsaglia & Zaman random number generator */
+		int i,k;
+		long pdiff,t;
+
+		rndptr++;
+		if (rndptr<NK) return ira[rndptr];
+		rndptr=0;
+		for (i=0,k=NK-NJ;i<NK;i++,k++)
+		{ /* calculate next NK values */
+			if (k==NK) k=0;
+			t=((long)ira[k])&0xffffffffL;
+			pdiff=(t - (((long)ira[i])&0xffffffffL) - (long)borrow)&0xffffffffL;
+			if (pdiff<t) borrow=0;
+			if (pdiff>t) borrow=1;
+			ira[i]=(int)(pdiff&0xffffffffL); 
+		}
+
+		return ira[0];
+	}
+
+	public void sirand(int seed)
+	{
+		int i,in;
+		int t,m=1;
+		borrow=0;
+		rndptr=0;
+		ira[0]^=seed;
+		for (i=1;i<NK;i++)
+		{ /* fill initialisation vector */
+			in=(NV*i)%NK;
+			ira[in]^=m;      /* note XOR */
+			t=m;
+			m=seed-m;
+			seed=t;
+		}
+		for (i=0;i<10000;i++) sbrand(); /* "warm-up" & stir the generator */
+	}
+
+	private void fill_pool()
+	{
+		HASH256 sh=new HASH256();
+		for (int i=0;i<128;i++) sh.process(sbrand());
+		pool=sh.hash();
+		pool_ptr=0;
+	}
+
+	private static int pack(byte[] b)
+	{ /* pack 4 bytes into a 32-bit Word */
+		return ((((int)b[3])&0xff)<<24)|(((int)b[2]&0xff)<<16)|(((int)b[1]&0xff)<<8)|((int)b[0]&0xff);
+	}
+
+/* Initialize RNG with some real entropy from some external source */
+	public void seed(int rawlen,byte[] raw)
+	{ /* initialise from at least 128 byte string of raw random entropy */
+		int i;
+		byte [] digest;
+		byte [] b=new byte[4];
+		HASH256 sh=new HASH256();
+		pool_ptr=0;
+		for (i=0;i<NK;i++) ira[i]=0;
+		if (rawlen>0)
+		{
+			for (i=0;i<rawlen;i++)
+				sh.process(raw[i]);
+			digest=sh.hash();
+
+/* initialise PRNG from distilled randomness */
+
+			for (i=0;i<8;i++) 
+			{
+				b[0]=digest[4*i]; b[1]=digest[4*i+1]; b[2]=digest[4*i+2]; b[3]=digest[4*i+3];
+				sirand(pack(b));
+			}
+		}
+		fill_pool();
+	}
+
+/* Terminate and clean up */
+	public void clean()
+	{ /* kill internal state */
+		int i;
+		pool_ptr=rndptr=0;
+		for (i=0;i<32;i++) pool[i]=0;
+		for (i=0;i<NK;i++) ira[i]=0;
+		borrow=0;
+	}
+
+/* get random byte */
+	public int getByte()
+	{ 
+		int r;
+		r=pool[pool_ptr++];
+		if (pool_ptr>=32) fill_pool();
+		return (r&0xff);
+	}
+
+/* test main program */
+/*
+	public static void main(String[] args) {
+		int i;
+		byte[] raw=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (i=0;i<100;i++) raw[i]=(byte)i;
+
+		rng.seed(100,raw);
+ 
+		for (i=0;i<1000;i++)
+			System.out.format("%03d ",rng.getByte());
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/BIG.java b/src/main/java/org/apache/milagro/amcl/RSA2048/BIG.java
new file mode 100644
index 0000000..fad9376
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.RSA2048;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=128; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=58; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/DBIG.java b/src/main/java/org/apache/milagro/amcl/RSA2048/DBIG.java
new file mode 100644
index 0000000..f12d682
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.RSA2048;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/FF.java b/src/main/java/org/apache/milagro/amcl/RSA2048/FF.java
new file mode 100644
index 0000000..9dd820c
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/FF.java
@@ -0,0 +1,1028 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Large Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.RSA2048;
+import org.apache.milagro.amcl.RAND;
+
+public final class FF {
+
+/* RSA/DH modulus length as multiple of BIGBITS */
+	public static final int FFLEN=2;
+
+/* Don't Modify from here... */
+
+
+/* Finite field support - for RSA, DH etc. */
+	public static final int FF_BITS=(BIG.BIGBITS*FFLEN); /* Finite Field Size in bits - must be 256.2^n */
+	public static final int HFLEN=(FFLEN/2);  /* Useful for half-size RSA private key operations */
+
+	public static final int P_MBITS=BIG.MODBYTES*8;
+	public static final int P_TBITS=(P_MBITS%BIG.BASEBITS);
+
+	private final BIG[] v;
+	private final int length;
+
+/**************** 64-bit specific ************************/
+
+	public static final long P_OMASK=((long)(-1)<<(P_MBITS%BIG.BASEBITS));
+	public static final long P_FEXCESS=((long)1<<(BIG.BASEBITS*BIG.NLEN-P_MBITS-1));
+
+	public static long EXCESS(BIG a)
+	{
+		return ((a.get(BIG.NLEN-1)&P_OMASK)>>(P_TBITS))+1;
+	}
+
+/* Check if product causes excess */
+	public static boolean pexceed(BIG a,BIG b)
+	{
+		long ea,eb;
+		ea=EXCESS(a);
+		eb=EXCESS(b);
+		if ((ea+1)>P_FEXCESS/(eb+1)) return true;
+		return false;
+	}
+
+/* Check if square causes excess */
+	public static boolean sexceed(BIG a)
+	{
+		long ea;
+		ea=EXCESS(a);
+		if ((ea+1)>P_FEXCESS/(ea+1)) return true;
+		return false;
+	}
+
+/******************************************************/
+
+/* Constructors */
+	public FF(int n)
+	{
+		v=new BIG[n];
+		for (int i=0;i<n;i++)
+			v[i]=new BIG(0);
+		length=n;
+	}
+
+	public int getlen()
+	{
+		return length;
+	}
+
+/* set to integer */
+	public void set(int m)
+	{
+		zero();
+		v[0].set(0,(m&BIG.BMASK));
+		v[0].set(1,(m>>BIG.BASEBITS));
+	}
+
+/* copy from FF b */
+	public void copy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[i]);
+		}
+	}
+
+/* x=y<<n */
+	public void dsucopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[b.length+i].copy(b.v[i]);
+			v[i].zero();
+		}
+	}
+
+/* x=y */
+	public void dscopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[i].copy(b.v[i]);
+			v[b.length+i].zero();
+		}
+	}
+
+/* x=y>>n */
+	public void sducopy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[length+i]);
+		}
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+	public void one()
+	{
+		v[0].one();
+		for (int i=1;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+/* test equals 0 */
+	public boolean iszilch() 
+	{
+		for (int i=0;i<length;i++)
+		{
+			if (!v[i].iszilch()) return false;
+		}
+		return true;
+	}
+
+/* shift right by BIGBITS-bit words */
+	public void shrw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[i].copy(v[i+n]);
+			v[i+n].zero();
+		}
+	}
+
+/* shift left by BIGBITS-bit words */
+	public void shlw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[n+i].copy(v[i]);
+			v[i].zero();
+		}
+	}
+
+/* extract last bit */
+	public int parity()
+	{
+		return v[0].parity();
+	}
+
+	public int lastbits(int m)
+	{
+		return v[0].lastbits(m);
+	}
+
+/* compare x and y - must be normalised, and of same length */
+	public static int comp(FF a,FF b)
+	{
+		int i,j;
+		for (i=a.length-1;i>=0;i--)
+		{
+			j=BIG.comp(a.v[i],b.v[i]);
+			if (j!=0) return j;
+		}
+		return 0;
+	}
+
+/* recursive add */
+	public void radd(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive inc */
+	public void rinc(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive sub */
+	public void rsub(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* recursive dec */
+	public void rdec(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* simple add */
+	public void add(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].add(b.v[i]);
+	}
+
+/* simple sub */
+	public void sub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].sub(b.v[i]);
+	}
+	
+/* reverse sub */
+	public void revsub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].rsub(b.v[i]);
+	}
+
+/* increment/decrement by a small integer */
+	public void inc(int m)
+	{
+		v[0].inc(m);
+		norm();
+	}
+
+	public void dec(int m)
+	{
+		v[0].dec(m);
+		norm();
+	}
+
+	/* normalise - but hold any overflow in top part unless n<0 */
+	private void rnorm(int vp,int n)
+	{
+		boolean trunc=false;
+		int i;
+		long carry;
+		if (n<0)
+		{ /* -v n signals to do truncation */
+			n=-n;
+			trunc=true;
+		}
+		for (i=0;i<n-1;i++)
+		{
+			carry=v[vp+i].norm();  
+			v[vp+i].xortop(carry<<P_TBITS);
+			v[vp+i+1].incl(carry);
+		}
+		carry=v[vp+n-1].norm();
+		if (trunc) 
+			v[vp+n-1].xortop(carry<<P_TBITS);
+	}
+
+	public void norm()
+	{
+		rnorm(0,length);
+	}
+
+/* shift left by one bit */
+	public void shl()
+	{
+		int i,carry,delay_carry=0;
+		for (i=0;i<length-1;i++)
+		{
+			carry=v[i].fshl(1);
+			v[i].inc(delay_carry);
+			v[i].xortop((long)carry<<P_TBITS);
+			delay_carry=carry;
+		}
+		v[length-1].fshl(1);
+		v[length-1].inc(delay_carry);
+	}
+
+/* shift right by one bit */
+
+	public void shr()
+	{
+		int carry;
+		for (int i=length-1;i>0;i--)
+		{
+			carry=v[i].fshr(1);
+			v[i-1].xortop((long)carry<<P_TBITS);
+		}
+		v[0].fshr(1);
+	}
+
+/* Convert to Hex String */
+	public String toString() 
+	{
+		norm();
+		String s="";
+		for (int i=length-1;i>=0;i--)
+		{
+			s+=v[i].toString(); //s+=" ";
+		}
+		return s;
+	}
+
+/*
+	public String toRawString(int len) 
+	{
+	//	norm(len);
+		String s="";
+		for (int i=len-1;i>=0;i--)
+		{
+			s+=v[i].toRawString(); s+=" ";
+		}
+		return s;
+	}
+*/
+/* Convert FFs to/from byte arrays */
+	public void toBytes(byte[] b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].tobytearray(b,(length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+	public static void fromBytes(FF x,byte[] b)
+	{
+		for (int i=0;i<x.length;i++)
+		{
+			x.v[i]=BIG.frombytearray(b,(x.length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+/* in-place swapping using xor - side channel resistant - lengths must be the same */
+	private static void cswap(FF a,FF b,int d)
+	{
+		for (int i=0;i<a.length;i++)
+		{
+		//	BIG.cswap(a.v[i],b.v[i],d);
+			a.v[i].cswap(b.v[i],d);
+		}
+	}
+
+/* z=x*y, t is workspace */
+	private void karmul(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			y.v[yp].norm();
+			DBIG d=BIG.mul(x.v[xp],y.v[yp]);
+			v[vp+1]=d.split(8*BIG.MODBYTES);
+			v[vp].copy(d);
+			return;
+		}
+		nd2=n/2;
+		radd(vp,x,xp,x,xp+nd2,nd2);
+		rnorm(vp,nd2);                   /* Important - required for 32-bit build */
+		radd(vp+nd2,y,yp,y,yp+nd2,nd2);
+		rnorm(vp+nd2,nd2);               /* Important - required for 32-bit build */
+
+		t.karmul(tp,this,vp,this,vp+nd2,t,tp+n,nd2);
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		karmul(vp+n,x,xp+nd2,y,yp+nd2,t,tp+n,nd2);
+		t.rdec(tp,this,vp,n);
+		t.rdec(tp,this,vp+n,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp,2*n);
+	}
+
+	private void karsqr(int vp,FF x,int xp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			DBIG d=BIG.sqr(x.v[xp]);
+			v[vp+1].copy(d.split(8*BIG.MODBYTES));
+			v[vp].copy(d);
+			return;
+		}	
+
+		nd2=n/2;
+		karsqr(vp,x,xp,t,tp+n,nd2);
+		karsqr(vp+n,x,xp+nd2,t,tp+n,nd2);
+		t.karmul(tp,x,xp,x,xp+nd2,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp+nd2,n);
+	}
+
+
+	private void karmul_lower(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{ /* Calculates Least Significant bottom half of x*y */
+		int nd2;
+		if (n==1)
+		{ /* only calculate bottom half of product */
+			v[vp].copy(BIG.smul(x.v[xp],y.v[yp]));
+			return;
+		}
+		nd2=n/2;
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		t.karmul_lower(tp,x,xp+nd2,y,yp,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,nd2);
+		t.karmul_lower(tp,x,xp,y,yp+nd2,t,tp+n,nd2);
+
+		rinc(vp+nd2,t,tp,nd2);
+		rnorm(vp+nd2,-nd2);  /* truncate it */
+	}
+
+	private void karmul_upper(FF x,FF y,FF t,int n)
+	{ /* Calculates Most Significant upper half of x*y, given lower part */
+		int nd2;
+ 
+		nd2=n/2;
+		radd(n,x,0,x,nd2,nd2);
+		radd(n+nd2,y,0,y,nd2,nd2);
+		rnorm(n,nd2);
+		rnorm(n+nd2,nd2);
+
+		t.karmul(0,this,n+nd2,this,n,t,n,nd2);  /* t = (a0+a1)(b0+b1) */
+		karmul(n,x,nd2,y,nd2,t,n,nd2); /* z[n]= a1*b1 */
+									/* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */
+		t.rdec(0,this,n,n);              /* t=t-a1b1  */
+		rinc(nd2,this,0,nd2);   /* z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1)  */
+		rdec(nd2,t,0,nd2);   /* z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) */
+		rnorm(0,-n);					/* a0b0 now in z - truncate it */
+		t.rdec(0,this,0,n);         /* (a0+a1)(b0+b1) - a0b0 */
+		rinc(nd2,t,0,n);
+
+		rnorm(nd2,n);
+	}
+
+	/* z=x*y. Assumes x and y are of same length. */
+	public static FF mul(FF x,FF y)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); y.norm();
+		z.karmul(0,x,0,y,0,t,0,n);
+		return z;
+	}
+
+	/* z=x^2 */
+	public static FF sqr(FF x)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); 
+		z.karsqr(0,x,0,t,0,n);
+		return z;
+	}
+
+/* return low part of product this*y */
+	public void lmul(FF y)
+	{
+		int n=length;
+		FF t=new FF(2*n);
+		FF x=new FF(n); x.copy(this);
+//		x.norm(); y.norm();
+		karmul_lower(0,x,0,y,0,t,0,n);
+	}
+
+/* Set b=b mod c */
+	public void mod(FF c)
+	{
+		int k=0;  
+
+		norm();
+		if (comp(this,c)<0) 
+			return;
+		do
+		{
+			c.shl();
+			k++;
+		} while (comp(this,c)>=0);
+
+		while (k>0)
+		{
+			c.shr();
+			if (comp(this,c)>=0)
+			{
+				sub(c);
+				norm();
+			}
+			k--;
+		}
+	}
+
+/* return This mod modulus, N is modulus, ND is Montgomery Constant */
+	public FF reduce(FF N,FF ND)
+	{ /* fast karatsuba Montgomery reduction */
+		int n=N.length;
+		FF t=new FF(2*n);
+		FF r=new FF(n);
+		FF m=new FF(n);
+
+		r.sducopy(this);
+		m.karmul_lower(0,this,0,ND,0,t,0,n);
+		karmul_upper(N,m,t,n);
+		m.sducopy(this);
+
+		r.add(N);
+		r.sub(m);
+		r.norm();
+
+		return r;
+	}
+
+/* Set r=this mod b */
+/* this is of length - 2*n */
+/* r,b is of length - n */
+	public FF dmod(FF b)
+	{
+		int k,n=b.length;
+		FF m=new FF(2*n);
+		FF x=new FF(2*n);
+		FF r=new FF(n);
+
+		x.copy(this);
+		x.norm();
+		m.dsucopy(b); k=BIG.BIGBITS*n;
+
+		while (comp(x,m)>=0)
+		{
+			x.sub(m);
+			x.norm();
+		}
+
+		while (k>0)
+		{	
+			m.shr();
+
+			if (comp(x,m)>=0)
+			{
+				x.sub(m);
+				x.norm();
+			}
+			k--;
+		}
+
+		r.copy(x);
+		r.mod(b);
+		return r;
+	}
+
+/* Set return=1/this mod p. Binary method - a<p on entry */
+
+	public void invmodp(FF p)
+	{
+		int n=p.length;
+
+		FF u=new FF(n);
+		FF v=new FF(n);
+		FF x1=new FF(n);
+		FF x2=new FF(n);
+		FF t=new FF(n);
+		FF one=new FF(n);
+
+		one.one();
+		u.copy(this);
+		v.copy(p);
+		x1.copy(one);
+		x2.zero();
+
+	// reduce n in here as well! 
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.shr();
+				if (x1.parity()!=0)
+				{
+					x1.add(p); 
+					x1.norm();
+				}
+				x1.shr(); 
+			}
+			while (v.parity()==0)
+			{
+				v.shr(); 
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.shr();
+			}
+			if (comp(u,v)>=0)
+			{
+
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0)
+			copy(x1);
+		else
+			copy(x2);
+	}
+
+/* nresidue mod m */
+	public void nres(FF m)
+	{
+		int n=m.length;
+		if (n==1)
+		{ 
+			DBIG d=new DBIG(this.v[0]);
+			d.shl(BIG.NLEN*BIG.BASEBITS);
+			this.v[0].copy(d.mod(m.v[0]));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			d.dsucopy(this);
+			copy(d.dmod(m));
+		}
+	}
+
+	public void redc(FF m,FF ND)
+	{
+		int n=m.length;
+		if (n==1)
+		{
+			DBIG d=new DBIG(this.v[0]);
+			this.v[0].copy(BIG.monty(m.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-ND.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			mod(m);
+			d.dscopy(this);
+			copy(d.reduce(m,ND));
+			mod(m);
+		}
+	}
+
+	private void mod2m(int m)
+	{
+		for (int i=m;i<length;i++)
+			v[i].zero();
+	}
+
+	/* U=1/a mod 2^m - Arazi & Qi */
+	private FF invmod2m()
+	{
+		int i,n=length;
+
+		FF b=new FF(n);
+		FF c=new FF(n);
+		FF U=new FF(n);
+		FF t;
+
+		U.zero();
+		U.v[0].copy(v[0]);
+		U.v[0].invmod2m();
+
+		for (i=1;i<n;i<<=1)
+		{
+			b.copy(this); b.mod2m(i);
+			t=mul(U,b);
+
+			t.shrw(i); b.copy(t);
+			c.copy(this); c.shrw(i); c.mod2m(i);
+			c.lmul(U); c.mod2m(i);
+
+			b.add(c); b.norm();
+			b.lmul(U); b.mod2m(i);
+
+			c.one(); c.shlw(i); b.revsub(c); b.norm();
+			b.shlw(i);
+			U.add(b);
+		}
+		U.norm();
+		return U;
+	}
+
+	public void random(RAND rng)
+	{
+		int n=length;
+		for (int i=0;i<n;i++)
+		{
+			v[i].copy(BIG.random(rng));
+		}
+	/* make sure top bit is 1 */
+		while (v[n-1].nbits()<BIG.MODBYTES*8) v[n-1].copy(BIG.random(rng));
+	}
+
+	/* generate random x */
+	public void randomnum(FF p,RAND rng)
+	{
+		int n=length;
+		FF d=new FF(2*n);
+
+		for (int i=0;i<2*n;i++)
+		{
+			d.v[i].copy(BIG.random(rng));
+		}
+		copy(d.dmod(p));
+	}
+
+	/* this*=y mod p */
+	public void modmul(FF y,FF p,FF nd)
+	{
+		if (pexceed(v[length-1],y.v[y.length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.mul(this.v[0],y.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=mul(this,y);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this*=y mod p */
+	public void modsqr(FF p,FF nd)
+	{
+		if (sexceed(v[length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.sqr(this.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+
+		}
+		else
+		{
+			FF d=sqr(this);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */
+	public void skpow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
+	public void skpow(BIG e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			b=e.bit(i);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* raise to an integer power - right-to-left method */
+	public void power(int e,FF p)
+	{
+		int n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+		boolean f=true;
+
+		w.copy(this);
+		w.nres(p);
+
+		if (e==2)
+		{
+			copy(w);
+			modsqr(p,ND);
+		}
+		else for (; ; )
+		{
+			if (e%2==1)
+			{
+				if (f) copy(w);
+				else modmul(w,p,ND);
+				f=false;
+			}
+			e>>=1;
+			if (e==0) break;
+			w.modsqr(p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* this=this^e mod p, faster but not side channel resistant */
+	public void pow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+
+		w.copy(this);
+		one();
+		nres(p);
+		w.nres(p);
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			modsqr(p,ND);
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			if (b==1) modmul(w,p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* double exponentiation r=x^e.y^f mod p */
+	public void pow2(BIG e,FF y,BIG f,FF p)
+	{
+		int i,eb,fb,n=p.length;
+		FF xn=new FF(n);
+		FF yn=new FF(n);
+		FF xy=new FF(n);
+		FF ND=p.invmod2m();
+
+		xn.copy(this);
+		yn.copy(y);
+		xn.nres(p);
+		yn.nres(p);
+		xy.copy(xn); xy.modmul(yn,p,ND);
+		one();
+		nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			eb=e.bit(i);
+			fb=f.bit(i);
+			modsqr(p,ND);
+			if (eb==1)
+			{
+				if (fb==1) modmul(xy,p,ND);
+				else modmul(xn,p,ND);
+			}
+			else
+			{
+				if (fb==1) modmul(yn,p,ND);
+			}
+		}
+		redc(p,ND);
+	}
+
+	private static int igcd(int x,int y)
+	{ /* integer GCD, returns GCD of x and y */
+		int r;
+		if (y==0) return x;
+		while ((r=x%y)!=0)
+			{x=y;y=r;}
+		return y;
+	}
+
+	/* quick and dirty check for common factor with n */
+	public boolean cfactor(int s)
+	{
+		int r,n=length;
+		int g;
+
+		FF x=new FF(n);
+		FF y=new FF(n);
+
+		y.set(s);
+		x.copy(this);
+		x.norm();
+
+		do
+		{
+			x.sub(y);
+			x.norm();
+			while (!x.iszilch() && x.parity()==0) x.shr();
+		}
+		while (comp(x,y)>0);
+
+		g=(int)x.v[0].get(0);
+		r=igcd(s,g);
+		if (r>1) return true;
+		return false;
+	}
+
+	/* Miller-Rabin test for primality. Slow. */
+	public static boolean prime(FF p,RAND rng)
+	{
+		int i,j,s=0,n=p.length;
+		boolean loop;
+		FF d=new FF(n);
+		FF x=new FF(n);
+		FF unity=new FF(n);
+		FF nm1=new FF(n);
+
+		int sf=4849845; /* 3*5*.. *19 */
+		p.norm();
+
+		if (p.cfactor(sf)) return false;
+		unity.one();
+		nm1.copy(p);
+		nm1.sub(unity);
+		nm1.norm();
+		d.copy(nm1);
+
+		while (d.parity()==0)
+		{
+			d.shr();
+			s++;
+		}
+		if (s==0) return false;
+		for (i=0;i<10;i++)
+		{
+			x.randomnum(p,rng);
+			x.pow(d,p);
+
+			if (comp(x,unity)==0 || comp(x,nm1)==0) continue;
+			loop=false;
+			for (j=1;j<s;j++)
+			{
+				x.power(2,p);
+				if (comp(x,unity)==0) return false;
+				if (comp(x,nm1)==0) {loop=true; break;}
+			}
+			if (loop) continue;
+			return false;
+		}
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/RSA.java b/src/main/java/org/apache/milagro/amcl/RSA2048/RSA.java
new file mode 100644
index 0000000..73609d0
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/RSA.java
@@ -0,0 +1,369 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* RSA API high-level functions  */
+
+package org.apache.milagro.amcl.RSA2048;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+
+public final class RSA {
+
+	public static final int RFS=BIG.MODBYTES*FF.FFLEN;
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=SHA256;
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,byte[] A,int n)
+	{
+		byte[] R=null;
+
+		if (sha==SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		return R;
+	}
+
+/* generate an RSA key pair */
+
+	public static void KEY_PAIR(RAND rng,int e,private_key PRIV,public_key PUB)
+	{ /* IEEE1363 A16.11/A16.12 more or less */
+
+		int n=PUB.n.getlen()/2;
+		FF t = new FF(n);
+		FF p1=new FF(n);
+		FF q1=new FF(n);
+
+		for (;;)
+		{
+			PRIV.p.random(rng);
+			while (PRIV.p.lastbits(2)!=3) PRIV.p.inc(1);
+			while (!FF.prime(PRIV.p,rng)) PRIV.p.inc(4);
+
+			p1.copy(PRIV.p);
+			p1.dec(1);
+
+			if (p1.cfactor(e)) continue;
+			break;
+		}
+
+		for (;;)
+		{
+			PRIV.q.random(rng);
+			while (PRIV.q.lastbits(2)!=3) PRIV.q.inc(1);
+			while (!FF.prime(PRIV.q,rng)) PRIV.q.inc(4);
+			
+			q1.copy(PRIV.q);
+			q1.dec(1);
+
+			if (q1.cfactor(e)) continue;
+
+			break;
+		}
+
+		PUB.n=FF.mul(PRIV.p,PRIV.q);
+		PUB.e=e;
+
+		t.copy(p1);
+		t.shr();
+		PRIV.dp.set(e);
+		PRIV.dp.invmodp(t);
+		if (PRIV.dp.parity()==0) PRIV.dp.add(t);
+		PRIV.dp.norm();
+
+		t.copy(q1);
+		t.shr();
+		PRIV.dq.set(e);
+		PRIV.dq.invmodp(t);
+		if (PRIV.dq.parity()==0) PRIV.dq.add(t);
+		PRIV.dq.norm();
+
+		PRIV.c.copy(PRIV.p);
+		PRIV.c.invmodp(PRIV.q);
+
+		return;
+	}
+
+/* Mask Generation Function */
+
+	public static void MGF1(int sha,byte[] Z,int olen,byte[] K)
+	{
+		int hlen=sha;
+		byte[] B;
+
+		int counter,cthreshold,k=0;
+
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}	
+	}
+
+	public static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}  
+
+
+
+/* SHARSA2048 identifier strings */
+	private static final byte[] SHA256ID={0x30,0x31,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
+	private static final byte[] SHA384ID={0x30,0x41,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30};
+	private static final byte[] SHA512ID={0x30,0x51,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40};
+
+/* PKCS 1.5 padding of a message to be signed */
+
+	public static boolean PKCS15(int sha,byte[] m,byte[] w)
+	{
+		int olen=FF.FF_BITS/8;
+		int i,hlen=sha;
+		int idlen=19; 
+
+		if (olen<idlen+hlen+10) return false;
+		byte[] H=hashit(sha,m,-1);
+
+		for (i=0;i<w.length;i++) w[i]=0;
+		i=0;
+		w[i++]=0;
+		w[i++]=1;
+		for (int j=0;j<olen-idlen-hlen-3;j++)
+			w[i++]=(byte)0xff;
+		w[i++]=0;
+
+
+		if (hlen==SHA256) for (int j=0;j<idlen;j++) w[i++]=SHA256ID[j];
+		if (hlen==SHA384) for (int j=0;j<idlen;j++) w[i++]=SHA384ID[j];
+		if (hlen==SHA512) for (int j=0;j<idlen;j++) w[i++]=SHA512ID[j];
+
+		for (int j=0;j<hlen;j++)
+			w[i++]=H[j];
+
+		return true;
+	}
+
+
+	/* OAEP Message Encoding for Encryption */
+	public static byte[] OAEP_ENCODE(int sha,byte[] m,RAND rng,byte[] p)
+	{ 
+		int i,slen,olen=RFS-1;
+		int mlen=m.length;
+		int hlen,seedlen;
+		byte[] f=new byte[RFS];
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+
+		if (mlen>olen-hlen-seedlen-1) return new byte[0]; 
+
+		byte[] DBMASK=new byte[olen-seedlen];
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) f[i]=h[i];
+
+		slen=olen-mlen-hlen-seedlen-1;      
+
+		for (i=0;i<slen;i++) f[hlen+i]=0;
+		f[hlen+slen]=1;
+		for (i=0;i<mlen;i++) f[hlen+slen+1+i]=m[i];
+
+		for (i=0;i<seedlen;i++) SEED[i]=(byte)rng.getByte();
+
+		MGF1(sha,SEED,olen-seedlen,DBMASK);
+
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		MGF1(sha,DBMASK,seedlen,f);
+
+		for (i=0;i<seedlen;i++) f[i]^=SEED[i];
+
+		for (i=0;i<olen-seedlen;i++) f[i+seedlen]=DBMASK[i];
+
+		/* pad to length RFS */
+		int d=1;
+		for (i=RFS-1;i>=d;i--)
+			f[i]=f[i-d];
+		for (i=d-1;i>=0;i--)
+			f[i]=0;
+
+		return f;
+	}
+
+	/* OAEP Message Decoding for Decryption */
+	public static byte[] OAEP_DECODE(int sha,byte[] p,byte[] f)
+	{
+		int x,t;
+		boolean comp;
+		int i,k,olen=RFS-1;
+		int hlen,seedlen;
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+		byte[] CHASH=new byte[hlen];
+	
+		if (olen<seedlen+hlen+1) return new byte[0];
+		byte[] DBMASK=new byte[olen-seedlen];
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		if (f.length<RFS)
+		{
+			int d=RFS-f.length;
+			for (i=RFS-1;i>=d;i--)
+				f[i]=f[i-d];
+			for (i=d-1;i>=0;i--)
+				f[i]=0;
+
+		}
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) CHASH[i]=h[i];
+
+		x=f[0];
+
+		for (i=seedlen;i<olen;i++)
+			DBMASK[i-seedlen]=f[i+1]; 
+
+		MGF1(sha,DBMASK,seedlen,SEED);
+		for (i=0;i<seedlen;i++) SEED[i]^=f[i+1];
+		MGF1(sha,SEED,olen-seedlen,f);
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		comp=true;
+		for (i=0;i<hlen;i++)
+		{
+			if (CHASH[i]!=DBMASK[i]) comp=false;
+		}
+
+		for (i=0;i<olen-seedlen-hlen;i++)
+			DBMASK[i]=DBMASK[i+hlen];
+
+		for (i=0;i<hlen;i++)
+			SEED[i]=CHASH[i]=0;
+		
+		for (k=0;;k++)
+		{
+			if (k>=olen-seedlen-hlen) return new byte[0];
+			if (DBMASK[k]!=0) break;
+		}
+
+		t=DBMASK[k];
+		if (!comp || x!=0 || t!=0x01) 
+		{
+			for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+			return new byte[0];
+		}
+
+		byte[] r=new byte[olen-seedlen-hlen-k-1];
+
+		for (i=0;i<olen-seedlen-hlen-k-1;i++)
+			r[i]=DBMASK[i+k+1];
+	
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		return r;
+	}
+
+	/* destroy the Private Key structure */
+	public static void PRIVATE_KEY_KILL(private_key PRIV)
+	{
+		PRIV.p.zero();
+		PRIV.q.zero();
+		PRIV.dp.zero();
+		PRIV.dq.zero();
+		PRIV.c.zero();
+	}
+
+	/* RSA encryption with the public key */
+	public static void ENCRYPT(public_key PUB,byte[] F,byte[] G)
+	{
+		int n=PUB.n.getlen();
+		FF f=new FF(n);
+		FF.fromBytes(f,F);
+		f.power(PUB.e,PUB.n);
+		f.toBytes(G);
+	}
+
+	/* RSA decryption with the private key */
+	public static void DECRYPT(private_key PRIV,byte[] G,byte[] F)
+	{
+		int n=PRIV.p.getlen();
+		FF g=new FF(2*n);
+
+		FF.fromBytes(g,G);
+		FF jp=g.dmod(PRIV.p);
+		FF jq=g.dmod(PRIV.q);
+
+		jp.skpow(PRIV.dp,PRIV.p);
+		jq.skpow(PRIV.dq,PRIV.q);
+
+		g.zero();
+		g.dscopy(jp);
+		jp.mod(PRIV.q);
+		if (FF.comp(jp,jq)>0) jq.add(PRIV.q);
+		jq.sub(jp);
+		jq.norm();
+
+		FF t=FF.mul(PRIV.c,jq);
+		jq=t.dmod(PRIV.q);
+
+		t=FF.mul(jq,PRIV.p);
+		g.add(t);
+		g.norm();
+
+		g.toBytes(F);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/private_key.java b/src/main/java/org/apache/milagro/amcl/RSA2048/private_key.java
new file mode 100644
index 0000000..359bf81
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/private_key.java
@@ -0,0 +1,16 @@
+
+package org.apache.milagro.amcl.RSA2048;
+
+public final class private_key
+{
+    public FF p,q,dp,dq,c;
+	
+	public private_key(int n)
+	{
+		p=new FF(n);
+		q=new FF(n);
+		dp=new FF(n);
+		dq=new FF(n);
+		c=new FF(n);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA2048/public_key.java b/src/main/java/org/apache/milagro/amcl/RSA2048/public_key.java
new file mode 100644
index 0000000..a08d884
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA2048/public_key.java
@@ -0,0 +1,14 @@
+
+package org.apache.milagro.amcl.RSA2048;
+
+public final class public_key
+{
+    public int e;
+    public FF n;
+
+	public public_key(int m)
+	{
+		e=0;
+		n=new FF(m);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/BIG.java b/src/main/java/org/apache/milagro/amcl/RSA3072/BIG.java
new file mode 100644
index 0000000..7796c59
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.RSA3072;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=48; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/DBIG.java b/src/main/java/org/apache/milagro/amcl/RSA3072/DBIG.java
new file mode 100644
index 0000000..564f403
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.RSA3072;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/FF.java b/src/main/java/org/apache/milagro/amcl/RSA3072/FF.java
new file mode 100644
index 0000000..48d5e2f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/FF.java
@@ -0,0 +1,1028 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Large Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.RSA3072;
+import org.apache.milagro.amcl.RAND;
+
+public final class FF {
+
+/* RSA/DH modulus length as multiple of BIGBITS */
+	public static final int FFLEN=8;
+
+/* Don't Modify from here... */
+
+
+/* Finite field support - for RSA, DH etc. */
+	public static final int FF_BITS=(BIG.BIGBITS*FFLEN); /* Finite Field Size in bits - must be 256.2^n */
+	public static final int HFLEN=(FFLEN/2);  /* Useful for half-size RSA private key operations */
+
+	public static final int P_MBITS=BIG.MODBYTES*8;
+	public static final int P_TBITS=(P_MBITS%BIG.BASEBITS);
+
+	private final BIG[] v;
+	private final int length;
+
+/**************** 64-bit specific ************************/
+
+	public static final long P_OMASK=((long)(-1)<<(P_MBITS%BIG.BASEBITS));
+	public static final long P_FEXCESS=((long)1<<(BIG.BASEBITS*BIG.NLEN-P_MBITS-1));
+
+	public static long EXCESS(BIG a)
+	{
+		return ((a.get(BIG.NLEN-1)&P_OMASK)>>(P_TBITS))+1;
+	}
+
+/* Check if product causes excess */
+	public static boolean pexceed(BIG a,BIG b)
+	{
+		long ea,eb;
+		ea=EXCESS(a);
+		eb=EXCESS(b);
+		if ((ea+1)>P_FEXCESS/(eb+1)) return true;
+		return false;
+	}
+
+/* Check if square causes excess */
+	public static boolean sexceed(BIG a)
+	{
+		long ea;
+		ea=EXCESS(a);
+		if ((ea+1)>P_FEXCESS/(ea+1)) return true;
+		return false;
+	}
+
+/******************************************************/
+
+/* Constructors */
+	public FF(int n)
+	{
+		v=new BIG[n];
+		for (int i=0;i<n;i++)
+			v[i]=new BIG(0);
+		length=n;
+	}
+
+	public int getlen()
+	{
+		return length;
+	}
+
+/* set to integer */
+	public void set(int m)
+	{
+		zero();
+		v[0].set(0,(m&BIG.BMASK));
+		v[0].set(1,(m>>BIG.BASEBITS));
+	}
+
+/* copy from FF b */
+	public void copy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[i]);
+		}
+	}
+
+/* x=y<<n */
+	public void dsucopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[b.length+i].copy(b.v[i]);
+			v[i].zero();
+		}
+	}
+
+/* x=y */
+	public void dscopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[i].copy(b.v[i]);
+			v[b.length+i].zero();
+		}
+	}
+
+/* x=y>>n */
+	public void sducopy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[length+i]);
+		}
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+	public void one()
+	{
+		v[0].one();
+		for (int i=1;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+/* test equals 0 */
+	public boolean iszilch() 
+	{
+		for (int i=0;i<length;i++)
+		{
+			if (!v[i].iszilch()) return false;
+		}
+		return true;
+	}
+
+/* shift right by BIGBITS-bit words */
+	public void shrw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[i].copy(v[i+n]);
+			v[i+n].zero();
+		}
+	}
+
+/* shift left by BIGBITS-bit words */
+	public void shlw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[n+i].copy(v[i]);
+			v[i].zero();
+		}
+	}
+
+/* extract last bit */
+	public int parity()
+	{
+		return v[0].parity();
+	}
+
+	public int lastbits(int m)
+	{
+		return v[0].lastbits(m);
+	}
+
+/* compare x and y - must be normalised, and of same length */
+	public static int comp(FF a,FF b)
+	{
+		int i,j;
+		for (i=a.length-1;i>=0;i--)
+		{
+			j=BIG.comp(a.v[i],b.v[i]);
+			if (j!=0) return j;
+		}
+		return 0;
+	}
+
+/* recursive add */
+	public void radd(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive inc */
+	public void rinc(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive sub */
+	public void rsub(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* recursive dec */
+	public void rdec(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* simple add */
+	public void add(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].add(b.v[i]);
+	}
+
+/* simple sub */
+	public void sub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].sub(b.v[i]);
+	}
+	
+/* reverse sub */
+	public void revsub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].rsub(b.v[i]);
+	}
+
+/* increment/decrement by a small integer */
+	public void inc(int m)
+	{
+		v[0].inc(m);
+		norm();
+	}
+
+	public void dec(int m)
+	{
+		v[0].dec(m);
+		norm();
+	}
+
+	/* normalise - but hold any overflow in top part unless n<0 */
+	private void rnorm(int vp,int n)
+	{
+		boolean trunc=false;
+		int i;
+		long carry;
+		if (n<0)
+		{ /* -v n signals to do truncation */
+			n=-n;
+			trunc=true;
+		}
+		for (i=0;i<n-1;i++)
+		{
+			carry=v[vp+i].norm();  
+			v[vp+i].xortop(carry<<P_TBITS);
+			v[vp+i+1].incl(carry);
+		}
+		carry=v[vp+n-1].norm();
+		if (trunc) 
+			v[vp+n-1].xortop(carry<<P_TBITS);
+	}
+
+	public void norm()
+	{
+		rnorm(0,length);
+	}
+
+/* shift left by one bit */
+	public void shl()
+	{
+		int i,carry,delay_carry=0;
+		for (i=0;i<length-1;i++)
+		{
+			carry=v[i].fshl(1);
+			v[i].inc(delay_carry);
+			v[i].xortop((long)carry<<P_TBITS);
+			delay_carry=carry;
+		}
+		v[length-1].fshl(1);
+		v[length-1].inc(delay_carry);
+	}
+
+/* shift right by one bit */
+
+	public void shr()
+	{
+		int carry;
+		for (int i=length-1;i>0;i--)
+		{
+			carry=v[i].fshr(1);
+			v[i-1].xortop((long)carry<<P_TBITS);
+		}
+		v[0].fshr(1);
+	}
+
+/* Convert to Hex String */
+	public String toString() 
+	{
+		norm();
+		String s="";
+		for (int i=length-1;i>=0;i--)
+		{
+			s+=v[i].toString(); //s+=" ";
+		}
+		return s;
+	}
+
+/*
+	public String toRawString(int len) 
+	{
+	//	norm(len);
+		String s="";
+		for (int i=len-1;i>=0;i--)
+		{
+			s+=v[i].toRawString(); s+=" ";
+		}
+		return s;
+	}
+*/
+/* Convert FFs to/from byte arrays */
+	public void toBytes(byte[] b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].tobytearray(b,(length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+	public static void fromBytes(FF x,byte[] b)
+	{
+		for (int i=0;i<x.length;i++)
+		{
+			x.v[i]=BIG.frombytearray(b,(x.length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+/* in-place swapping using xor - side channel resistant - lengths must be the same */
+	private static void cswap(FF a,FF b,int d)
+	{
+		for (int i=0;i<a.length;i++)
+		{
+		//	BIG.cswap(a.v[i],b.v[i],d);
+			a.v[i].cswap(b.v[i],d);
+		}
+	}
+
+/* z=x*y, t is workspace */
+	private void karmul(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			y.v[yp].norm();
+			DBIG d=BIG.mul(x.v[xp],y.v[yp]);
+			v[vp+1]=d.split(8*BIG.MODBYTES);
+			v[vp].copy(d);
+			return;
+		}
+		nd2=n/2;
+		radd(vp,x,xp,x,xp+nd2,nd2);
+		rnorm(vp,nd2);                   /* Important - required for 32-bit build */
+		radd(vp+nd2,y,yp,y,yp+nd2,nd2);
+		rnorm(vp+nd2,nd2);               /* Important - required for 32-bit build */
+
+		t.karmul(tp,this,vp,this,vp+nd2,t,tp+n,nd2);
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		karmul(vp+n,x,xp+nd2,y,yp+nd2,t,tp+n,nd2);
+		t.rdec(tp,this,vp,n);
+		t.rdec(tp,this,vp+n,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp,2*n);
+	}
+
+	private void karsqr(int vp,FF x,int xp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			DBIG d=BIG.sqr(x.v[xp]);
+			v[vp+1].copy(d.split(8*BIG.MODBYTES));
+			v[vp].copy(d);
+			return;
+		}	
+
+		nd2=n/2;
+		karsqr(vp,x,xp,t,tp+n,nd2);
+		karsqr(vp+n,x,xp+nd2,t,tp+n,nd2);
+		t.karmul(tp,x,xp,x,xp+nd2,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp+nd2,n);
+	}
+
+
+	private void karmul_lower(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{ /* Calculates Least Significant bottom half of x*y */
+		int nd2;
+		if (n==1)
+		{ /* only calculate bottom half of product */
+			v[vp].copy(BIG.smul(x.v[xp],y.v[yp]));
+			return;
+		}
+		nd2=n/2;
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		t.karmul_lower(tp,x,xp+nd2,y,yp,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,nd2);
+		t.karmul_lower(tp,x,xp,y,yp+nd2,t,tp+n,nd2);
+
+		rinc(vp+nd2,t,tp,nd2);
+		rnorm(vp+nd2,-nd2);  /* truncate it */
+	}
+
+	private void karmul_upper(FF x,FF y,FF t,int n)
+	{ /* Calculates Most Significant upper half of x*y, given lower part */
+		int nd2;
+ 
+		nd2=n/2;
+		radd(n,x,0,x,nd2,nd2);
+		radd(n+nd2,y,0,y,nd2,nd2);
+		rnorm(n,nd2);
+		rnorm(n+nd2,nd2);
+
+		t.karmul(0,this,n+nd2,this,n,t,n,nd2);  /* t = (a0+a1)(b0+b1) */
+		karmul(n,x,nd2,y,nd2,t,n,nd2); /* z[n]= a1*b1 */
+									/* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */
+		t.rdec(0,this,n,n);              /* t=t-a1b1  */
+		rinc(nd2,this,0,nd2);   /* z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1)  */
+		rdec(nd2,t,0,nd2);   /* z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) */
+		rnorm(0,-n);					/* a0b0 now in z - truncate it */
+		t.rdec(0,this,0,n);         /* (a0+a1)(b0+b1) - a0b0 */
+		rinc(nd2,t,0,n);
+
+		rnorm(nd2,n);
+	}
+
+	/* z=x*y. Assumes x and y are of same length. */
+	public static FF mul(FF x,FF y)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); y.norm();
+		z.karmul(0,x,0,y,0,t,0,n);
+		return z;
+	}
+
+	/* z=x^2 */
+	public static FF sqr(FF x)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); 
+		z.karsqr(0,x,0,t,0,n);
+		return z;
+	}
+
+/* return low part of product this*y */
+	public void lmul(FF y)
+	{
+		int n=length;
+		FF t=new FF(2*n);
+		FF x=new FF(n); x.copy(this);
+//		x.norm(); y.norm();
+		karmul_lower(0,x,0,y,0,t,0,n);
+	}
+
+/* Set b=b mod c */
+	public void mod(FF c)
+	{
+		int k=0;  
+
+		norm();
+		if (comp(this,c)<0) 
+			return;
+		do
+		{
+			c.shl();
+			k++;
+		} while (comp(this,c)>=0);
+
+		while (k>0)
+		{
+			c.shr();
+			if (comp(this,c)>=0)
+			{
+				sub(c);
+				norm();
+			}
+			k--;
+		}
+	}
+
+/* return This mod modulus, N is modulus, ND is Montgomery Constant */
+	public FF reduce(FF N,FF ND)
+	{ /* fast karatsuba Montgomery reduction */
+		int n=N.length;
+		FF t=new FF(2*n);
+		FF r=new FF(n);
+		FF m=new FF(n);
+
+		r.sducopy(this);
+		m.karmul_lower(0,this,0,ND,0,t,0,n);
+		karmul_upper(N,m,t,n);
+		m.sducopy(this);
+
+		r.add(N);
+		r.sub(m);
+		r.norm();
+
+		return r;
+	}
+
+/* Set r=this mod b */
+/* this is of length - 2*n */
+/* r,b is of length - n */
+	public FF dmod(FF b)
+	{
+		int k,n=b.length;
+		FF m=new FF(2*n);
+		FF x=new FF(2*n);
+		FF r=new FF(n);
+
+		x.copy(this);
+		x.norm();
+		m.dsucopy(b); k=BIG.BIGBITS*n;
+
+		while (comp(x,m)>=0)
+		{
+			x.sub(m);
+			x.norm();
+		}
+
+		while (k>0)
+		{	
+			m.shr();
+
+			if (comp(x,m)>=0)
+			{
+				x.sub(m);
+				x.norm();
+			}
+			k--;
+		}
+
+		r.copy(x);
+		r.mod(b);
+		return r;
+	}
+
+/* Set return=1/this mod p. Binary method - a<p on entry */
+
+	public void invmodp(FF p)
+	{
+		int n=p.length;
+
+		FF u=new FF(n);
+		FF v=new FF(n);
+		FF x1=new FF(n);
+		FF x2=new FF(n);
+		FF t=new FF(n);
+		FF one=new FF(n);
+
+		one.one();
+		u.copy(this);
+		v.copy(p);
+		x1.copy(one);
+		x2.zero();
+
+	// reduce n in here as well! 
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.shr();
+				if (x1.parity()!=0)
+				{
+					x1.add(p); 
+					x1.norm();
+				}
+				x1.shr(); 
+			}
+			while (v.parity()==0)
+			{
+				v.shr(); 
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.shr();
+			}
+			if (comp(u,v)>=0)
+			{
+
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0)
+			copy(x1);
+		else
+			copy(x2);
+	}
+
+/* nresidue mod m */
+	public void nres(FF m)
+	{
+		int n=m.length;
+		if (n==1)
+		{ 
+			DBIG d=new DBIG(this.v[0]);
+			d.shl(BIG.NLEN*BIG.BASEBITS);
+			this.v[0].copy(d.mod(m.v[0]));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			d.dsucopy(this);
+			copy(d.dmod(m));
+		}
+	}
+
+	public void redc(FF m,FF ND)
+	{
+		int n=m.length;
+		if (n==1)
+		{
+			DBIG d=new DBIG(this.v[0]);
+			this.v[0].copy(BIG.monty(m.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-ND.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			mod(m);
+			d.dscopy(this);
+			copy(d.reduce(m,ND));
+			mod(m);
+		}
+	}
+
+	private void mod2m(int m)
+	{
+		for (int i=m;i<length;i++)
+			v[i].zero();
+	}
+
+	/* U=1/a mod 2^m - Arazi & Qi */
+	private FF invmod2m()
+	{
+		int i,n=length;
+
+		FF b=new FF(n);
+		FF c=new FF(n);
+		FF U=new FF(n);
+		FF t;
+
+		U.zero();
+		U.v[0].copy(v[0]);
+		U.v[0].invmod2m();
+
+		for (i=1;i<n;i<<=1)
+		{
+			b.copy(this); b.mod2m(i);
+			t=mul(U,b);
+
+			t.shrw(i); b.copy(t);
+			c.copy(this); c.shrw(i); c.mod2m(i);
+			c.lmul(U); c.mod2m(i);
+
+			b.add(c); b.norm();
+			b.lmul(U); b.mod2m(i);
+
+			c.one(); c.shlw(i); b.revsub(c); b.norm();
+			b.shlw(i);
+			U.add(b);
+		}
+		U.norm();
+		return U;
+	}
+
+	public void random(RAND rng)
+	{
+		int n=length;
+		for (int i=0;i<n;i++)
+		{
+			v[i].copy(BIG.random(rng));
+		}
+	/* make sure top bit is 1 */
+		while (v[n-1].nbits()<BIG.MODBYTES*8) v[n-1].copy(BIG.random(rng));
+	}
+
+	/* generate random x */
+	public void randomnum(FF p,RAND rng)
+	{
+		int n=length;
+		FF d=new FF(2*n);
+
+		for (int i=0;i<2*n;i++)
+		{
+			d.v[i].copy(BIG.random(rng));
+		}
+		copy(d.dmod(p));
+	}
+
+	/* this*=y mod p */
+	public void modmul(FF y,FF p,FF nd)
+	{
+		if (pexceed(v[length-1],y.v[y.length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.mul(this.v[0],y.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=mul(this,y);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this*=y mod p */
+	public void modsqr(FF p,FF nd)
+	{
+		if (sexceed(v[length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.sqr(this.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+
+		}
+		else
+		{
+			FF d=sqr(this);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */
+	public void skpow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
+	public void skpow(BIG e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			b=e.bit(i);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* raise to an integer power - right-to-left method */
+	public void power(int e,FF p)
+	{
+		int n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+		boolean f=true;
+
+		w.copy(this);
+		w.nres(p);
+
+		if (e==2)
+		{
+			copy(w);
+			modsqr(p,ND);
+		}
+		else for (; ; )
+		{
+			if (e%2==1)
+			{
+				if (f) copy(w);
+				else modmul(w,p,ND);
+				f=false;
+			}
+			e>>=1;
+			if (e==0) break;
+			w.modsqr(p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* this=this^e mod p, faster but not side channel resistant */
+	public void pow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+
+		w.copy(this);
+		one();
+		nres(p);
+		w.nres(p);
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			modsqr(p,ND);
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			if (b==1) modmul(w,p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* double exponentiation r=x^e.y^f mod p */
+	public void pow2(BIG e,FF y,BIG f,FF p)
+	{
+		int i,eb,fb,n=p.length;
+		FF xn=new FF(n);
+		FF yn=new FF(n);
+		FF xy=new FF(n);
+		FF ND=p.invmod2m();
+
+		xn.copy(this);
+		yn.copy(y);
+		xn.nres(p);
+		yn.nres(p);
+		xy.copy(xn); xy.modmul(yn,p,ND);
+		one();
+		nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			eb=e.bit(i);
+			fb=f.bit(i);
+			modsqr(p,ND);
+			if (eb==1)
+			{
+				if (fb==1) modmul(xy,p,ND);
+				else modmul(xn,p,ND);
+			}
+			else
+			{
+				if (fb==1) modmul(yn,p,ND);
+			}
+		}
+		redc(p,ND);
+	}
+
+	private static int igcd(int x,int y)
+	{ /* integer GCD, returns GCD of x and y */
+		int r;
+		if (y==0) return x;
+		while ((r=x%y)!=0)
+			{x=y;y=r;}
+		return y;
+	}
+
+	/* quick and dirty check for common factor with n */
+	public boolean cfactor(int s)
+	{
+		int r,n=length;
+		int g;
+
+		FF x=new FF(n);
+		FF y=new FF(n);
+
+		y.set(s);
+		x.copy(this);
+		x.norm();
+
+		do
+		{
+			x.sub(y);
+			x.norm();
+			while (!x.iszilch() && x.parity()==0) x.shr();
+		}
+		while (comp(x,y)>0);
+
+		g=(int)x.v[0].get(0);
+		r=igcd(s,g);
+		if (r>1) return true;
+		return false;
+	}
+
+	/* Miller-Rabin test for primality. Slow. */
+	public static boolean prime(FF p,RAND rng)
+	{
+		int i,j,s=0,n=p.length;
+		boolean loop;
+		FF d=new FF(n);
+		FF x=new FF(n);
+		FF unity=new FF(n);
+		FF nm1=new FF(n);
+
+		int sf=4849845; /* 3*5*.. *19 */
+		p.norm();
+
+		if (p.cfactor(sf)) return false;
+		unity.one();
+		nm1.copy(p);
+		nm1.sub(unity);
+		nm1.norm();
+		d.copy(nm1);
+
+		while (d.parity()==0)
+		{
+			d.shr();
+			s++;
+		}
+		if (s==0) return false;
+		for (i=0;i<10;i++)
+		{
+			x.randomnum(p,rng);
+			x.pow(d,p);
+
+			if (comp(x,unity)==0 || comp(x,nm1)==0) continue;
+			loop=false;
+			for (j=1;j<s;j++)
+			{
+				x.power(2,p);
+				if (comp(x,unity)==0) return false;
+				if (comp(x,nm1)==0) {loop=true; break;}
+			}
+			if (loop) continue;
+			return false;
+		}
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/RSA.java b/src/main/java/org/apache/milagro/amcl/RSA3072/RSA.java
new file mode 100644
index 0000000..1936bcb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/RSA.java
@@ -0,0 +1,369 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* RSA API high-level functions  */
+
+package org.apache.milagro.amcl.RSA3072;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+
+public final class RSA {
+
+	public static final int RFS=BIG.MODBYTES*FF.FFLEN;
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=SHA256;
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,byte[] A,int n)
+	{
+		byte[] R=null;
+
+		if (sha==SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		return R;
+	}
+
+/* generate an RSA key pair */
+
+	public static void KEY_PAIR(RAND rng,int e,private_key PRIV,public_key PUB)
+	{ /* IEEE1363 A16.11/A16.12 more or less */
+
+		int n=PUB.n.getlen()/2;
+		FF t = new FF(n);
+		FF p1=new FF(n);
+		FF q1=new FF(n);
+
+		for (;;)
+		{
+			PRIV.p.random(rng);
+			while (PRIV.p.lastbits(2)!=3) PRIV.p.inc(1);
+			while (!FF.prime(PRIV.p,rng)) PRIV.p.inc(4);
+
+			p1.copy(PRIV.p);
+			p1.dec(1);
+
+			if (p1.cfactor(e)) continue;
+			break;
+		}
+
+		for (;;)
+		{
+			PRIV.q.random(rng);
+			while (PRIV.q.lastbits(2)!=3) PRIV.q.inc(1);
+			while (!FF.prime(PRIV.q,rng)) PRIV.q.inc(4);
+			
+			q1.copy(PRIV.q);
+			q1.dec(1);
+
+			if (q1.cfactor(e)) continue;
+
+			break;
+		}
+
+		PUB.n=FF.mul(PRIV.p,PRIV.q);
+		PUB.e=e;
+
+		t.copy(p1);
+		t.shr();
+		PRIV.dp.set(e);
+		PRIV.dp.invmodp(t);
+		if (PRIV.dp.parity()==0) PRIV.dp.add(t);
+		PRIV.dp.norm();
+
+		t.copy(q1);
+		t.shr();
+		PRIV.dq.set(e);
+		PRIV.dq.invmodp(t);
+		if (PRIV.dq.parity()==0) PRIV.dq.add(t);
+		PRIV.dq.norm();
+
+		PRIV.c.copy(PRIV.p);
+		PRIV.c.invmodp(PRIV.q);
+
+		return;
+	}
+
+/* Mask Generation Function */
+
+	public static void MGF1(int sha,byte[] Z,int olen,byte[] K)
+	{
+		int hlen=sha;
+		byte[] B;
+
+		int counter,cthreshold,k=0;
+
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}	
+	}
+
+	public static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}  
+
+
+
+/* SHARSA3072 identifier strings */
+	private static final byte[] SHA256ID={0x30,0x31,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
+	private static final byte[] SHA384ID={0x30,0x41,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30};
+	private static final byte[] SHA512ID={0x30,0x51,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40};
+
+/* PKCS 1.5 padding of a message to be signed */
+
+	public static boolean PKCS15(int sha,byte[] m,byte[] w)
+	{
+		int olen=FF.FF_BITS/8;
+		int i,hlen=sha;
+		int idlen=19; 
+
+		if (olen<idlen+hlen+10) return false;
+		byte[] H=hashit(sha,m,-1);
+
+		for (i=0;i<w.length;i++) w[i]=0;
+		i=0;
+		w[i++]=0;
+		w[i++]=1;
+		for (int j=0;j<olen-idlen-hlen-3;j++)
+			w[i++]=(byte)0xff;
+		w[i++]=0;
+
+
+		if (hlen==SHA256) for (int j=0;j<idlen;j++) w[i++]=SHA256ID[j];
+		if (hlen==SHA384) for (int j=0;j<idlen;j++) w[i++]=SHA384ID[j];
+		if (hlen==SHA512) for (int j=0;j<idlen;j++) w[i++]=SHA512ID[j];
+
+		for (int j=0;j<hlen;j++)
+			w[i++]=H[j];
+
+		return true;
+	}
+
+
+	/* OAEP Message Encoding for Encryption */
+	public static byte[] OAEP_ENCODE(int sha,byte[] m,RAND rng,byte[] p)
+	{ 
+		int i,slen,olen=RFS-1;
+		int mlen=m.length;
+		int hlen,seedlen;
+		byte[] f=new byte[RFS];
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+
+		if (mlen>olen-hlen-seedlen-1) return new byte[0]; 
+
+		byte[] DBMASK=new byte[olen-seedlen];
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) f[i]=h[i];
+
+		slen=olen-mlen-hlen-seedlen-1;      
+
+		for (i=0;i<slen;i++) f[hlen+i]=0;
+		f[hlen+slen]=1;
+		for (i=0;i<mlen;i++) f[hlen+slen+1+i]=m[i];
+
+		for (i=0;i<seedlen;i++) SEED[i]=(byte)rng.getByte();
+
+		MGF1(sha,SEED,olen-seedlen,DBMASK);
+
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		MGF1(sha,DBMASK,seedlen,f);
+
+		for (i=0;i<seedlen;i++) f[i]^=SEED[i];
+
+		for (i=0;i<olen-seedlen;i++) f[i+seedlen]=DBMASK[i];
+
+		/* pad to length RFS */
+		int d=1;
+		for (i=RFS-1;i>=d;i--)
+			f[i]=f[i-d];
+		for (i=d-1;i>=0;i--)
+			f[i]=0;
+
+		return f;
+	}
+
+	/* OAEP Message Decoding for Decryption */
+	public static byte[] OAEP_DECODE(int sha,byte[] p,byte[] f)
+	{
+		int x,t;
+		boolean comp;
+		int i,k,olen=RFS-1;
+		int hlen,seedlen;
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+		byte[] CHASH=new byte[hlen];
+	
+		if (olen<seedlen+hlen+1) return new byte[0];
+		byte[] DBMASK=new byte[olen-seedlen];
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		if (f.length<RFS)
+		{
+			int d=RFS-f.length;
+			for (i=RFS-1;i>=d;i--)
+				f[i]=f[i-d];
+			for (i=d-1;i>=0;i--)
+				f[i]=0;
+
+		}
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) CHASH[i]=h[i];
+
+		x=f[0];
+
+		for (i=seedlen;i<olen;i++)
+			DBMASK[i-seedlen]=f[i+1]; 
+
+		MGF1(sha,DBMASK,seedlen,SEED);
+		for (i=0;i<seedlen;i++) SEED[i]^=f[i+1];
+		MGF1(sha,SEED,olen-seedlen,f);
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		comp=true;
+		for (i=0;i<hlen;i++)
+		{
+			if (CHASH[i]!=DBMASK[i]) comp=false;
+		}
+
+		for (i=0;i<olen-seedlen-hlen;i++)
+			DBMASK[i]=DBMASK[i+hlen];
+
+		for (i=0;i<hlen;i++)
+			SEED[i]=CHASH[i]=0;
+		
+		for (k=0;;k++)
+		{
+			if (k>=olen-seedlen-hlen) return new byte[0];
+			if (DBMASK[k]!=0) break;
+		}
+
+		t=DBMASK[k];
+		if (!comp || x!=0 || t!=0x01) 
+		{
+			for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+			return new byte[0];
+		}
+
+		byte[] r=new byte[olen-seedlen-hlen-k-1];
+
+		for (i=0;i<olen-seedlen-hlen-k-1;i++)
+			r[i]=DBMASK[i+k+1];
+	
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		return r;
+	}
+
+	/* destroy the Private Key structure */
+	public static void PRIVATE_KEY_KILL(private_key PRIV)
+	{
+		PRIV.p.zero();
+		PRIV.q.zero();
+		PRIV.dp.zero();
+		PRIV.dq.zero();
+		PRIV.c.zero();
+	}
+
+	/* RSA encryption with the public key */
+	public static void ENCRYPT(public_key PUB,byte[] F,byte[] G)
+	{
+		int n=PUB.n.getlen();
+		FF f=new FF(n);
+		FF.fromBytes(f,F);
+		f.power(PUB.e,PUB.n);
+		f.toBytes(G);
+	}
+
+	/* RSA decryption with the private key */
+	public static void DECRYPT(private_key PRIV,byte[] G,byte[] F)
+	{
+		int n=PRIV.p.getlen();
+		FF g=new FF(2*n);
+
+		FF.fromBytes(g,G);
+		FF jp=g.dmod(PRIV.p);
+		FF jq=g.dmod(PRIV.q);
+
+		jp.skpow(PRIV.dp,PRIV.p);
+		jq.skpow(PRIV.dq,PRIV.q);
+
+		g.zero();
+		g.dscopy(jp);
+		jp.mod(PRIV.q);
+		if (FF.comp(jp,jq)>0) jq.add(PRIV.q);
+		jq.sub(jp);
+		jq.norm();
+
+		FF t=FF.mul(PRIV.c,jq);
+		jq=t.dmod(PRIV.q);
+
+		t=FF.mul(jq,PRIV.p);
+		g.add(t);
+		g.norm();
+
+		g.toBytes(F);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/private_key.java b/src/main/java/org/apache/milagro/amcl/RSA3072/private_key.java
new file mode 100644
index 0000000..f46b833
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/private_key.java
@@ -0,0 +1,16 @@
+
+package org.apache.milagro.amcl.RSA3072;
+
+public final class private_key
+{
+    public FF p,q,dp,dq,c;
+	
+	public private_key(int n)
+	{
+		p=new FF(n);
+		q=new FF(n);
+		dp=new FF(n);
+		dq=new FF(n);
+		c=new FF(n);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA3072/public_key.java b/src/main/java/org/apache/milagro/amcl/RSA3072/public_key.java
new file mode 100644
index 0000000..564c41f
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA3072/public_key.java
@@ -0,0 +1,14 @@
+
+package org.apache.milagro.amcl.RSA3072;
+
+public final class public_key
+{
+    public int e;
+    public FF n;
+
+	public public_key(int m)
+	{
+		e=0;
+		n=new FF(m);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/BIG.java b/src/main/java/org/apache/milagro/amcl/RSA4096/BIG.java
new file mode 100644
index 0000000..e79eb83
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.RSA4096;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=64; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=60; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/DBIG.java b/src/main/java/org/apache/milagro/amcl/RSA4096/DBIG.java
new file mode 100644
index 0000000..0a7b1a5
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.RSA4096;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/FF.java b/src/main/java/org/apache/milagro/amcl/RSA4096/FF.java
new file mode 100644
index 0000000..7244bab
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/FF.java
@@ -0,0 +1,1028 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Large Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.RSA4096;
+import org.apache.milagro.amcl.RAND;
+
+public final class FF {
+
+/* RSA/DH modulus length as multiple of BIGBITS */
+	public static final int FFLEN=8;
+
+/* Don't Modify from here... */
+
+
+/* Finite field support - for RSA, DH etc. */
+	public static final int FF_BITS=(BIG.BIGBITS*FFLEN); /* Finite Field Size in bits - must be 256.2^n */
+	public static final int HFLEN=(FFLEN/2);  /* Useful for half-size RSA private key operations */
+
+	public static final int P_MBITS=BIG.MODBYTES*8;
+	public static final int P_TBITS=(P_MBITS%BIG.BASEBITS);
+
+	private final BIG[] v;
+	private final int length;
+
+/**************** 64-bit specific ************************/
+
+	public static final long P_OMASK=((long)(-1)<<(P_MBITS%BIG.BASEBITS));
+	public static final long P_FEXCESS=((long)1<<(BIG.BASEBITS*BIG.NLEN-P_MBITS-1));
+
+	public static long EXCESS(BIG a)
+	{
+		return ((a.get(BIG.NLEN-1)&P_OMASK)>>(P_TBITS))+1;
+	}
+
+/* Check if product causes excess */
+	public static boolean pexceed(BIG a,BIG b)
+	{
+		long ea,eb;
+		ea=EXCESS(a);
+		eb=EXCESS(b);
+		if ((ea+1)>P_FEXCESS/(eb+1)) return true;
+		return false;
+	}
+
+/* Check if square causes excess */
+	public static boolean sexceed(BIG a)
+	{
+		long ea;
+		ea=EXCESS(a);
+		if ((ea+1)>P_FEXCESS/(ea+1)) return true;
+		return false;
+	}
+
+/******************************************************/
+
+/* Constructors */
+	public FF(int n)
+	{
+		v=new BIG[n];
+		for (int i=0;i<n;i++)
+			v[i]=new BIG(0);
+		length=n;
+	}
+
+	public int getlen()
+	{
+		return length;
+	}
+
+/* set to integer */
+	public void set(int m)
+	{
+		zero();
+		v[0].set(0,(m&BIG.BMASK));
+		v[0].set(1,(m>>BIG.BASEBITS));
+	}
+
+/* copy from FF b */
+	public void copy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[i]);
+		}
+	}
+
+/* x=y<<n */
+	public void dsucopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[b.length+i].copy(b.v[i]);
+			v[i].zero();
+		}
+	}
+
+/* x=y */
+	public void dscopy(FF b)
+	{
+		for (int i=0;i<b.length;i++)
+		{
+			v[i].copy(b.v[i]);
+			v[b.length+i].zero();
+		}
+	}
+
+/* x=y>>n */
+	public void sducopy(FF b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].copy(b.v[length+i]);
+		}
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+	public void one()
+	{
+		v[0].one();
+		for (int i=1;i<length;i++)
+		{
+			v[i].zero();
+		}
+	}
+
+/* test equals 0 */
+	public boolean iszilch() 
+	{
+		for (int i=0;i<length;i++)
+		{
+			if (!v[i].iszilch()) return false;
+		}
+		return true;
+	}
+
+/* shift right by BIGBITS-bit words */
+	public void shrw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[i].copy(v[i+n]);
+			v[i+n].zero();
+		}
+	}
+
+/* shift left by BIGBITS-bit words */
+	public void shlw(int n)
+	{
+		for (int i=0;i<n;i++) 
+		{
+			v[n+i].copy(v[i]);
+			v[i].zero();
+		}
+	}
+
+/* extract last bit */
+	public int parity()
+	{
+		return v[0].parity();
+	}
+
+	public int lastbits(int m)
+	{
+		return v[0].lastbits(m);
+	}
+
+/* compare x and y - must be normalised, and of same length */
+	public static int comp(FF a,FF b)
+	{
+		int i,j;
+		for (i=a.length-1;i>=0;i--)
+		{
+			j=BIG.comp(a.v[i],b.v[i]);
+			if (j!=0) return j;
+		}
+		return 0;
+	}
+
+/* recursive add */
+	public void radd(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive inc */
+	public void rinc(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].add(y.v[yp+i]);
+		}
+	}
+
+/* recursive sub */
+	public void rsub(int vp,FF x,int xp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].copy(x.v[xp+i]);
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* recursive dec */
+	public void rdec(int vp,FF y,int yp,int n)
+	{
+		for (int i=0;i<n;i++)
+		{
+			v[vp+i].sub(y.v[yp+i]);
+		}
+	}
+
+/* simple add */
+	public void add(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].add(b.v[i]);
+	}
+
+/* simple sub */
+	public void sub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].sub(b.v[i]);
+	}
+	
+/* reverse sub */
+	public void revsub(FF b)
+	{
+		for (int i=0;i<length;i++)
+			v[i].rsub(b.v[i]);
+	}
+
+/* increment/decrement by a small integer */
+	public void inc(int m)
+	{
+		v[0].inc(m);
+		norm();
+	}
+
+	public void dec(int m)
+	{
+		v[0].dec(m);
+		norm();
+	}
+
+	/* normalise - but hold any overflow in top part unless n<0 */
+	private void rnorm(int vp,int n)
+	{
+		boolean trunc=false;
+		int i;
+		long carry;
+		if (n<0)
+		{ /* -v n signals to do truncation */
+			n=-n;
+			trunc=true;
+		}
+		for (i=0;i<n-1;i++)
+		{
+			carry=v[vp+i].norm();  
+			v[vp+i].xortop(carry<<P_TBITS);
+			v[vp+i+1].incl(carry);
+		}
+		carry=v[vp+n-1].norm();
+		if (trunc) 
+			v[vp+n-1].xortop(carry<<P_TBITS);
+	}
+
+	public void norm()
+	{
+		rnorm(0,length);
+	}
+
+/* shift left by one bit */
+	public void shl()
+	{
+		int i,carry,delay_carry=0;
+		for (i=0;i<length-1;i++)
+		{
+			carry=v[i].fshl(1);
+			v[i].inc(delay_carry);
+			v[i].xortop((long)carry<<P_TBITS);
+			delay_carry=carry;
+		}
+		v[length-1].fshl(1);
+		v[length-1].inc(delay_carry);
+	}
+
+/* shift right by one bit */
+
+	public void shr()
+	{
+		int carry;
+		for (int i=length-1;i>0;i--)
+		{
+			carry=v[i].fshr(1);
+			v[i-1].xortop((long)carry<<P_TBITS);
+		}
+		v[0].fshr(1);
+	}
+
+/* Convert to Hex String */
+	public String toString() 
+	{
+		norm();
+		String s="";
+		for (int i=length-1;i>=0;i--)
+		{
+			s+=v[i].toString(); //s+=" ";
+		}
+		return s;
+	}
+
+/*
+	public String toRawString(int len) 
+	{
+	//	norm(len);
+		String s="";
+		for (int i=len-1;i>=0;i--)
+		{
+			s+=v[i].toRawString(); s+=" ";
+		}
+		return s;
+	}
+*/
+/* Convert FFs to/from byte arrays */
+	public void toBytes(byte[] b)
+	{
+		for (int i=0;i<length;i++)
+		{
+			v[i].tobytearray(b,(length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+	public static void fromBytes(FF x,byte[] b)
+	{
+		for (int i=0;i<x.length;i++)
+		{
+			x.v[i]=BIG.frombytearray(b,(x.length-i-1)*BIG.MODBYTES);
+		}
+	}
+
+/* in-place swapping using xor - side channel resistant - lengths must be the same */
+	private static void cswap(FF a,FF b,int d)
+	{
+		for (int i=0;i<a.length;i++)
+		{
+		//	BIG.cswap(a.v[i],b.v[i],d);
+			a.v[i].cswap(b.v[i],d);
+		}
+	}
+
+/* z=x*y, t is workspace */
+	private void karmul(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			y.v[yp].norm();
+			DBIG d=BIG.mul(x.v[xp],y.v[yp]);
+			v[vp+1]=d.split(8*BIG.MODBYTES);
+			v[vp].copy(d);
+			return;
+		}
+		nd2=n/2;
+		radd(vp,x,xp,x,xp+nd2,nd2);
+		rnorm(vp,nd2);                   /* Important - required for 32-bit build */
+		radd(vp+nd2,y,yp,y,yp+nd2,nd2);
+		rnorm(vp+nd2,nd2);               /* Important - required for 32-bit build */
+
+		t.karmul(tp,this,vp,this,vp+nd2,t,tp+n,nd2);
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		karmul(vp+n,x,xp+nd2,y,yp+nd2,t,tp+n,nd2);
+		t.rdec(tp,this,vp,n);
+		t.rdec(tp,this,vp+n,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp,2*n);
+	}
+
+	private void karsqr(int vp,FF x,int xp,FF t,int tp,int n)
+	{
+		int nd2;
+		if (n==1)
+		{
+			x.v[xp].norm();
+			DBIG d=BIG.sqr(x.v[xp]);
+			v[vp+1].copy(d.split(8*BIG.MODBYTES));
+			v[vp].copy(d);
+			return;
+		}	
+
+		nd2=n/2;
+		karsqr(vp,x,xp,t,tp+n,nd2);
+		karsqr(vp+n,x,xp+nd2,t,tp+n,nd2);
+		t.karmul(tp,x,xp,x,xp+nd2,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,n);
+		rinc(vp+nd2,t,tp,n);
+		rnorm(vp+nd2,n);
+	}
+
+
+	private void karmul_lower(int vp,FF x,int xp,FF y,int yp,FF t,int tp,int n)
+	{ /* Calculates Least Significant bottom half of x*y */
+		int nd2;
+		if (n==1)
+		{ /* only calculate bottom half of product */
+			v[vp].copy(BIG.smul(x.v[xp],y.v[yp]));
+			return;
+		}
+		nd2=n/2;
+		karmul(vp,x,xp,y,yp,t,tp+n,nd2);
+		t.karmul_lower(tp,x,xp+nd2,y,yp,t,tp+n,nd2);
+		rinc(vp+nd2,t,tp,nd2);
+		t.karmul_lower(tp,x,xp,y,yp+nd2,t,tp+n,nd2);
+
+		rinc(vp+nd2,t,tp,nd2);
+		rnorm(vp+nd2,-nd2);  /* truncate it */
+	}
+
+	private void karmul_upper(FF x,FF y,FF t,int n)
+	{ /* Calculates Most Significant upper half of x*y, given lower part */
+		int nd2;
+ 
+		nd2=n/2;
+		radd(n,x,0,x,nd2,nd2);
+		radd(n+nd2,y,0,y,nd2,nd2);
+		rnorm(n,nd2);
+		rnorm(n+nd2,nd2);
+
+		t.karmul(0,this,n+nd2,this,n,t,n,nd2);  /* t = (a0+a1)(b0+b1) */
+		karmul(n,x,nd2,y,nd2,t,n,nd2); /* z[n]= a1*b1 */
+									/* z[0-nd2]=l(a0b0) z[nd2-n]= h(a0b0)+l(t)-l(a0b0)-l(a1b1) */
+		t.rdec(0,this,n,n);              /* t=t-a1b1  */
+		rinc(nd2,this,0,nd2);   /* z[nd2-n]+=l(a0b0) = h(a0b0)+l(t)-l(a1b1)  */
+		rdec(nd2,t,0,nd2);   /* z[nd2-n]=h(a0b0)+l(t)-l(a1b1)-l(t-a1b1)=h(a0b0) */
+		rnorm(0,-n);					/* a0b0 now in z - truncate it */
+		t.rdec(0,this,0,n);         /* (a0+a1)(b0+b1) - a0b0 */
+		rinc(nd2,t,0,n);
+
+		rnorm(nd2,n);
+	}
+
+	/* z=x*y. Assumes x and y are of same length. */
+	public static FF mul(FF x,FF y)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); y.norm();
+		z.karmul(0,x,0,y,0,t,0,n);
+		return z;
+	}
+
+	/* z=x^2 */
+	public static FF sqr(FF x)
+	{
+		int n=x.length;
+		FF z=new FF(2*n);
+		FF t=new FF(2*n);
+//		x.norm(); 
+		z.karsqr(0,x,0,t,0,n);
+		return z;
+	}
+
+/* return low part of product this*y */
+	public void lmul(FF y)
+	{
+		int n=length;
+		FF t=new FF(2*n);
+		FF x=new FF(n); x.copy(this);
+//		x.norm(); y.norm();
+		karmul_lower(0,x,0,y,0,t,0,n);
+	}
+
+/* Set b=b mod c */
+	public void mod(FF c)
+	{
+		int k=0;  
+
+		norm();
+		if (comp(this,c)<0) 
+			return;
+		do
+		{
+			c.shl();
+			k++;
+		} while (comp(this,c)>=0);
+
+		while (k>0)
+		{
+			c.shr();
+			if (comp(this,c)>=0)
+			{
+				sub(c);
+				norm();
+			}
+			k--;
+		}
+	}
+
+/* return This mod modulus, N is modulus, ND is Montgomery Constant */
+	public FF reduce(FF N,FF ND)
+	{ /* fast karatsuba Montgomery reduction */
+		int n=N.length;
+		FF t=new FF(2*n);
+		FF r=new FF(n);
+		FF m=new FF(n);
+
+		r.sducopy(this);
+		m.karmul_lower(0,this,0,ND,0,t,0,n);
+		karmul_upper(N,m,t,n);
+		m.sducopy(this);
+
+		r.add(N);
+		r.sub(m);
+		r.norm();
+
+		return r;
+	}
+
+/* Set r=this mod b */
+/* this is of length - 2*n */
+/* r,b is of length - n */
+	public FF dmod(FF b)
+	{
+		int k,n=b.length;
+		FF m=new FF(2*n);
+		FF x=new FF(2*n);
+		FF r=new FF(n);
+
+		x.copy(this);
+		x.norm();
+		m.dsucopy(b); k=BIG.BIGBITS*n;
+
+		while (comp(x,m)>=0)
+		{
+			x.sub(m);
+			x.norm();
+		}
+
+		while (k>0)
+		{	
+			m.shr();
+
+			if (comp(x,m)>=0)
+			{
+				x.sub(m);
+				x.norm();
+			}
+			k--;
+		}
+
+		r.copy(x);
+		r.mod(b);
+		return r;
+	}
+
+/* Set return=1/this mod p. Binary method - a<p on entry */
+
+	public void invmodp(FF p)
+	{
+		int n=p.length;
+
+		FF u=new FF(n);
+		FF v=new FF(n);
+		FF x1=new FF(n);
+		FF x2=new FF(n);
+		FF t=new FF(n);
+		FF one=new FF(n);
+
+		one.one();
+		u.copy(this);
+		v.copy(p);
+		x1.copy(one);
+		x2.zero();
+
+	// reduce n in here as well! 
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.shr();
+				if (x1.parity()!=0)
+				{
+					x1.add(p); 
+					x1.norm();
+				}
+				x1.shr(); 
+			}
+			while (v.parity()==0)
+			{
+				v.shr(); 
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.shr();
+			}
+			if (comp(u,v)>=0)
+			{
+
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0)
+			copy(x1);
+		else
+			copy(x2);
+	}
+
+/* nresidue mod m */
+	public void nres(FF m)
+	{
+		int n=m.length;
+		if (n==1)
+		{ 
+			DBIG d=new DBIG(this.v[0]);
+			d.shl(BIG.NLEN*BIG.BASEBITS);
+			this.v[0].copy(d.mod(m.v[0]));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			d.dsucopy(this);
+			copy(d.dmod(m));
+		}
+	}
+
+	public void redc(FF m,FF ND)
+	{
+		int n=m.length;
+		if (n==1)
+		{
+			DBIG d=new DBIG(this.v[0]);
+			this.v[0].copy(BIG.monty(m.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-ND.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=new FF(2*n);
+			mod(m);
+			d.dscopy(this);
+			copy(d.reduce(m,ND));
+			mod(m);
+		}
+	}
+
+	private void mod2m(int m)
+	{
+		for (int i=m;i<length;i++)
+			v[i].zero();
+	}
+
+	/* U=1/a mod 2^m - Arazi & Qi */
+	private FF invmod2m()
+	{
+		int i,n=length;
+
+		FF b=new FF(n);
+		FF c=new FF(n);
+		FF U=new FF(n);
+		FF t;
+
+		U.zero();
+		U.v[0].copy(v[0]);
+		U.v[0].invmod2m();
+
+		for (i=1;i<n;i<<=1)
+		{
+			b.copy(this); b.mod2m(i);
+			t=mul(U,b);
+
+			t.shrw(i); b.copy(t);
+			c.copy(this); c.shrw(i); c.mod2m(i);
+			c.lmul(U); c.mod2m(i);
+
+			b.add(c); b.norm();
+			b.lmul(U); b.mod2m(i);
+
+			c.one(); c.shlw(i); b.revsub(c); b.norm();
+			b.shlw(i);
+			U.add(b);
+		}
+		U.norm();
+		return U;
+	}
+
+	public void random(RAND rng)
+	{
+		int n=length;
+		for (int i=0;i<n;i++)
+		{
+			v[i].copy(BIG.random(rng));
+		}
+	/* make sure top bit is 1 */
+		while (v[n-1].nbits()<BIG.MODBYTES*8) v[n-1].copy(BIG.random(rng));
+	}
+
+	/* generate random x */
+	public void randomnum(FF p,RAND rng)
+	{
+		int n=length;
+		FF d=new FF(2*n);
+
+		for (int i=0;i<2*n;i++)
+		{
+			d.v[i].copy(BIG.random(rng));
+		}
+		copy(d.dmod(p));
+	}
+
+	/* this*=y mod p */
+	public void modmul(FF y,FF p,FF nd)
+	{
+		if (pexceed(v[length-1],y.v[y.length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.mul(this.v[0],y.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+		}
+		else
+		{
+			FF d=mul(this,y);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this*=y mod p */
+	public void modsqr(FF p,FF nd)
+	{
+		if (sexceed(v[length-1])) mod(p);
+		int n=p.length;
+		if (n==1)
+		{
+			DBIG d=BIG.sqr(this.v[0]);
+			this.v[0].copy(BIG.monty(p.v[0],(BIG.cast_to_chunk(1)<<BIG.BASEBITS)-nd.v[0].w[0],d));
+
+		}
+		else
+		{
+			FF d=sqr(this);
+			copy(d.reduce(p,nd));
+		}
+	}
+
+	/* this=this^e mod p using side-channel resistant Montgomery Ladder, for large e */
+	public void skpow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* this =this^e mod p using side-channel resistant Montgomery Ladder, for short e */
+	public void skpow(BIG e,FF p)
+	{
+		int i,b,n=p.length;
+		FF R0=new FF(n);
+		FF R1=new FF(n);
+		FF ND=p.invmod2m();
+
+		mod(p);
+		R0.one();
+		R1.copy(this);
+		R0.nres(p);
+		R1.nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			b=e.bit(i);
+			copy(R0);
+			modmul(R1,p,ND);
+
+			cswap(R0,R1,b);
+			R0.modsqr(p,ND);
+
+			R1.copy(this);
+			cswap(R0,R1,b);
+		}
+		copy(R0);
+		redc(p,ND);
+	}
+
+	/* raise to an integer power - right-to-left method */
+	public void power(int e,FF p)
+	{
+		int n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+		boolean f=true;
+
+		w.copy(this);
+		w.nres(p);
+
+		if (e==2)
+		{
+			copy(w);
+			modsqr(p,ND);
+		}
+		else for (; ; )
+		{
+			if (e%2==1)
+			{
+				if (f) copy(w);
+				else modmul(w,p,ND);
+				f=false;
+			}
+			e>>=1;
+			if (e==0) break;
+			w.modsqr(p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* this=this^e mod p, faster but not side channel resistant */
+	public void pow(FF e,FF p)
+	{
+		int i,b,n=p.length;
+		FF w=new FF(n);
+		FF ND=p.invmod2m();
+
+		w.copy(this);
+		one();
+		nres(p);
+		w.nres(p);
+		for (i=8*BIG.MODBYTES*n-1;i>=0;i--)
+		{
+			modsqr(p,ND);
+			b=e.v[i/BIG.BIGBITS].bit(i%BIG.BIGBITS);
+			if (b==1) modmul(w,p,ND);
+		}
+		redc(p,ND);
+	}
+
+	/* double exponentiation r=x^e.y^f mod p */
+	public void pow2(BIG e,FF y,BIG f,FF p)
+	{
+		int i,eb,fb,n=p.length;
+		FF xn=new FF(n);
+		FF yn=new FF(n);
+		FF xy=new FF(n);
+		FF ND=p.invmod2m();
+
+		xn.copy(this);
+		yn.copy(y);
+		xn.nres(p);
+		yn.nres(p);
+		xy.copy(xn); xy.modmul(yn,p,ND);
+		one();
+		nres(p);
+
+		for (i=8*BIG.MODBYTES-1;i>=0;i--)
+		{
+			eb=e.bit(i);
+			fb=f.bit(i);
+			modsqr(p,ND);
+			if (eb==1)
+			{
+				if (fb==1) modmul(xy,p,ND);
+				else modmul(xn,p,ND);
+			}
+			else
+			{
+				if (fb==1) modmul(yn,p,ND);
+			}
+		}
+		redc(p,ND);
+	}
+
+	private static int igcd(int x,int y)
+	{ /* integer GCD, returns GCD of x and y */
+		int r;
+		if (y==0) return x;
+		while ((r=x%y)!=0)
+			{x=y;y=r;}
+		return y;
+	}
+
+	/* quick and dirty check for common factor with n */
+	public boolean cfactor(int s)
+	{
+		int r,n=length;
+		int g;
+
+		FF x=new FF(n);
+		FF y=new FF(n);
+
+		y.set(s);
+		x.copy(this);
+		x.norm();
+
+		do
+		{
+			x.sub(y);
+			x.norm();
+			while (!x.iszilch() && x.parity()==0) x.shr();
+		}
+		while (comp(x,y)>0);
+
+		g=(int)x.v[0].get(0);
+		r=igcd(s,g);
+		if (r>1) return true;
+		return false;
+	}
+
+	/* Miller-Rabin test for primality. Slow. */
+	public static boolean prime(FF p,RAND rng)
+	{
+		int i,j,s=0,n=p.length;
+		boolean loop;
+		FF d=new FF(n);
+		FF x=new FF(n);
+		FF unity=new FF(n);
+		FF nm1=new FF(n);
+
+		int sf=4849845; /* 3*5*.. *19 */
+		p.norm();
+
+		if (p.cfactor(sf)) return false;
+		unity.one();
+		nm1.copy(p);
+		nm1.sub(unity);
+		nm1.norm();
+		d.copy(nm1);
+
+		while (d.parity()==0)
+		{
+			d.shr();
+			s++;
+		}
+		if (s==0) return false;
+		for (i=0;i<10;i++)
+		{
+			x.randomnum(p,rng);
+			x.pow(d,p);
+
+			if (comp(x,unity)==0 || comp(x,nm1)==0) continue;
+			loop=false;
+			for (j=1;j<s;j++)
+			{
+				x.power(2,p);
+				if (comp(x,unity)==0) return false;
+				if (comp(x,nm1)==0) {loop=true; break;}
+			}
+			if (loop) continue;
+			return false;
+		}
+		return true;
+	}
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/RSA.java b/src/main/java/org/apache/milagro/amcl/RSA4096/RSA.java
new file mode 100644
index 0000000..8f6ba8d
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/RSA.java
@@ -0,0 +1,369 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* RSA API high-level functions  */
+
+package org.apache.milagro.amcl.RSA4096;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+
+public final class RSA {
+
+	public static final int RFS=BIG.MODBYTES*FF.FFLEN;
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=SHA256;
+
+/* Hash number (optional) and string to array size of Bigs */
+
+	public static byte[] hashit(int sha,byte[] A,int n)
+	{
+		byte[] R=null;
+
+		if (sha==SHA256)
+		{
+			HASH256 H=new HASH256();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA384)
+		{
+			HASH384 H=new HASH384();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		if (sha==SHA512)
+		{
+			HASH512 H=new HASH512();
+			if (A!=null) H.process_array(A);
+			if (n>=0) H.process_num(n);
+			R=H.hash();
+		}
+		return R;
+	}
+
+/* generate an RSA key pair */
+
+	public static void KEY_PAIR(RAND rng,int e,private_key PRIV,public_key PUB)
+	{ /* IEEE1363 A16.11/A16.12 more or less */
+
+		int n=PUB.n.getlen()/2;
+		FF t = new FF(n);
+		FF p1=new FF(n);
+		FF q1=new FF(n);
+
+		for (;;)
+		{
+			PRIV.p.random(rng);
+			while (PRIV.p.lastbits(2)!=3) PRIV.p.inc(1);
+			while (!FF.prime(PRIV.p,rng)) PRIV.p.inc(4);
+
+			p1.copy(PRIV.p);
+			p1.dec(1);
+
+			if (p1.cfactor(e)) continue;
+			break;
+		}
+
+		for (;;)
+		{
+			PRIV.q.random(rng);
+			while (PRIV.q.lastbits(2)!=3) PRIV.q.inc(1);
+			while (!FF.prime(PRIV.q,rng)) PRIV.q.inc(4);
+			
+			q1.copy(PRIV.q);
+			q1.dec(1);
+
+			if (q1.cfactor(e)) continue;
+
+			break;
+		}
+
+		PUB.n=FF.mul(PRIV.p,PRIV.q);
+		PUB.e=e;
+
+		t.copy(p1);
+		t.shr();
+		PRIV.dp.set(e);
+		PRIV.dp.invmodp(t);
+		if (PRIV.dp.parity()==0) PRIV.dp.add(t);
+		PRIV.dp.norm();
+
+		t.copy(q1);
+		t.shr();
+		PRIV.dq.set(e);
+		PRIV.dq.invmodp(t);
+		if (PRIV.dq.parity()==0) PRIV.dq.add(t);
+		PRIV.dq.norm();
+
+		PRIV.c.copy(PRIV.p);
+		PRIV.c.invmodp(PRIV.q);
+
+		return;
+	}
+
+/* Mask Generation Function */
+
+	public static void MGF1(int sha,byte[] Z,int olen,byte[] K)
+	{
+		int hlen=sha;
+		byte[] B;
+
+		int counter,cthreshold,k=0;
+
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}	
+	}
+
+	public static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}  
+
+
+
+/* SHARSA4096 identifier strings */
+	private static final byte[] SHA256ID={0x30,0x31,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
+	private static final byte[] SHA384ID={0x30,0x41,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30};
+	private static final byte[] SHA512ID={0x30,0x51,0x30,0x0d,0x06,0x09,0x60,(byte)0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40};
+
+/* PKCS 1.5 padding of a message to be signed */
+
+	public static boolean PKCS15(int sha,byte[] m,byte[] w)
+	{
+		int olen=FF.FF_BITS/8;
+		int i,hlen=sha;
+		int idlen=19; 
+
+		if (olen<idlen+hlen+10) return false;
+		byte[] H=hashit(sha,m,-1);
+
+		for (i=0;i<w.length;i++) w[i]=0;
+		i=0;
+		w[i++]=0;
+		w[i++]=1;
+		for (int j=0;j<olen-idlen-hlen-3;j++)
+			w[i++]=(byte)0xff;
+		w[i++]=0;
+
+
+		if (hlen==SHA256) for (int j=0;j<idlen;j++) w[i++]=SHA256ID[j];
+		if (hlen==SHA384) for (int j=0;j<idlen;j++) w[i++]=SHA384ID[j];
+		if (hlen==SHA512) for (int j=0;j<idlen;j++) w[i++]=SHA512ID[j];
+
+		for (int j=0;j<hlen;j++)
+			w[i++]=H[j];
+
+		return true;
+	}
+
+
+	/* OAEP Message Encoding for Encryption */
+	public static byte[] OAEP_ENCODE(int sha,byte[] m,RAND rng,byte[] p)
+	{ 
+		int i,slen,olen=RFS-1;
+		int mlen=m.length;
+		int hlen,seedlen;
+		byte[] f=new byte[RFS];
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+
+		if (mlen>olen-hlen-seedlen-1) return new byte[0]; 
+
+		byte[] DBMASK=new byte[olen-seedlen];
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) f[i]=h[i];
+
+		slen=olen-mlen-hlen-seedlen-1;      
+
+		for (i=0;i<slen;i++) f[hlen+i]=0;
+		f[hlen+slen]=1;
+		for (i=0;i<mlen;i++) f[hlen+slen+1+i]=m[i];
+
+		for (i=0;i<seedlen;i++) SEED[i]=(byte)rng.getByte();
+
+		MGF1(sha,SEED,olen-seedlen,DBMASK);
+
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		MGF1(sha,DBMASK,seedlen,f);
+
+		for (i=0;i<seedlen;i++) f[i]^=SEED[i];
+
+		for (i=0;i<olen-seedlen;i++) f[i+seedlen]=DBMASK[i];
+
+		/* pad to length RFS */
+		int d=1;
+		for (i=RFS-1;i>=d;i--)
+			f[i]=f[i-d];
+		for (i=d-1;i>=0;i--)
+			f[i]=0;
+
+		return f;
+	}
+
+	/* OAEP Message Decoding for Decryption */
+	public static byte[] OAEP_DECODE(int sha,byte[] p,byte[] f)
+	{
+		int x,t;
+		boolean comp;
+		int i,k,olen=RFS-1;
+		int hlen,seedlen;
+
+		hlen=sha;
+		byte[] SEED=new byte[hlen];
+		seedlen=hlen;
+		byte[] CHASH=new byte[hlen];
+	
+		if (olen<seedlen+hlen+1) return new byte[0];
+		byte[] DBMASK=new byte[olen-seedlen];
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		if (f.length<RFS)
+		{
+			int d=RFS-f.length;
+			for (i=RFS-1;i>=d;i--)
+				f[i]=f[i-d];
+			for (i=d-1;i>=0;i--)
+				f[i]=0;
+
+		}
+
+		byte[] h=hashit(sha,p,-1);
+
+		for (i=0;i<hlen;i++) CHASH[i]=h[i];
+
+		x=f[0];
+
+		for (i=seedlen;i<olen;i++)
+			DBMASK[i-seedlen]=f[i+1]; 
+
+		MGF1(sha,DBMASK,seedlen,SEED);
+		for (i=0;i<seedlen;i++) SEED[i]^=f[i+1];
+		MGF1(sha,SEED,olen-seedlen,f);
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]^=f[i];
+
+		comp=true;
+		for (i=0;i<hlen;i++)
+		{
+			if (CHASH[i]!=DBMASK[i]) comp=false;
+		}
+
+		for (i=0;i<olen-seedlen-hlen;i++)
+			DBMASK[i]=DBMASK[i+hlen];
+
+		for (i=0;i<hlen;i++)
+			SEED[i]=CHASH[i]=0;
+		
+		for (k=0;;k++)
+		{
+			if (k>=olen-seedlen-hlen) return new byte[0];
+			if (DBMASK[k]!=0) break;
+		}
+
+		t=DBMASK[k];
+		if (!comp || x!=0 || t!=0x01) 
+		{
+			for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+			return new byte[0];
+		}
+
+		byte[] r=new byte[olen-seedlen-hlen-k-1];
+
+		for (i=0;i<olen-seedlen-hlen-k-1;i++)
+			r[i]=DBMASK[i+k+1];
+	
+		for (i=0;i<olen-seedlen;i++) DBMASK[i]=0;
+
+		return r;
+	}
+
+	/* destroy the Private Key structure */
+	public static void PRIVATE_KEY_KILL(private_key PRIV)
+	{
+		PRIV.p.zero();
+		PRIV.q.zero();
+		PRIV.dp.zero();
+		PRIV.dq.zero();
+		PRIV.c.zero();
+	}
+
+	/* RSA encryption with the public key */
+	public static void ENCRYPT(public_key PUB,byte[] F,byte[] G)
+	{
+		int n=PUB.n.getlen();
+		FF f=new FF(n);
+		FF.fromBytes(f,F);
+		f.power(PUB.e,PUB.n);
+		f.toBytes(G);
+	}
+
+	/* RSA decryption with the private key */
+	public static void DECRYPT(private_key PRIV,byte[] G,byte[] F)
+	{
+		int n=PRIV.p.getlen();
+		FF g=new FF(2*n);
+
+		FF.fromBytes(g,G);
+		FF jp=g.dmod(PRIV.p);
+		FF jq=g.dmod(PRIV.q);
+
+		jp.skpow(PRIV.dp,PRIV.p);
+		jq.skpow(PRIV.dq,PRIV.q);
+
+		g.zero();
+		g.dscopy(jp);
+		jp.mod(PRIV.q);
+		if (FF.comp(jp,jq)>0) jq.add(PRIV.q);
+		jq.sub(jp);
+		jq.norm();
+
+		FF t=FF.mul(PRIV.c,jq);
+		jq=t.dmod(PRIV.q);
+
+		t=FF.mul(jq,PRIV.p);
+		g.add(t);
+		g.norm();
+
+		g.toBytes(F);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/private_key.java b/src/main/java/org/apache/milagro/amcl/RSA4096/private_key.java
new file mode 100644
index 0000000..1fbc69e
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/private_key.java
@@ -0,0 +1,16 @@
+
+package org.apache.milagro.amcl.RSA4096;
+
+public final class private_key
+{
+    public FF p,q,dp,dq,c;
+	
+	public private_key(int n)
+	{
+		p=new FF(n);
+		q=new FF(n);
+		dp=new FF(n);
+		dq=new FF(n);
+		c=new FF(n);
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/milagro/amcl/RSA4096/public_key.java b/src/main/java/org/apache/milagro/amcl/RSA4096/public_key.java
new file mode 100644
index 0000000..ffa6cb3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/RSA4096/public_key.java
@@ -0,0 +1,14 @@
+
+package org.apache.milagro.amcl.RSA4096;
+
+public final class public_key
+{
+    public int e;
+    public FF n;
+
+	public public_key(int m)
+	{
+		e=0;
+		n=new FF(m);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/BIG.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/BIG.java
new file mode 100644
index 0000000..bab6041
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/BIG.java
@@ -0,0 +1,917 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL BIG number class */ 
+
+package org.apache.milagro.amcl.SECP256K1;
+import org.apache.milagro.amcl.RAND;
+
+public class BIG {
+
+	public static final int CHUNK=64; /* Set word size */
+
+	public static final int MODBYTES=32; //(1+(MODBITS-1)/8);
+	public static final int BASEBITS=56; 
+
+	public static final int NLEN=(1+((8*MODBYTES-1)/BASEBITS));
+	public static final int DNLEN=2*NLEN;
+	public static final long BMASK=(((long)1<<BASEBITS)-1);
+
+	public static final int HBITS=BASEBITS/2;
+	public static final long HMASK=(((long)1<<HBITS)-1);
+	public static final int NEXCESS = ((int)1<<(CHUNK-BASEBITS-1));
+	public static final int BIGBITS=(MODBYTES*8);
+
+
+
+	protected long[] w=new long[NLEN];
+/* Constructors */
+	public BIG()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+	public BIG(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public BIG(long[] x)
+	{
+			for (int i=0;i<NLEN;i++)
+				w[i]=x[i];
+	}
+
+	public long get(int i)
+	{
+		return w[i];
+	}
+
+	public void set(int i,long x)
+	{
+		w[i]=x;
+	} 
+
+
+/* Conditional swap of two bigs depending on d using XOR - no branches */
+	public void cswap(BIG b,int d)
+	{
+		int i;
+		long t,c=(long)d;
+		c=~(c-1);
+
+		for (i=0;i<NLEN;i++)
+		{
+			t=c&(w[i]^b.w[i]);
+			w[i]^=t;
+			b.w[i]^=t;
+		}
+	}
+
+	public void cmove(BIG g,int d)
+	{
+		int i;
+		long t,b=-d;
+
+		for (i=0;i<NLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&b;
+		}
+	}
+
+    public static long cast_to_chunk(int x)
+	{
+		return (long)x;
+	}
+
+/* normalise BIG - force all digits < 2^BASEBITS */
+	public long norm() {
+		long d,carry=0;
+		for (int i=0;i<NLEN-1;i++)
+		{
+			d=w[i]+carry;
+			w[i]=d&BMASK;
+			carry=(d>>BASEBITS);
+		}
+		w[NLEN-1]=(w[NLEN-1]+carry);
+		return (long)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS));  
+	}
+
+/* return number of bits */
+	public int nbits() {
+		BIG t=new BIG(this);
+		int bts,k=NLEN-1;
+		long c;
+		t.norm();
+		while (k>=0 && t.w[k]==0) k--;
+		if (k<0) return 0;
+		bts=BASEBITS*k;
+		c=t.w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+	public String toRawString()
+	{
+		BIG b=new BIG(this);
+		String s="(";
+		for (int i=0;i<NLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[NLEN-1]); s+=")";
+		return s;
+	}
+
+/* Convert to Hex String */
+	public String toString() {
+		BIG b;
+		String s="";
+		int len=nbits();
+
+		if (len%4==0) len/=4;
+		else {len/=4; len++;}
+		if (len<MODBYTES*2) len=MODBYTES*2;
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new BIG(this);
+			b.shr(i*4);
+			s+=Long.toHexString(b.w[0]&15);
+		}
+		return s;
+	}
+
+/* set this[i]+=x*y+c, and return high part */
+
+	public static long[] muladd(long a,long b,long c,long r)
+	{
+		long x0,x1,y0,y1;
+		long[] tb=new long[2];
+		x0=a&HMASK;
+		x1=(a>>HBITS);
+		y0=b&HMASK;
+		y1=(b>>HBITS);
+		long bot=x0*y0;
+		long top=x1*y1;
+		long mid=x0*y1+x1*y0;
+		x0=mid&HMASK;
+		x1=(mid>>HBITS);
+		bot+=x0<<HBITS; bot+=c; bot+=r;
+		top+=x1;
+		long carry=bot>>BASEBITS;
+		bot&=BMASK;
+		top+=carry;
+		tb[0]=top;
+		tb[1]=bot;
+		return tb;
+	}
+
+/* this*=x, where x is >NEXCESS */
+	public long pmul(int c)
+	{
+		long ak,carry=0;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			ak=w[i];
+			w[i]=0;
+
+			cr=muladd(ak,(long)c,carry,w[i]);
+			carry=cr[0];
+			w[i]=cr[1];
+
+		}
+		return carry;
+	}
+
+/* return this*c and catch overflow in DBIG */
+	public DBIG pxmul(int c)
+	{
+		DBIG m=new DBIG(0);	
+		long[] cr=new long[2];
+		long carry=0;
+		for (int j=0;j<NLEN;j++)
+		{
+			cr=muladd(w[j],(long)c,carry,m.w[j]);
+			carry=cr[0];
+			m.w[j]=cr[1];
+		}
+		m.w[NLEN]=carry;		
+		return m;
+	}
+
+/* divide by 3 */
+	public int div3()
+	{	
+		long ak,base,carry=0;
+		norm();
+		base=((long)1<<BASEBITS);
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			ak=(carry*base+w[i]);
+			w[i]=ak/3;
+			carry=ak%3;
+		}
+		return (int)carry;
+	}
+
+/* return a*b where result fits in a BIG */
+	public static BIG smul(BIG a,BIG b)
+	{
+		long carry;
+		long[] cr=new long[2];
+		BIG c=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+				if (i+j<NLEN)
+				{
+					cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+					carry=cr[0];
+					c.w[i+j]=cr[1];
+				}
+		}
+		return c;
+	}
+
+/* return a*b as DBIG */
+/* Inputs must be normed */
+	public static DBIG mul(BIG a,BIG b)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(a.w[i],b.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		return c;
+	}
+
+/* return a^2 as DBIG */
+/* Input must be normed */
+	public static DBIG sqr(BIG a)
+	{
+		DBIG c=new DBIG(0);
+		long carry;
+		long[] cr=new long[2];
+
+		for (int i=0;i<NLEN;i++)
+		{
+			carry=0;
+			for (int j=i+1;j<NLEN;j++)
+			{
+				cr=muladd(2*a.w[i],a.w[j],carry,c.w[i+j]);
+				carry=cr[0];
+				c.w[i+j]=cr[1];
+			}
+			c.w[NLEN+i]=carry;
+		}
+
+		for (int i=0;i<NLEN;i++)
+		{
+			cr=muladd(a.w[i],a.w[i],0,c.w[2*i]);
+			c.w[2*i+1]+=cr[0];
+			c.w[2*i]=cr[1];
+		}
+		c.norm(); 
+		return c;
+	}
+
+	static BIG monty(BIG md,long MC,DBIG d)
+	{
+		BIG b;
+		long m,carry;
+		long[] cr=new long[2];
+		for (int i=0;i<NLEN;i++) 
+		{
+			if (MC==-1) m=(-d.w[i])&BMASK;
+			else
+			{
+				if (MC==1) m=d.w[i];
+				else m=(MC*d.w[i])&BMASK;
+			}
+
+			carry=0;
+			for (int j=0;j<NLEN;j++)
+			{
+				cr=muladd(m,md.w[j],carry,d.w[i+j]);
+				carry=cr[0];
+				d.w[i+j]=cr[1];
+			}
+			d.w[NLEN+i]+=carry;
+		}
+
+		b=new BIG(0);
+		for (int i=0;i<NLEN;i++ )
+			b.w[i]=d.w[NLEN+i];
+		b.norm();
+		return b;		
+	}
+
+
+
+/****************************************************************************/
+
+	public void xortop(long x)
+	{
+		w[NLEN-1]^=x;
+	}
+
+/* set x = x mod 2^m */
+	public void mod2m(int m)
+	{
+		int i,wd,bt;
+		wd=m/BASEBITS;
+		bt=m%BASEBITS;
+		w[wd]&=((cast_to_chunk(1)<<bt)-1);
+		for (i=wd+1;i<NLEN;i++) w[i]=0;
+	}
+
+/* return n-th bit */
+	public int bit(int n)
+	{
+		if ((w[n/BASEBITS]&(cast_to_chunk(1)<<(n%BASEBITS)))>0) return 1;
+		else return 0;
+	}
+
+/* Shift right by less than a word */
+	public int fshr(int k) {
+		int r=(int)(w[0]&((cast_to_chunk(1)<<k)-1)); /* shifted out part */
+		for (int i=0;i<NLEN-1;i++)
+			w[i]=(w[i]>>k)|((w[i+1]<<(BASEBITS-k))&BMASK);
+		w[NLEN-1]=w[NLEN-1]>>k;
+		return r;
+	}
+
+/* Shift right by less than a word */
+	public int fshl(int k) {
+		w[NLEN-1]=((w[NLEN-1]<<k))|(w[NLEN-2]>>(BASEBITS-k));
+		for (int i=NLEN-2;i>0;i--)
+			w[i]=((w[i]<<k)&BMASK)|(w[i-1]>>(BASEBITS-k));
+		w[0]=(w[0]<<k)&BMASK; 
+		return (int)(w[NLEN-1]>>((8*MODBYTES)%BASEBITS)); /* return excess - only used in FF.java */
+	}
+
+/* test for zero */
+	public boolean iszilch() {
+		for (int i=0;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* set to zero */
+	public void zero()
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* set to one */
+	public void one()
+	{
+		w[0]=1;
+		for (int i=1;i<NLEN;i++)
+			w[i]=0;
+	}
+
+/* Test for equal to one */
+	public boolean isunity()
+	{
+		for (int i=1;i<NLEN;i++)
+			if (w[i]!=0) return false;
+		if (w[0]!=1) return false;
+		return true;
+	}
+
+/* Copy from another BIG */
+	public void copy(BIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* general shift right */
+	public void shr(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;	
+		for (int i=0;i<NLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BASEBITS-n))&BMASK);
+		if (NLEN>m) w[NLEN-m-1]=w[NLEN-1]>>n;
+		for (int i=NLEN-m;i<NLEN;i++) w[i]=0;
+	}
+
+/* general shift left */
+	public void shl(int k) {
+		int n=k%BASEBITS;
+		int m=k/BASEBITS;
+
+		w[NLEN-1]=((w[NLEN-1-m]<<n));
+		if (NLEN>=m+2) w[NLEN-1]|=(w[NLEN-m-2]>>(BASEBITS-n));
+
+		for (int i=NLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BMASK)|(w[i-m-1]>>(BASEBITS-n));
+		w[m]=(w[0]<<n)&BMASK;
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* return this+x */
+	public BIG plus(BIG x) {
+		BIG s=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			s.w[i]=w[i]+x.w[i];
+		return s;
+	}
+
+/* this+=x */
+	public void add(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]+=x.w[i];
+	}
+
+/* this|=x */
+	public void or(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]|=x.w[i];
+	}
+
+
+/* this+=x, where x is int */
+	public void inc(int x) {
+		norm();
+		w[0]+=x;
+	}
+
+/* this+=x, where x is long */
+	public void incl(long x) {
+		norm();
+		w[0]+=x;
+	}	
+
+/* return this.x */
+	public BIG minus(BIG x) {
+		BIG d=new BIG(0);
+		for (int i=0;i<NLEN;i++)
+			d.w[i]=w[i]-x.w[i];
+		return d;
+	}
+
+/* this-=x */
+	public void sub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+/* reverse subtract this=x-this */
+	public void rsub(BIG x) {
+		for (int i=0;i<NLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* this-=x where x is int */
+	public void dec(int x) {
+		norm();
+		w[0]-=x;
+	}
+
+/* this*=x, where x is small int<NEXCESS */
+	public void imul(int c)
+	{
+		for (int i=0;i<NLEN;i++) w[i]*=c;
+	}
+
+/* convert this BIG to byte array */
+	public void tobytearray(byte[] b,int n)
+	{
+		
+		BIG c=new BIG(this);
+		c.norm();
+
+		for (int i=MODBYTES-1;i>=0;i--)
+		{
+			b[i+n]=(byte)c.w[0];
+			c.fshr(8);
+		}
+	}
+
+/* convert from byte array to BIG */
+	public static BIG frombytearray(byte[] b,int n)
+	{
+		BIG m=new BIG(0);
+
+		for (int i=0;i<MODBYTES;i++)
+		{
+			m.fshl(8); m.w[0]+=(int)b[i+n]&0xff;
+			//m.inc((int)b[i]&0xff);
+		}
+		return m; 
+	}
+
+	public void toBytes(byte[] b)
+	{
+		tobytearray(b,0);
+	}
+
+	public static BIG fromBytes(byte[] b)
+	{
+		return frombytearray(b,0);
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(BIG a,BIG b)
+	{
+		for (int i=NLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* Arazi and Qi inversion mod 256 */
+	public static int invmod256(int a)
+	{
+		int U,t1,t2,b,c;
+		t1=0;
+		c=(a>>1)&1;  
+		t1+=c;
+		t1&=1;
+		t1=2-t1;
+		t1<<=1;
+		U=t1+1;
+
+// i=2
+		b=a&3;
+		t1=U*b; t1>>=2;
+		c=(a>>2)&3;
+		t2=(U*c)&3;
+		t1+=t2;
+		t1*=U; t1&=3;
+		t1=4-t1;
+		t1<<=2;
+		U+=t1;
+
+// i=4
+		b=a&15;
+		t1=U*b; t1>>=4;
+		c=(a>>4)&15;
+		t2=(U*c)&15;
+		t1+=t2;
+		t1*=U; t1&=15;
+		t1=16-t1;
+		t1<<=4;
+		U+=t1;
+
+		return U;
+	}
+
+/* a=1/a mod 2^256. This is very fast! */
+	public void invmod2m()
+	{
+		int i;
+		BIG U=new BIG(0);
+		BIG b=new BIG(0);
+		BIG c=new BIG(0);
+
+		U.inc(invmod256(lastbits(8)));
+
+		for (i=8;i<BIGBITS;i<<=1)
+		{
+			U.norm();
+			b.copy(this); b.mod2m(i);
+			BIG t1=BIG.smul(U,b); 
+			t1.shr(i);
+
+			c.copy(this); c.shr(i); c.mod2m(i);
+			BIG t2=BIG.smul(U,c); t2.mod2m(i);
+
+			t1.add(t2);
+			t1.norm();
+			b=BIG.smul(t1,U); t1.copy(b);
+			t1.mod2m(i);
+
+			t2.one(); t2.shl(i); t1.rsub(t2); t1.norm();
+
+			t1.shl(i);
+			U.add(t1);
+		}
+		U.mod2m(BIGBITS);
+		copy(U);
+		norm();
+	}
+
+/* reduce this mod m */
+	public void mod(BIG m1)
+	{
+		int k=0;  
+		BIG r=new BIG(0);
+		BIG m=new BIG(m1);
+
+		norm();
+		if (comp(this,m)<0) return;
+		do
+		{
+			m.fshl(1);
+			k++;
+		} while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.fshr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1)));
+			k--;
+		}
+	}
+
+/* divide this by m */
+	public void div(BIG m1)
+	{
+		int d,k=0;
+		norm();
+		BIG e=new BIG(1);
+		BIG m=new BIG(m1);
+		BIG b=new BIG(this);
+		BIG r=new BIG(0);
+		zero();
+
+		while (comp(b,m)>=0)
+		{
+			e.fshl(1);
+			m.fshl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.fshr(1);
+			e.fshr(1);
+
+			r.copy(b);
+			r.sub(m);
+			r.norm();
+			d=(int)(1-((r.w[NLEN-1]>>(CHUNK-1))&1));
+			b.cmove(r,d);
+			r.copy(this);
+			r.add(e);
+			r.norm();
+			cmove(r,d);
+			k--;
+		}
+	}
+
+/* return parity */
+	public int parity()
+	{
+		return (int)(w[0]%2);
+	}
+
+/* return n last bits */
+	public int lastbits(int n)
+	{
+		int msk=(1<<n)-1;
+		norm();
+		return ((int)w[0])&msk;
+	}
+
+/* get 8*MODBYTES size random number */
+	public static BIG random(RAND rng)
+	{
+		BIG m=new BIG(0);
+		int i,b,j=0,r=0;
+
+/* generate random BIG */ 
+		for (i=0;i<8*MODBYTES;i++)   
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			m.shl(1); m.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		return m;
+	}
+
+/* Create random BIG in portable way, one bit at a time */
+	public static BIG randomnum(BIG q,RAND rng) 
+	{
+		DBIG d=new DBIG(0);
+		int i,b,j=0,r=0;
+		for (i=0;i<2*q.nbits();i++)
+		{
+			if (j==0) r=rng.getByte();
+			else r>>=1;
+
+			b=r&1;
+			d.shl(1); d.w[0]+=b;// m.inc(b);
+			j++; j&=7; 
+		}
+		BIG m=d.mod(q);
+		return m;
+	}
+
+/* return a*b mod m */
+	public static BIG modmul(BIG a1,BIG b1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		BIG b=new BIG(b1);
+		a.mod(m);
+		b.mod(m);
+		DBIG d=mul(a,b);
+		return d.mod(m);
+	}
+
+/* return a^2 mod m */
+	public static BIG modsqr(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		DBIG d=sqr(a);
+		return d.mod(m);
+	}
+
+/* return -a mod m */
+	public static BIG modneg(BIG a1,BIG m)
+	{
+		BIG a=new BIG(a1);
+		a.mod(m);
+		return m.minus(a);
+	}
+
+/* return this^e mod m */
+	public BIG powmod(BIG e1,BIG m)
+	{
+		BIG e=new BIG(e1);
+		int bt;
+		norm();
+		e.norm();
+		BIG a=new BIG(1);
+		BIG z=new BIG(e);
+		BIG s=new BIG(this);
+		while (true)
+		{
+			bt=z.parity();
+			z.fshr(1);
+			if (bt==1) a=modmul(a,s,m);
+			if (z.iszilch()) break;
+			s=modsqr(s,m);
+		}
+		return a;
+	}
+
+/* Jacobi Symbol (this/p). Returns 0, 1 or -1 */
+	public int jacobi(BIG p)
+	{
+		int n8,k,m=0;
+		BIG t=new BIG(0);
+		BIG x=new BIG(0);
+		BIG n=new BIG(0);
+		BIG zilch=new BIG(0);
+		BIG one=new BIG(1);
+		if (p.parity()==0 || comp(this,zilch)==0 || comp(p,one)<=0) return 0;
+		norm();
+		x.copy(this);
+		n.copy(p);
+		x.mod(p);
+
+		while (comp(n,one)>0)
+		{
+			if (comp(x,zilch)==0) return 0;
+			n8=n.lastbits(3);
+			k=0;
+			while (x.parity()==0)
+			{
+				k++;
+				x.shr(1);
+			}
+			if (k%2==1) m+=(n8*n8-1)/8;
+			m+=(n8-1)*(x.lastbits(2)-1)/4;
+			t.copy(n);
+			t.mod(x);
+			n.copy(x);
+			x.copy(t);
+			m%=2;
+
+		}
+		if (m==0) return 1;
+		else return -1;
+	}
+
+/* this=1/this mod p. Binary method */
+	public void invmodp(BIG p)
+	{
+		mod(p);
+		BIG u=new BIG(this);
+		BIG v=new BIG(p);
+		BIG x1=new BIG(1);
+		BIG x2=new BIG(0);
+		BIG t=new BIG(0);
+		BIG one=new BIG(1);
+
+		while (comp(u,one)!=0 && comp(v,one)!=0)
+		{
+			while (u.parity()==0)
+			{
+				u.fshr(1);
+				if (x1.parity()!=0)
+				{
+					x1.add(p);
+					x1.norm();
+				}
+				x1.fshr(1);
+			}
+			while (v.parity()==0)
+			{
+				v.fshr(1);
+				if (x2.parity()!=0)
+				{
+					x2.add(p);
+					x2.norm();
+				}
+				x2.fshr(1);
+			}
+			if (comp(u,v)>=0)
+			{
+				u.sub(v);
+				u.norm();
+				if (comp(x1,x2)>=0) x1.sub(x2);
+				else
+				{
+					t.copy(p);
+					t.sub(x2);
+					x1.add(t);
+				}
+				x1.norm();
+			}
+			else
+			{
+				v.sub(u);
+				v.norm();
+				if (comp(x2,x1)>=0) x2.sub(x1);
+				else
+				{
+					t.copy(p);
+					t.sub(x1);
+					x2.add(t);
+				}
+				x2.norm();
+			}
+		}
+		if (comp(u,one)==0) copy(x1);
+		else copy(x2);
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/DBIG.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/DBIG.java
new file mode 100644
index 0000000..a66adff
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/DBIG.java
@@ -0,0 +1,279 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* AMCL double length DBIG number class */ 
+
+package org.apache.milagro.amcl.SECP256K1;
+
+public class DBIG {
+	protected long[] w=new long[BIG.DNLEN];
+
+/* normalise this */
+	public void norm() {
+		long d,carry=0;
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			d=w[i]+carry;
+			carry=d>>BIG.BASEBITS;
+			w[i]=d&BIG.BMASK;
+		}
+		w[BIG.DNLEN-1]=(w[BIG.DNLEN-1]+carry);
+	}
+
+
+/*
+	public String toRawString()
+	{
+		DBIG b=new DBIG(this);
+		String s="(";
+		for (int i=0;i<BIG.DNLEN-1;i++)
+		{
+			s+=Long.toHexString(b.w[i]); s+=",";
+		}
+		s+=Long.toHexString(b.w[BIG.DNLEN-1]); s+=")";
+		return s;
+	}
+*/
+
+/* split DBIG at position n, return higher half, keep lower half */
+	public BIG split(int n)
+	{
+		BIG t=new BIG(0);
+		int m=n%BIG.BASEBITS;
+		long nw,carry=w[BIG.DNLEN-1]<<(BIG.BASEBITS-m);
+
+		for (int i=BIG.DNLEN-2;i>=BIG.NLEN-1;i--)
+		{
+			nw=(w[i]>>m)|carry;
+			carry=(w[i]<<(BIG.BASEBITS-m))&BIG.BMASK;
+			t.w[i-BIG.NLEN+1]=nw;
+			//t.set(i-BIG.NLEN+1,nw);
+		}
+		w[BIG.NLEN-1]&=(((long)1<<m)-1);
+		return t;
+	}
+
+/****************************************************************************/
+
+/* return number of bits in this */
+	public int nbits() {
+		int bts,k=BIG.DNLEN-1;
+		long c;
+		norm();
+		while (w[k]==0 && k>=0) k--;
+		if (k<0) return 0;
+		bts=BIG.BASEBITS*k;
+		c=w[k];
+		while (c!=0) {c/=2; bts++;}
+		return bts;
+	}
+
+/* convert this to string */
+	public String toString() {
+		DBIG b;
+		String s="";
+		int len=nbits();
+		if (len%4==0) len>>=2; //len/=4;
+		else {len>>=2; len++;}
+
+		for (int i=len-1;i>=0;i--)
+		{
+			b=new DBIG(this);
+			b.shr(i*4);
+			s+=Integer.toHexString((int)(b.w[0]&15));
+		}
+		return s;
+	}
+
+	public void cmove(DBIG g,int d)
+	{
+		int i;
+		for (i=0;i<BIG.DNLEN;i++)
+		{
+			w[i]^=(w[i]^g.w[i])&BIG.cast_to_chunk(-d);
+		}
+	}
+
+/* Constructors */
+	public DBIG(int x)
+	{
+		w[0]=x;
+		for (int i=1;i<BIG.DNLEN;i++)
+			w[i]=0;
+	}
+
+	public DBIG(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+	public DBIG(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN-1;i++)
+			w[i]=x.w[i]; //get(i);
+
+		w[BIG.NLEN-1]=x.w[(BIG.NLEN-1)]&BIG.BMASK; /* top word normalized */
+		w[BIG.NLEN]=(x.w[(BIG.NLEN-1)]>>BIG.BASEBITS);
+
+		for (int i=BIG.NLEN+1;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* Copy from another DBIG */
+	public void copy(DBIG x)
+	{
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i];
+	}
+
+/* Copy into upper part */
+	public void ucopy(BIG x)
+	{
+		for (int i=0;i<BIG.NLEN;i++)
+			w[i]=0;
+		for (int i=BIG.NLEN;i<BIG.DNLEN;i++)
+			w[i]=x.w[i-BIG.NLEN];
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		for (int i=0;i<BIG.DNLEN;i++)
+			if (w[i]!=0) return false;
+		return true; 
+	}
+
+/* shift this right by k bits */
+	public void shr(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;	
+		for (int i=0;i<BIG.DNLEN-m-1;i++)
+			w[i]=(w[m+i]>>n)|((w[m+i+1]<<(BIG.BASEBITS-n))&BIG.BMASK);
+		w[BIG.DNLEN-m-1]=w[BIG.DNLEN-1]>>n;
+		for (int i=BIG.DNLEN-m;i<BIG.DNLEN;i++) w[i]=0;
+	}
+
+/* shift this left by k bits */
+	public void shl(int k) {
+		int n=k%BIG.BASEBITS;
+		int m=k/BIG.BASEBITS;
+
+		w[BIG.DNLEN-1]=((w[BIG.DNLEN-1-m]<<n))|(w[BIG.DNLEN-m-2]>>(BIG.BASEBITS-n));
+		for (int i=BIG.DNLEN-2;i>m;i--)
+			w[i]=((w[i-m]<<n)&BIG.BMASK)|(w[i-m-1]>>(BIG.BASEBITS-n));
+		w[m]=(w[0]<<n)&BIG.BMASK; 
+		for (int i=0;i<m;i++) w[i]=0;
+	}
+
+/* this+=x */
+	public void add(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]+=x.w[i];	
+	}
+
+/* this-=x */
+	public void sub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]-=x.w[i];
+	}
+
+	public void rsub(DBIG x) {
+		for (int i=0;i<BIG.DNLEN;i++)
+			w[i]=x.w[i]-w[i];
+	}
+
+/* Compare a and b, return 0 if a==b, -1 if a<b, +1 if a>b. Inputs must be normalised */
+	public static int comp(DBIG a,DBIG b)
+	{
+		for (int i=BIG.DNLEN-1;i>=0;i--)
+		{
+			if (a.w[i]==b.w[i]) continue;
+			if (a.w[i]>b.w[i]) return 1;
+			else  return -1;
+		}
+		return 0;
+	}
+
+/* reduces this DBIG mod a BIG, and returns the BIG */
+	public BIG mod(BIG c)
+	{
+		int k=0;  
+		norm();
+		DBIG m=new DBIG(c);
+		DBIG r=new DBIG(0);
+
+		if (comp(this,m)<0) return new BIG(this);
+		
+		do
+		{
+			m.shl(1);
+			k++;
+		}
+		while (comp(this,m)>=0);
+
+		while (k>0)
+		{
+			m.shr(1);
+
+			r.copy(this);
+			r.sub(m);
+			r.norm();
+			cmove(r,(int)(1-((r.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1)));
+
+			k--;
+		}
+		return new BIG(this);
+	}
+
+/* return this/c */
+	public BIG div(BIG c)
+	{
+		int d,k=0;
+		DBIG m=new DBIG(c);
+		DBIG dr=new DBIG(0);
+		BIG r=new BIG(0);
+		BIG a=new BIG(0);
+		BIG e=new BIG(1);
+		norm();
+
+		while (comp(this,m)>=0)
+		{
+			e.fshl(1);
+			m.shl(1);
+			k++;
+		}
+
+		while (k>0)
+		{
+			m.shr(1);
+			e.shr(1);
+
+			dr.copy(this);
+			dr.sub(m);
+			dr.norm();
+			d=(int)(1-((dr.w[BIG.DNLEN-1]>>(BIG.CHUNK-1))&1));
+			cmove(dr,d);
+			r.copy(a);
+			r.add(e);
+			r.norm();
+			a.cmove(r,d);
+			k--;
+		}
+		return a;
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/ECDH.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/ECDH.java
new file mode 100644
index 0000000..485dfeb
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/ECDH.java
@@ -0,0 +1,594 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve API high-level functions  */
+
+package org.apache.milagro.amcl.SECP256K1;
+
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.HASH256;
+import org.apache.milagro.amcl.HASH384;
+import org.apache.milagro.amcl.HASH512;
+import org.apache.milagro.amcl.AES;
+
+public final class ECDH {
+	public static final int INVALID_PUBLIC_KEY=-2;
+	public static final int ERROR=-3;
+	public static final int INVALID=-4;
+	public static final int EFS=BIG.MODBYTES;
+	public static final int EGS=BIG.MODBYTES;
+//	public static final int EAS=16;
+//	public static final int EBS=16;
+
+//	public static final int SHA256=32;
+//	public static final int SHA384=48;
+//	public static final int SHA512=64;
+
+
+//	public static final int HASH_TYPE=SHA512;
+
+
+/* Convert Integer to n-byte array */
+	public static byte[] inttoBytes(int n,int len)
+	{
+		int i;
+		byte[] b=new byte[len];
+
+		for (i=0;i<len;i++) b[i]=0;
+		i=len; 
+		while (n>0 && i>0)
+		{
+			i--;
+			b[i]=(byte)(n&0xff);
+			n/=256;
+		}	
+		return b;
+	}
+
+	public static byte[] hashit(int sha,byte[] A,int n,byte[] B,int pad)
+	{
+		byte[] R=null;
+
+		if (sha==ECP.SHA256)
+		{
+			HASH256 H=new HASH256();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA384)
+		{
+			HASH384 H=new HASH384();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (sha==ECP.SHA512)
+		{
+			HASH512 H=new HASH512();
+			H.process_array(A); if (n>0) H.process_num(n);
+			if (B!=null) H.process_array(B);
+			R=H.hash();
+		}
+		if (R==null) return null;
+
+		if (pad==0) return R;
+/* If pad>0 output is truncated or padded to pad bytes */
+		byte[] W=new byte[pad];
+		if (pad<=sha) 
+		{
+			for (int i=0;i<pad;i++) W[i]=R[i];
+		}
+		else
+		{
+			for (int i=0;i<sha;i++) W[i+pad-sha]=R[i];
+            for (int i=0;i<pad-sha;i++) W[i]=0;
+ 
+			//for (int i=0;i<sha;i++) W[i]=R[i];
+			//for (int i=sha;i<pad;i++) W[i]=0;
+		}
+		return W;
+	}
+
+/* Key Derivation Functions */
+/* Input octet Z */
+/* Output key of length olen */
+	public static byte[] KDF1(int sha,byte[] Z,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output K in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=0;counter<cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,null,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+		return K;
+	}
+
+	public static byte[] KDF2(int sha,byte[] Z,byte[] P,int olen)
+	{
+/* NOTE: the parameter olen is the length of the output k in bytes */
+		int hlen=sha;
+		byte[] K=new byte[olen];
+		byte[] B;
+		int counter,cthreshold,k=0;
+    
+		for (int i=0;i<K.length;i++) K[i]=0;
+
+		cthreshold=olen/hlen; if (olen%hlen!=0) cthreshold++;
+
+		for (counter=1;counter<=cthreshold;counter++)
+		{
+			B=hashit(sha,Z,counter,P,0);
+			if (k+hlen>olen) for (int i=0;i<olen%hlen;i++) K[k++]=B[i];
+			else for (int i=0;i<hlen;i++) K[k++]=B[i];
+		}
+
+		return K;
+	}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+	public static byte[] PBKDF2(int sha,byte[] Pass,byte[] Salt,int rep,int olen)
+	{
+		int i,j,k,len,d,opt;
+		d=olen/sha; if (olen%sha!=0) d++;
+		byte[] F=new byte[sha];
+		byte[] U=new byte[sha];
+		byte[] S=new byte[Salt.length+4];
+
+		byte[] K=new byte[d*sha];
+		opt=0;
+
+		for (i=1;i<=d;i++)
+		{
+			for (j=0;j<Salt.length;j++) S[j]=Salt[j];
+			byte[] N=inttoBytes(i,4);
+			for (j=0;j<4;j++) S[Salt.length+j]=N[j];
+
+			HMAC(sha,S,Pass,F);
+
+			for (j=0;j<sha;j++) U[j]=F[j];
+			for (j=2;j<=rep;j++)
+			{
+				HMAC(sha,U,Pass,U);
+				for (k=0;k<sha;k++) F[k]^=U[k];
+			}
+			for (j=0;j<sha;j++) K[opt++]=F[j];
+		}
+		byte[] key=new byte[olen];
+		for (i=0;i<olen;i++) key[i]=K[i];
+		return key;
+	}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+	public static int HMAC(int sha,byte[] M,byte[] K,byte[] tag)
+	{
+	/* Input is from an octet m        *
+	* olen is requested output length in bytes. k is the key  *
+	* The output is the calculated tag */
+		int b=64;
+		if (sha>32) b=128;
+		byte[] B;
+		byte[] K0=new byte[b];
+		int olen=tag.length;
+
+		//b=K0.length;
+		if (olen<4 /*|| olen>sha*/) return 0;
+
+		for (int i=0;i<b;i++) K0[i]=0;
+
+		if (K.length > b) 
+		{
+			B=hashit(sha,K,0,null,0);
+			for (int i=0;i<sha;i++) K0[i]=B[i];
+		}
+		else
+			for (int i=0;i<K.length;i++ ) K0[i]=K[i];
+		
+		for (int i=0;i<b;i++) K0[i]^=0x36;
+		B=hashit(sha,K0,0,M,0);
+
+		for (int i=0;i<b;i++) K0[i]^=0x6a;
+		B=hashit(sha,K0,0,B,olen);
+
+		for (int i=0;i<olen;i++) tag[i]=B[i];
+
+		return 1;
+	}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns ciphertext */
+	public static byte[] AES_CBC_IV0_ENCRYPT(byte[] K,byte[] M)
+	{ /* AES CBC encryption, with Null IV and key K */
+	/* Input is from an octet string M, output is to an octet string C */
+	/* Input is padded as necessary to make up a full final block */
+		AES a=new AES();
+		boolean fin;
+		int i,j,ipt,opt;
+		byte[] buff=new byte[16];
+		int clen=16+(M.length/16)*16;
+
+		byte[] C=new byte[clen];
+		int padlen;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		ipt=opt=0;
+		fin=false;
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				if (ipt<M.length) buff[i]=M[ipt++];
+				else {fin=true; break;}
+			}
+			if (fin) break;
+			a.encrypt(buff);
+			for (i=0;i<16;i++)
+				C[opt++]=buff[i];
+		}    
+
+/* last block, filled up to i-th index */
+
+		padlen=16-i;
+		for (j=i;j<16;j++) buff[j]=(byte)padlen;
+
+		a.encrypt(buff);
+
+		for (i=0;i<16;i++)
+			C[opt++]=buff[i];
+		a.end();    
+		return C;
+	}
+
+/* returns plaintext if all consistent, else returns null string */
+	public static byte[] AES_CBC_IV0_DECRYPT(byte[] K,byte[] C)
+	{ /* padding is removed */
+		AES a=new AES();
+		int i,ipt,opt,ch;
+		byte[] buff=new byte[16];
+		byte[] MM=new byte[C.length];
+		boolean fin,bad;
+		int padlen;
+		ipt=opt=0;
+
+		a.init(AES.CBC,K.length,K,null);
+
+		if (C.length==0) return new byte[0];
+		ch=C[ipt++]; 
+  
+		fin=false;
+
+		for(;;)
+		{
+			for (i=0;i<16;i++)
+			{
+				buff[i]=(byte)ch;      
+				if (ipt>=C.length) {fin=true; break;}  
+				else ch=C[ipt++];  
+			}
+			a.decrypt(buff);
+			if (fin) break;
+			for (i=0;i<16;i++)
+				MM[opt++]=buff[i];
+		}    
+
+		a.end();
+		bad=false;
+		padlen=buff[15];
+		if (i!=15 || padlen<1 || padlen>16) bad=true;
+		if (padlen>=2 && padlen<=16)
+			for (i=16-padlen;i<16;i++) if (buff[i]!=padlen) bad=true;
+    
+		if (!bad) for (i=0;i<16-padlen;i++)
+					MM[opt++]=buff[i];
+
+		if (bad) return new byte[0];
+
+		byte[] M=new byte[opt];
+		for (i=0;i<opt;i++) M[i]=MM[i];
+
+		return M;
+	}
+
+/* Calculate a public/private EC GF(p) key pair W,S where W=S.G mod EC(p),
+ * where S is the secret key and W is the public key
+ * and G is fixed generator.
+ * If RNG is NULL then the private key is provided externally in S
+ * otherwise it is generated randomly internally */
+	public static int KEY_PAIR_GENERATE(RAND RNG,byte[] S,byte[] W)
+	{
+		BIG r,s;
+		ECP G,WP;
+		int res=0;
+	//	byte[] T=new byte[EFS];
+
+		G=ECP.generator();
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (RNG==null)
+		{
+			s=BIG.fromBytes(S);
+			s.mod(r);
+		}
+		else
+		{
+			s=BIG.randomnum(r,RNG);
+		}
+
+		//if (ROM.AES_S>0)
+		//{
+		//	s.mod2m(2*ROM.AES_S);
+		//}
+		s.toBytes(S);
+
+		WP=G.mul(s);
+		WP.toBytes(W,false);  // To use point compression on public keys, change to true 
+
+		return res;
+	}
+
+/* validate public key. */
+	public static int PUBLIC_KEY_VALIDATE(byte[] W)
+	{
+		BIG r,q,k;
+		ECP WP=ECP.fromBytes(W);
+		int nb,res=0;
+
+		r=new BIG(ROM.CURVE_Order);
+
+		if (WP.is_infinity()) res=INVALID_PUBLIC_KEY;
+
+		if (res==0)
+		{
+
+			q=new BIG(ROM.Modulus);
+			nb=q.nbits();
+			k=new BIG(1); k.shl((nb+4)/2);
+			k.add(q);
+			k.div(r);
+
+			while (k.parity()==0)
+			{
+				k.shr(1);
+				WP.dbl();
+			}
+
+			if (!k.isunity()) WP=WP.mul(k);
+			if (WP.is_infinity()) res=INVALID_PUBLIC_KEY; 
+		}
+		return res;
+	}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+	public static int SVDP_DH(byte[] S,byte[] WD,byte[] Z)    
+	{
+		BIG r,s,wx,wy,z;
+		int valid;
+		ECP W;
+		int res=0;
+		byte[] T=new byte[EFS];
+
+		s=BIG.fromBytes(S);
+
+		W=ECP.fromBytes(WD);
+		if (W.is_infinity()) res=ERROR;
+
+		if (res==0)
+		{
+			r=new BIG(ROM.CURVE_Order);
+			s.mod(r);
+
+			W=W.mul(s);
+			if (W.is_infinity()) res=ERROR; 
+			else 
+			{
+				W.getX().toBytes(T);
+				for (int i=0;i<EFS;i++) Z[i]=T[i];
+			}
+		}
+		return res;
+	}
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+	public static int SP_DSA(int sha,RAND RNG,byte[] S,byte[] F,byte[] C,byte[] D)
+	{
+		byte[] T=new byte[EFS];
+		BIG r,s,f,c,d,u,vx,w;
+		ECP G,V;
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		s=BIG.fromBytes(S);
+		f=BIG.fromBytes(B);
+
+		c=new BIG(0);
+		d=new BIG(0);
+		V=new ECP();
+
+		do {
+			u=BIG.randomnum(r,RNG);
+			w=BIG.randomnum(r,RNG); /* side channel masking */
+			//if (ROM.AES_S>0)
+			//{
+			//	u.mod2m(2*ROM.AES_S);
+			//}			
+			V.copy(G);
+			V=V.mul(u);   		
+			vx=V.getX();
+			c.copy(vx);
+			c.mod(r);
+			if (c.iszilch()) continue;
+
+			u.copy(BIG.modmul(u,w,r));
+
+			u.invmodp(r);
+			d.copy(BIG.modmul(s,c,r));
+			d.add(f);
+
+			d.copy(BIG.modmul(d,w,r));
+
+			d.copy(BIG.modmul(u,d,r));
+		} while (d.iszilch());
+       
+		c.toBytes(T);
+		for (int i=0;i<EFS;i++) C[i]=T[i];
+		d.toBytes(T);
+		for (int i=0;i<EFS;i++) D[i]=T[i];
+		return 0;
+	}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified using public key W */
+	public static int VP_DSA(int sha,byte[] W,byte[] F, byte[] C,byte[] D)
+	{
+		BIG r,f,c,d,h2;
+		int res=0;
+		ECP G,WP,P;
+		int valid; 
+
+		byte[] B=hashit(sha,F,0,null,BIG.MODBYTES);
+
+		G=ECP.generator();
+		r=new BIG(ROM.CURVE_Order);
+
+		c=BIG.fromBytes(C);
+		d=BIG.fromBytes(D);
+		f=BIG.fromBytes(B);
+     
+		if (c.iszilch() || BIG.comp(c,r)>=0 || d.iszilch() || BIG.comp(d,r)>=0) 
+            res=INVALID;
+
+		if (res==0)
+		{
+			d.invmodp(r);
+			f.copy(BIG.modmul(f,d,r));
+			h2=BIG.modmul(c,d,r);
+
+			WP=ECP.fromBytes(W);
+			if (WP.is_infinity()) res=ERROR;
+			else
+			{
+				P=new ECP();
+				P.copy(WP);
+				P=P.mul2(h2,G,f);
+				if (P.is_infinity()) res=INVALID;
+				else
+				{
+					d=P.getX();
+					d.mod(r);
+					if (BIG.comp(d,c)!=0) res=INVALID;
+				}
+			}
+		}
+
+		return res;
+	}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and produces ciphertext V,C,T */
+	public static byte[] ECIES_ENCRYPT(int sha,byte[] P1,byte[] P2,RAND RNG,byte[] W,byte[] M,byte[] V,byte[] T)
+	{ 
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] U=new byte[EGS];
+
+		if (KEY_PAIR_GENERATE(RNG,U,V)!=0) return new byte[0];  
+		if (SVDP_DH(U,W,Z)!=0) return new byte[0];     
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] C=AES_CBC_IV0_ENCRYPT(K1,M);
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,T);
+
+		return C;
+	}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key U outputs plaintext M */
+	public static byte[] ECIES_DECRYPT(int sha,byte[] P1,byte[] P2,byte[] V,byte[] C,byte[] T,byte[] U)
+	{ 
+
+		int i,len;
+
+		byte[] Z=new byte[EFS];
+		byte[] VZ=new byte[3*EFS+1];
+		byte[] K1=new byte[ECP.AESKEY];
+		byte[] K2=new byte[ECP.AESKEY];
+		byte[] TAG=new byte[T.length];
+
+		if (SVDP_DH(U,V,Z)!=0) return new byte[0];  
+
+		for (i=0;i<2*EFS+1;i++) VZ[i]=V[i];
+		for (i=0;i<EFS;i++) VZ[2*EFS+1+i]=Z[i];
+
+		byte[] K=KDF2(sha,VZ,P1,2*ECP.AESKEY);
+
+		for (i=0;i<ECP.AESKEY;i++) {K1[i]=K[i]; K2[i]=K[ECP.AESKEY+i];} 
+
+		byte[] M=AES_CBC_IV0_DECRYPT(K1,C); 
+
+		if (M.length==0) return M;
+
+		byte[] L2=inttoBytes(P2.length,8);	
+	
+		byte[] AC=new byte[C.length+P2.length+8];
+
+		for (i=0;i<C.length;i++) AC[i]=C[i];
+		for (i=0;i<P2.length;i++) AC[C.length+i]=P2[i];
+		for (i=0;i<8;i++) AC[C.length+P2.length+i]=L2[i];
+	
+		HMAC(sha,AC,K2,TAG);
+
+		boolean same=true;
+		for (i=0;i<T.length;i++) if (T[i]!=TAG[i]) same=false;
+		if (!same) return new byte[0];
+	
+		return M;
+
+	}
+}
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/ECP.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/ECP.java
new file mode 100644
index 0000000..84a10d3
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/ECP.java
@@ -0,0 +1,1109 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Elliptic Curve Point class */
+
+package org.apache.milagro.amcl.SECP256K1;
+
+public final class ECP {
+
+	public static final int WEIERSTRASS=0;
+	public static final int EDWARDS=1;
+	public static final int MONTGOMERY=2;
+	public static final int NOT=0;
+	public static final int BN=1;
+	public static final int BLS=2;
+	public static final int D_TYPE=0;
+	public static final int M_TYPE=1;
+	public static final int POSITIVEX=0;
+	public static final int NEGATIVEX=1;
+
+	public static final int CURVETYPE=WEIERSTRASS;
+	public static final int CURVE_PAIRING_TYPE=NOT;
+	public static final int SEXTIC_TWIST=NOT;
+	public static final int SIGN_OF_X=NOT;
+
+	public static final int SHA256=32;
+	public static final int SHA384=48;
+	public static final int SHA512=64;
+
+	public static final int HASH_TYPE=32;
+	public static final int AESKEY=16;
+
+	private FP x;
+	private FP y;
+	private FP z;
+//	private boolean INF;
+
+/* Constructor - set to O */
+	public ECP() {
+		//INF=true;
+		x=new FP(0);
+		y=new FP(1);
+		if (CURVETYPE==EDWARDS)
+		{
+			z=new FP(1);
+		}
+		else
+		{
+			z=new FP(0);
+		}
+	}
+
+    public ECP(ECP e) {
+        this.x = new FP(e.x);
+        this.y = new FP(e.y);
+        this.z = new FP(e.z);
+    }
+
+/* test for O point-at-infinity */
+	public boolean is_infinity() {
+//		if (INF) return true;                            // Edits made
+		if (CURVETYPE==EDWARDS)
+		{
+			return (x.iszilch() && y.equals(z));
+		}
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			return (x.iszilch() && z.iszilch());
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return z.iszilch();
+		}
+		return true;
+	}
+/* Conditional swap of P and Q dependant on d */
+	private void cswap(ECP Q,int d)
+	{
+		x.cswap(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cswap(Q.y,d);
+		z.cswap(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		bd=bd&(INF^Q.INF);
+	//		INF^=bd;
+	//		Q.INF^=bd;
+	//	}
+	}
+
+/* Conditional move of Q to P dependant on d */
+	private void cmove(ECP Q,int d)
+	{
+		x.cmove(Q.x,d);
+		if (CURVETYPE!=MONTGOMERY) y.cmove(Q.y,d);
+		z.cmove(Q.z,d);
+	//	if (CURVETYPE!=EDWARDS)
+	//	{
+	//		boolean bd;
+	//		if (d==0) bd=false;
+	//		else bd=true;
+	//		INF^=(INF^Q.INF)&bd;
+	//	}
+	}
+
+/* return 1 if b==c, no branching */
+	private static int teq(int b,int c)
+	{
+		int x=b^c;
+		x-=1;  // if x=0, x now -1
+		return ((x>>31)&1);
+	}
+
+/* Constant time select from pre-computed table */
+	private void select(ECP W[],int b)
+	{
+		ECP MP=new ECP(); 
+		int m=b>>31;
+		int babs=(b^m)-m;
+
+		babs=(babs-1)/2;
+		cmove(W[0],teq(babs,0));  // conditional move
+		cmove(W[1],teq(babs,1));
+		cmove(W[2],teq(babs,2));
+		cmove(W[3],teq(babs,3));
+		cmove(W[4],teq(babs,4));
+		cmove(W[5],teq(babs,5));
+		cmove(W[6],teq(babs,6));
+		cmove(W[7],teq(babs,7));
+ 
+		MP.copy(this);
+		MP.neg();
+		cmove(MP,(int)(m&1));
+	}
+
+/* Test P == Q */
+	public boolean equals(ECP Q) {
+//		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);
+		a.copy(x); a.mul(Q.z); 
+		b.copy(Q.x); b.mul(z); 
+		if (!a.equals(b)) return false;
+		if (CURVETYPE!=MONTGOMERY)
+		{
+			a.copy(y); a.mul(Q.z); 
+			b.copy(Q.y); b.mul(z); 
+			if (!a.equals(b)) return false;
+		}
+		return true;
+	}
+
+/* this=P */
+	public void copy(ECP P)
+	{
+		x.copy(P.x);
+		if (CURVETYPE!=MONTGOMERY) y.copy(P.y);
+		z.copy(P.z);
+		//INF=P.INF;
+	}
+/* this=-this */
+	public void neg() {
+//		if (is_infinity()) return;
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			y.neg(); y.norm();
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+			x.neg(); x.norm();
+		}
+		return;
+	}
+/* set this=O */
+	public void inf() {
+//		INF=true;
+		x.zero();
+		if (CURVETYPE!=MONTGOMERY) y.one();
+		if (CURVETYPE!=EDWARDS) z.zero();
+		else z.one();
+	}
+
+/* Calculate RHS of curve equation */
+	public static FP RHS(FP x) {
+		x.norm();
+		FP r=new FP(x);
+		r.sqr();
+
+		if (CURVETYPE==WEIERSTRASS)
+		{ // x^3+Ax+B
+			FP b=new FP(new BIG(ROM.CURVE_B));
+			r.mul(x);
+			if (ROM.CURVE_A==-3)
+			{
+				FP cx=new FP(x);
+				cx.imul(3);
+				cx.neg(); cx.norm();
+				r.add(cx);
+			}
+			r.add(b);
+		}
+		if (CURVETYPE==EDWARDS)
+		{ // (Ax^2-1)/(Bx^2-1) 
+			FP b=new FP(new BIG(ROM.CURVE_B));
+
+			FP one=new FP(1);
+			b.mul(r);
+			b.sub(one);
+			b.norm();
+			if (ROM.CURVE_A==-1) r.neg();
+			r.sub(one); r.norm();
+			b.inverse();
+
+			r.mul(b);
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{ // x^3+Ax^2+x
+			FP x3=new FP(0);
+			x3.copy(r);
+			x3.mul(x);
+			r.imul(ROM.CURVE_A);
+			r.add(x3);
+			r.add(x);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* set (x,y) from two BIGs */
+	public ECP(BIG ix,BIG iy) {
+		x=new FP(ix);
+		y=new FP(iy);
+		z=new FP(1);
+		FP rhs=RHS(x);
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			if (rhs.jacobi()!=1) inf();
+			//if (rhs.jacobi()==1) INF=false;
+			//else inf();
+		}
+		else
+		{
+			FP y2=new FP(y);
+			y2.sqr();
+			if (!y2.equals(rhs)) inf();
+			//if (y2.equals(rhs)) INF=false;
+			//else inf();
+		}
+	}
+/* set (x,y) from BIG and a bit */
+	public ECP(BIG ix,int s) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			FP ny=rhs.sqrt();
+			if (ny.redc().parity()!=s) ny.neg();
+			y.copy(ny);
+			//INF=false;
+		}
+		else inf();
+	}
+
+/* set from x - calculate y from curve equation */
+	public ECP(BIG ix) {
+		x=new FP(ix);
+		FP rhs=RHS(x);
+		y=new FP(0);
+		z=new FP(1);
+		if (rhs.jacobi()==1)
+		{
+			if (CURVETYPE!=MONTGOMERY) y.copy(rhs.sqrt());
+			//INF=false;
+		}
+		else inf(); //INF=true;
+	}
+
+/* set to affine - from (x,y,z) to (x,y) */
+	public void affine() {
+		if (is_infinity()) return;	// 
+		FP one=new FP(1);
+		if (z.equals(one)) return;
+		z.inverse();
+		x.mul(z); x.reduce();
+		if (CURVETYPE!=MONTGOMERY)            // Edits made
+		{
+			y.mul(z); y.reduce();
+		}
+		z.copy(one);
+	}
+/* extract x as a BIG */
+	public BIG getX()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.x.redc();
+	}
+/* extract y as a BIG */
+	public BIG getY()
+	{
+		ECP W=new ECP(this);
+		W.affine();
+		return W.y.redc();
+	}
+
+/* get sign of Y */
+	public int getS()
+	{
+		//affine();
+		BIG y=getY();
+		return y.parity();
+	}
+/* extract x as an FP */
+	public FP getx()
+	{
+		return x;
+	}
+/* extract y as an FP */
+	public FP gety()
+	{
+		return y;
+	}
+/* extract z as an FP */
+	public FP getz()
+	{
+		return z;
+	}
+/* convert to byte array */
+	public void toBytes(byte[] b,boolean compress)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		ECP W=new ECP(this);
+		W.affine();
+
+		W.x.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+1]=t[i];
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			b[0]=0x06;
+			return;
+		}
+
+		if (compress)
+		{
+			b[0]=0x02;
+			if (y.redc().parity()==1) b[0]=0x03;
+			return;
+		}
+
+		b[0]=0x04;
+
+		W.y.redc().toBytes(t);
+		for (int i=0;i<BIG.MODBYTES;i++) b[i+BIG.MODBYTES+1]=t[i];
+	}
+/* convert from byte array to point */
+	public static ECP fromBytes(byte[] b)
+	{
+		byte[] t=new byte[BIG.MODBYTES];
+		BIG p=new BIG(ROM.Modulus);
+
+		for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+1];
+		BIG px=BIG.fromBytes(t);
+		if (BIG.comp(px,p)>=0) return new ECP();
+
+		if (CURVETYPE==MONTGOMERY)
+		{
+			return new ECP(px);
+		}
+
+		if (b[0]==0x04)
+		{
+			for (int i=0;i<BIG.MODBYTES;i++) t[i]=b[i+BIG.MODBYTES+1];
+			BIG py=BIG.fromBytes(t);
+			if (BIG.comp(py,p)>=0) return new ECP();
+			return new ECP(px,py);
+		}
+
+		if (b[0]==0x02 || b[0]==0x03)
+		{
+			return new ECP(px,(int)(b[0]&1));
+		}
+		return new ECP();
+	}
+/* convert to hex string */
+	public String toString() {
+		ECP W=new ECP(this);	
+		W.affine();
+		if (W.is_infinity()) return "infinity";
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+")";
+	}
+
+/* convert to hex string */
+	public String toRawString() {
+		//if (is_infinity()) return "infinity";
+		//affine();
+		ECP W=new ECP(this);	
+		if (CURVETYPE==MONTGOMERY) return "("+W.x.redc().toString()+","+W.z.redc().toString()+")";
+		else return "("+W.x.redc().toString()+","+W.y.redc().toString()+","+W.z.redc().toString()+")";
+	}
+
+/* this*=2 */
+	public void dbl() {
+//		if (INF) return;
+		
+		if (CURVETYPE==WEIERSTRASS)
+		{
+			if (ROM.CURVE_A==0)
+			{
+//System.out.println("Into dbl");
+				FP t0=new FP(y);                      /*** Change ***/    // Edits made
+				t0.sqr();
+				FP t1=new FP(y);
+				t1.mul(z);
+				FP t2=new FP(z);
+				t2.sqr();
+
+				z.copy(t0);
+				z.add(t0); z.norm(); 
+				z.add(z); z.add(z); z.norm();
+				t2.imul(3*ROM.CURVE_B_I);
+
+				FP x3=new FP(t2);
+				x3.mul(z);
+
+				FP y3=new FP(t0);
+				y3.add(t2); y3.norm();
+				z.mul(t1); 
+				t1.copy(t2); t1.add(t2); t2.add(t1);
+				t0.sub(t2); t0.norm(); y3.mul(t0); y3.add(x3);
+				t1.copy(x); t1.mul(y); 
+				x.copy(t0); x.norm(); x.mul(t1); x.add(x);
+				x.norm(); 
+				y.copy(y3); y.norm();
+//System.out.println("Out of dbl");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				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);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.sqr();  //1    x^2
+				t1.sqr();  //2    y^2
+				t2.sqr();  //3
+
+				t3.mul(y); //4
+				t3.add(t3); t3.norm();//5
+				z3.mul(x);   //6
+				z3.add(z3);  z3.norm();//7
+				y3.copy(t2); 
+				
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //8
+				else
+					y3.imul(ROM.CURVE_B_I);
+				
+				y3.sub(z3); //y3.norm(); //9  ***
+				x3.copy(y3); x3.add(y3); x3.norm();//10
+
+				y3.add(x3); //y3.norm();//11
+				x3.copy(t1); x3.sub(y3); x3.norm();//12
+				y3.add(t1); y3.norm();//13
+				y3.mul(x3); //14
+				x3.mul(t3); //15
+				t3.copy(t2); t3.add(t2); //t3.norm(); //16
+				t2.add(t3); //t2.norm(); //17
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+
+				z3.sub(t2); //z3.norm();//19
+				z3.sub(t0); z3.norm();//20  ***
+				t3.copy(z3); t3.add(z3); //t3.norm();//21
+
+				z3.add(t3); z3.norm(); //22
+				t3.copy(t0); t3.add(t0); //t3.norm(); //23
+				t0.add(t3); //t0.norm();//24
+				t0.sub(t2); t0.norm();//25
+
+				t0.mul(z3);//26
+				y3.add(t0); //y3.norm();//27
+				t0.copy(y); t0.mul(z);//28
+				t0.add(t0); t0.norm(); //29
+				z3.mul(t0);//30
+				x3.sub(z3); //x3.norm();//31
+				t0.add(t0); t0.norm();//32
+				t1.add(t1); t1.norm();//33
+				z3.copy(t0); z3.mul(t1);//34
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into dbl");
+			FP C=new FP(x);
+			FP D=new FP(y);
+			FP H=new FP(z);
+			FP J=new FP(0);
+
+			x.mul(y); x.add(x); x.norm();
+			C.sqr();
+			D.sqr();
+
+			if (ROM.CURVE_A==-1) C.neg();	
+
+			y.copy(C); y.add(D); y.norm();
+			H.sqr(); H.add(H);
+
+			z.copy(y);
+			J.copy(y); 
+
+			J.sub(H); J.norm();
+			x.mul(J);
+
+			C.sub(D); C.norm();
+			y.mul(C);
+			z.mul(J);
+//System.out.println("Out of dbl");
+		}
+		if (CURVETYPE==MONTGOMERY)
+		{
+			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);
+
+			A.add(z); A.norm();
+			AA.copy(A); AA.sqr();
+			B.sub(z); B.norm();
+			BB.copy(B); BB.sqr();
+			C.copy(AA); C.sub(BB); C.norm();
+			x.copy(AA); x.mul(BB);
+
+			A.copy(C); A.imul((ROM.CURVE_A+2)/4);
+
+			BB.add(A); BB.norm();
+			z.copy(BB); z.mul(C);
+		}
+		return;
+	}
+
+/* this+=Q */
+	public void add(ECP Q) {
+//		if (INF)
+//		{
+//			copy(Q);
+//			return;
+//		}
+//		if (Q.INF) return;
+
+		if (CURVETYPE==WEIERSTRASS)
+		{
+
+
+			if (ROM.CURVE_A==0)
+			{
+// Edits made
+//System.out.println("Into add");
+				int b=3*ROM.CURVE_B_I;
+				FP t0=new FP(x);
+				t0.mul(Q.x);
+				FP t1=new FP(y);
+				t1.mul(Q.y);
+				FP t2=new FP(z);
+				t2.mul(Q.z);
+				FP t3=new FP(x);
+				t3.add(y); t3.norm();
+				FP t4=new FP(Q.x);
+				t4.add(Q.y); t4.norm();
+				t3.mul(t4);
+				t4.copy(t0); t4.add(t1);
+
+				t3.sub(t4); t3.norm();
+				t4.copy(y);
+				t4.add(z); t4.norm();
+				FP x3=new FP(Q.y);
+				x3.add(Q.z); x3.norm();
+
+				t4.mul(x3);
+				x3.copy(t1);
+				x3.add(t2);
+	
+				t4.sub(x3); t4.norm();
+				x3.copy(x); x3.add(z); x3.norm();
+				FP y3=new FP(Q.x);
+				y3.add(Q.z); y3.norm();
+				x3.mul(y3);
+				y3.copy(t0);
+				y3.add(t2);
+				y3.rsub(x3); y3.norm();
+				x3.copy(t0); x3.add(t0); 
+				t0.add(x3); t0.norm();
+				t2.imul(b);
+
+				FP z3=new FP(t1); z3.add(t2); z3.norm();
+				t1.sub(t2); t1.norm(); 
+				y3.imul(b);
+	
+				x3.copy(y3); x3.mul(t4); t2.copy(t3); t2.mul(t1); x3.rsub(t2);
+				y3.mul(t0); t1.mul(z3); y3.add(t1);
+				t0.mul(t3); z3.mul(t4); z3.add(t0);
+
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+//System.out.println("Out of add");
+			}
+			else
+			{
+				FP t0=new FP(x);
+				FP t1=new FP(y);
+				FP t2=new FP(z);
+				FP t3=new FP(x);
+				FP t4=new FP(Q.x);
+				FP z3=new FP(0);
+				FP y3=new FP(Q.x);
+				FP x3=new FP(Q.y);
+				FP b=new FP(0);
+
+				if (ROM.CURVE_B_I==0)
+					b.copy(new FP(new BIG(ROM.CURVE_B)));
+
+				t0.mul(Q.x); //1
+				t1.mul(Q.y); //2
+				t2.mul(Q.z); //3
+
+				t3.add(y); t3.norm(); //4
+				t4.add(Q.y); t4.norm();//5
+				t3.mul(t4);//6
+				t4.copy(t0); t4.add(t1); //t4.norm(); //7
+				t3.sub(t4); t3.norm(); //8
+				t4.copy(y); t4.add(z); t4.norm();//9
+				x3.add(Q.z); x3.norm();//10
+				t4.mul(x3); //11
+				x3.copy(t1); x3.add(t2); //x3.norm();//12
+
+				t4.sub(x3); t4.norm();//13
+				x3.copy(x); x3.add(z); x3.norm(); //14
+				y3.add(Q.z); y3.norm();//15
+
+				x3.mul(y3); //16
+				y3.copy(t0); y3.add(t2); //y3.norm();//17
+
+				y3.rsub(x3); y3.norm(); //18
+				z3.copy(t2); 
+				
+
+				if (ROM.CURVE_B_I==0)
+					z3.mul(b); //18
+				else
+					z3.imul(ROM.CURVE_B_I);
+				
+				x3.copy(y3); x3.sub(z3); x3.norm(); //20
+				z3.copy(x3); z3.add(x3); //z3.norm(); //21
+
+				x3.add(z3); //x3.norm(); //22
+				z3.copy(t1); z3.sub(x3); z3.norm(); //23
+				x3.add(t1); x3.norm(); //24
+
+				if (ROM.CURVE_B_I==0)
+					y3.mul(b); //18
+				else
+					y3.imul(ROM.CURVE_B_I);
+
+				t1.copy(t2); t1.add(t2); //t1.norm();//26
+				t2.add(t1); //t2.norm();//27
+
+				y3.sub(t2); //y3.norm(); //28
+
+				y3.sub(t0); y3.norm(); //29
+				t1.copy(y3); t1.add(y3); //t1.norm();//30
+				y3.add(t1); y3.norm(); //31
+
+				t1.copy(t0); t1.add(t0); //t1.norm(); //32
+				t0.add(t1); //t0.norm();//33
+				t0.sub(t2); t0.norm();//34
+				t1.copy(t4); t1.mul(y3);//35
+				t2.copy(t0); t2.mul(y3);//36
+				y3.copy(x3); y3.mul(z3);//37
+				y3.add(t2); //y3.norm();//38
+				x3.mul(t3);//39
+				x3.sub(t1);//40
+				z3.mul(t4);//41
+				t1.copy(t3); t1.mul(t0);//42
+				z3.add(t1); 
+				x.copy(x3); x.norm(); 
+				y.copy(y3); y.norm();
+				z.copy(z3); z.norm();
+			}
+		}
+		if (CURVETYPE==EDWARDS)
+		{
+//System.out.println("Into add");
+			FP A=new FP(z);
+			FP B=new FP(0);
+			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);
+
+			A.mul(Q.z);   
+			B.copy(A); B.sqr();    
+			C.mul(Q.x);      
+			D.mul(Q.y); 
+
+			E.copy(C); E.mul(D);  
+		
+			if (ROM.CURVE_B_I==0)
+			{
+				FP b=new FP(new BIG(ROM.CURVE_B));
+				E.mul(b);
+			}
+			else
+				E.imul(ROM.CURVE_B_I); 
+
+			F.copy(B); F.sub(E);      
+			G.copy(B); G.add(E);       
+
+			if (ROM.CURVE_A==1)
+			{
+				E.copy(D); E.sub(C);
+			}
+			C.add(D); 
+
+			B.copy(x); B.add(y);    
+			D.copy(Q.x); D.add(Q.y); B.norm(); D.norm(); 
+			B.mul(D);                   
+			B.sub(C); B.norm(); F.norm(); 
+			B.mul(F);                     
+			x.copy(A); x.mul(B); G.norm();  
+			if (ROM.CURVE_A==1)
+			{
+				E.norm(); C.copy(E); C.mul(G);  
+			}
+			if (ROM.CURVE_A==-1)
+			{
+				C.norm(); C.mul(G);
+			}
+			y.copy(A); y.mul(C);     
+
+			z.copy(F);	
+			z.mul(G);
+//System.out.println("Out of add");
+		}
+		return;
+	}
+
+/* Differential Add for Montgomery curves. this+=Q where W is this-Q and is affine. */
+	public void dadd(ECP Q,ECP W) {
+		FP A=new FP(x);
+		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);	
+			
+		A.add(z); 
+		B.sub(z); 
+
+		C.add(Q.z);
+		D.sub(Q.z);
+		A.norm();
+
+		D.norm();
+		DA.copy(D); DA.mul(A);
+
+		C.norm();
+		B.norm();
+		CB.copy(C); CB.mul(B);
+
+		A.copy(DA); A.add(CB); 
+		A.norm(); A.sqr();
+		B.copy(DA); B.sub(CB); 
+		B.norm(); B.sqr();
+
+		x.copy(A);
+		z.copy(W.x); z.mul(B);
+	}
+/* this-=Q */
+	public void sub(ECP Q) {
+		ECP NQ=new ECP(Q);
+		NQ.neg();
+		add(NQ);
+	}
+
+/* constant time multiply by small integer of length bts - use ladder */
+	public ECP pinmul(int e,int bts) {	
+		if (CURVETYPE==MONTGOMERY)
+			return this.mul(new BIG(e));
+		else
+		{
+			int nb,i,b;
+			ECP P=new ECP();
+			ECP R0=new ECP();
+			ECP R1=new ECP(); R1.copy(this);
+
+			for (i=bts-1;i>=0;i--)
+			{
+				b=(e>>i)&1;
+				P.copy(R1);
+				P.add(R0);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+			}
+			P.copy(R0);
+			P.affine();
+			return P;
+		}
+	}
+
+/* return e.this */
+
+	public ECP mul(BIG e) {
+		if (e.iszilch() || is_infinity()) return new ECP();
+		ECP P=new ECP();
+		if (CURVETYPE==MONTGOMERY)
+		{
+/* use Ladder */
+			int nb,i,b;
+			ECP D=new ECP();
+			ECP R0=new ECP(); R0.copy(this);
+			ECP R1=new ECP(); R1.copy(this);
+			R1.dbl();
+
+			D.copy(this); D.affine();
+			nb=e.nbits();
+			for (i=nb-2;i>=0;i--)
+			{
+				b=e.bit(i);
+				P.copy(R1);
+
+				P.dadd(R0,D);
+				R0.cswap(R1,b);
+				R1.copy(P);
+				R0.dbl();
+				R0.cswap(R1,b);
+
+			}
+
+			P.copy(R0);
+		}
+		else
+		{
+// fixed size windows 
+			int i,b,nb,m,s,ns;
+			BIG mt=new BIG();
+			BIG t=new BIG();
+			ECP Q=new ECP();
+			ECP C=new ECP();
+			ECP[] W=new ECP[8];
+			byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+
+			//affine();
+
+// precompute table 
+			Q.copy(this);
+
+			Q.dbl();
+			W[0]=new ECP();
+			W[0].copy(this);
+
+			for (i=1;i<8;i++)
+			{
+				W[i]=new ECP();
+				W[i].copy(W[i-1]);
+				W[i].add(Q);
+			}
+
+// make exponent odd - add 2P if even, P if odd 
+			t.copy(e);
+			s=t.parity();
+			t.inc(1); t.norm(); ns=t.parity(); mt.copy(t); mt.inc(1); mt.norm();
+			t.cmove(mt,s);
+			Q.cmove(this,ns);
+			C.copy(Q);
+
+			nb=1+(t.nbits()+3)/4;
+
+// convert exponent to signed 4-bit window 
+			for (i=0;i<nb;i++)
+			{
+				w[i]=(byte)(t.lastbits(5)-16);
+				t.dec(w[i]); t.norm();
+				t.fshr(4);	
+			}
+			w[nb]=(byte)t.lastbits(5);
+	
+			P.copy(W[(w[nb]-1)/2]);  
+			for (i=nb-1;i>=0;i--)
+			{
+				Q.select(W,w[i]);
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.dbl();
+				P.add(Q);
+			}
+			P.sub(C); /* apply correction */
+		}
+		P.affine();
+		return P;
+	}
+
+/* Return e.this+f.Q */
+
+	public ECP mul2(BIG e,ECP Q,BIG f) {
+		BIG te=new BIG();
+		BIG tf=new BIG();
+		BIG mt=new BIG();
+		ECP S=new ECP();
+		ECP T=new ECP();
+		ECP C=new ECP();
+		ECP[] W=new ECP[8];
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+1)/2];		
+		int i,s,ns,nb;
+		byte a,b;
+
+		//affine();
+		//Q.affine();
+
+		te.copy(e);
+		tf.copy(f);
+
+// precompute table 
+		W[1]=new ECP(); W[1].copy(this); W[1].sub(Q);
+		W[2]=new ECP(); W[2].copy(this); W[2].add(Q);
+		S.copy(Q); S.dbl();
+		W[0]=new ECP(); W[0].copy(W[1]); W[0].sub(S);
+		W[3]=new ECP(); W[3].copy(W[2]); W[3].add(S);
+		T.copy(this); T.dbl();
+		W[5]=new ECP(); W[5].copy(W[1]); W[5].add(T);
+		W[6]=new ECP(); W[6].copy(W[2]); W[6].add(T);
+		W[4]=new ECP(); W[4].copy(W[5]); W[4].sub(S);
+		W[7]=new ECP(); W[7].copy(W[6]); W[7].add(S);
+
+// if multiplier is odd, add 2, else add 1 to multiplier, and add 2P or P to correction 
+
+		s=te.parity();
+		te.inc(1); te.norm(); ns=te.parity(); mt.copy(te); mt.inc(1); mt.norm();
+		te.cmove(mt,s);
+		T.cmove(this,ns);
+		C.copy(T);
+
+		s=tf.parity();
+		tf.inc(1); tf.norm(); ns=tf.parity(); mt.copy(tf); mt.inc(1); mt.norm();
+		tf.cmove(mt,s);
+		S.cmove(Q,ns);
+		C.add(S);
+
+		mt.copy(te); mt.add(tf); mt.norm();
+		nb=1+(mt.nbits()+1)/2;
+
+// convert exponent to signed 2-bit window 
+		for (i=0;i<nb;i++)
+		{
+			a=(byte)(te.lastbits(3)-4);
+			te.dec(a); te.norm(); 
+			te.fshr(2);
+			b=(byte)(tf.lastbits(3)-4);
+			tf.dec(b); tf.norm(); 
+			tf.fshr(2);
+			w[i]=(byte)(4*a+b);
+		}
+		w[nb]=(byte)(4*te.lastbits(3)+tf.lastbits(3));
+		S.copy(W[(w[nb]-1)/2]);  
+
+		for (i=nb-1;i>=0;i--)
+		{
+			T.select(W,w[i]);
+			S.dbl();
+			S.dbl();
+			S.add(T);
+		}
+		S.sub(C); /* apply correction */
+		S.affine();
+		return S;
+	}
+
+// multiply a point by the curves cofactor
+	public void cfp()
+	{
+		int cf=ROM.CURVE_Cof_I;
+		if (cf==1) return;
+		if (cf==4)
+		{
+			dbl(); dbl();
+			//affine();
+			return;
+		} 
+		if (cf==8)
+		{
+			dbl(); dbl(); dbl();
+			//affine();
+			return;
+		}
+		BIG c=new BIG(ROM.CURVE_Cof);
+		copy(mul(c));
+	}
+
+/* Map byte string to curve point */
+	public static ECP mapit(byte[] h)
+	{
+		BIG q=new BIG(ROM.Modulus);
+		BIG x=BIG.fromBytes(h);
+		x.mod(q);
+		ECP P;
+
+		while (true)
+		{
+			while (true)
+			{
+				if (CURVETYPE!=MONTGOMERY)
+					P=new ECP(x,0);
+				else
+					P=new ECP(x);	
+				x.inc(1); x.norm();
+				if (!P.is_infinity()) break;
+			}
+			P.cfp();
+			if (!P.is_infinity()) break;
+		}
+		return P;
+	}
+
+	public static ECP generator()
+	{
+		ECP G;
+		BIG gx,gy;
+		gx=new BIG(ROM.CURVE_Gx);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			gy=new BIG(ROM.CURVE_Gy);
+			G=new ECP(gx,gy);
+		}
+		else
+			G=new ECP(gx);
+		return G;
+	}
+
+/*
+	public static void main(String[] args) {
+
+		BIG Gx=new BIG(ROM.CURVE_Gx);
+		BIG Gy;
+		ECP P;
+		if (CURVETYPE!=MONTGOMERY) Gy=new BIG(ROM.CURVE_Gy);
+		BIG r=new BIG(ROM.CURVE_Order);
+
+		//r.dec(7);
+	
+		System.out.println("Gx= "+Gx.toString());		
+		if (CURVETYPE!=MONTGOMERY) System.out.println("Gy= "+Gy.toString());	
+
+		if (CURVETYPE!=MONTGOMERY) P=new ECP(Gx,Gy);
+		else  P=new ECP(Gx);
+
+		System.out.println("P= "+P.toString());		
+
+		ECP R=P.mul(r);
+		//for (int i=0;i<10000;i++)
+		//	R=P.mul(r);
+	
+		System.out.println("R= "+R.toString());
+    } */
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/FP.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/FP.java
new file mode 100644
index 0000000..5405395
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/FP.java
@@ -0,0 +1,526 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Finite Field arithmetic */
+/* AMCL mod p functions */
+
+package org.apache.milagro.amcl.SECP256K1;
+
+public final class FP {
+
+	public static final int NOT_SPECIAL=0;
+	public static final int PSEUDO_MERSENNE=1;
+	public static final int MONTGOMERY_FRIENDLY=2;
+	public static final int GENERALISED_MERSENNE=3;
+
+	public static final int MODBITS=256; /* Number of bits in Modulus */
+	public static final int MOD8=7;  /* Modulus mod 8 */
+	public static final int MODTYPE=NOT_SPECIAL;
+
+	public static final int FEXCESS =((int)1<<24);  // BASEBITS*NLEN-MODBITS or 2^30 max!
+	public static final long OMASK=(long)(-1)<<(MODBITS%BIG.BASEBITS);
+	public static final int TBITS=MODBITS%BIG.BASEBITS; // Number of active bits in top word 
+	public static final long TMASK=((long)1<<TBITS)-1;
+
+
+	public final BIG x;
+	//public BIG p=new BIG(ROM.Modulus);
+	//public BIG r2modp=new BIG(ROM.R2modp);
+	public int XES;
+
+/**************** 64-bit specific ************************/
+
+/* reduce a DBIG to a BIG using the appropriate form of the modulus */
+	public static BIG mod(DBIG d)
+	{
+		if (MODTYPE==PSEUDO_MERSENNE)
+		{
+			BIG b;		
+			long v,tw;
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+
+			v=t.pmul((int)ROM.MConst);
+
+			t.add(b);
+			t.norm();
+
+			tw=t.w[BIG.NLEN-1];
+			t.w[BIG.NLEN-1]&=FP.TMASK;
+			t.w[0]+=(ROM.MConst*((tw>>TBITS)+(v<<(BIG.BASEBITS-TBITS))));
+
+			t.norm();
+			return t;			
+		}
+		if (FP.MODTYPE==MONTGOMERY_FRIENDLY)
+		{
+			BIG b;		
+			long[] cr=new long[2];
+			for (int i=0;i<BIG.NLEN;i++)
+			{
+				cr=BIG.muladd(d.w[i],ROM.MConst-1,d.w[i],d.w[BIG.NLEN+i-1]);
+				d.w[BIG.NLEN+i]+=cr[0];
+				d.w[BIG.NLEN+i-1]=cr[1];
+			}
+			
+			b=new BIG(0);
+			for (int i=0;i<BIG.NLEN;i++ )
+				b.w[i]=d.w[BIG.NLEN+i];
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==GENERALISED_MERSENNE)
+		{ // GoldiLocks Only
+			BIG b;		
+			BIG t=d.split(MODBITS);
+			b=new BIG(d);
+			b.add(t);
+			DBIG dd=new DBIG(t);
+			dd.shl(MODBITS/2);
+
+			BIG tt=dd.split(MODBITS);
+			BIG lo=new BIG(dd);
+			b.add(tt);
+			b.add(lo);
+			b.norm();
+			tt.shl(MODBITS/2);
+			b.add(tt);
+
+			long carry=b.w[BIG.NLEN-1]>>TBITS;
+			b.w[BIG.NLEN-1]&=FP.TMASK;
+			b.w[0]+=carry;
+			
+			b.w[224/BIG.BASEBITS]+=carry<<(224%BIG.BASEBITS);
+			b.norm();
+			return b;		
+		}
+		if (MODTYPE==NOT_SPECIAL)
+		{
+			return BIG.monty(new BIG(ROM.Modulus),ROM.MConst,d);
+		}
+
+		return new BIG(0);
+	}
+
+
+
+/*********************************************************/
+
+
+/* Constructors */
+	public FP(int a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+
+	public FP()
+	{
+		x=new BIG(0);
+		XES=1;
+	}
+
+	public FP(BIG a)
+	{
+		x=new BIG(a);
+		nres();
+	}
+	
+	public FP(FP a)
+	{
+		x=new BIG(a.x);
+		XES=a.XES;
+	}
+
+/* convert to string */
+	public String toString() 
+	{
+		String s=redc().toString();
+		return s;
+	}
+
+	public String toRawString() 
+	{
+		String s=x.toRawString();
+		return s;
+	}
+
+/* convert to Montgomery n-residue form */
+	public void nres()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=BIG.mul(x,new BIG(ROM.R2modp));  /*** Change ***/
+			x.copy(mod(d));
+			XES=2;
+		}
+		else XES=1;
+	}
+
+/* convert back to regular form */
+	public BIG redc()
+	{
+		if (MODTYPE!=PSEUDO_MERSENNE && MODTYPE!=GENERALISED_MERSENNE)
+		{
+			DBIG d=new DBIG(x);
+			return mod(d);
+		}
+		else 
+		{
+			BIG r=new BIG(x);
+			return r;
+		}
+	}
+
+/* test this=0? */
+	public boolean iszilch() {
+		FP z=new FP(this);
+		z.reduce();
+		return z.x.iszilch();
+
+	}
+
+/* copy from FP b */
+	public void copy(FP b)
+	{
+		x.copy(b.x);
+		XES=b.XES;
+	}
+
+/* set this=0 */
+	public void zero()
+	{
+		x.zero();
+		XES=1;
+	}
+	
+/* set this=1 */
+	public void one()
+	{
+		x.one(); nres();
+	}
+
+/* normalise this */
+	public void norm()
+	{
+		x.norm();
+	}
+
+/* swap FPs depending on d */
+	public void cswap(FP b,int d)
+	{
+		x.cswap(b.x,d);
+		int t,c=d;
+		c=~(c-1);
+		t=c&(XES^b.XES);
+		XES^=t;
+		b.XES^=t;
+	}
+
+/* copy FPs depending on d */
+	public void cmove(FP b,int d)
+	{
+		x.cmove(b.x,d);
+		XES^=(XES^b.XES)&(-d);
+
+	}
+
+/* this*=b mod Modulus */
+	public void mul(FP b)
+	{
+		if ((long)XES*b.XES>(long)FEXCESS) reduce();
+
+		DBIG d=BIG.mul(x,b.x);
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this*=c mod Modulus, where c is a small int */
+	public void imul(int c)
+	{
+//		norm();
+		boolean s=false;
+		if (c<0)
+		{
+			c=-c;
+			s=true;
+		}
+
+		if (MODTYPE==PSEUDO_MERSENNE || MODTYPE==GENERALISED_MERSENNE)
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+		else
+		{
+			if (XES*c<=FEXCESS)
+			{
+				x.pmul(c);
+				XES*=c;
+			}
+			else
+			{  // this is not good
+				FP n=new FP(c);
+				mul(n);
+			}
+		}
+		
+/*
+		if (c<=BIG.NEXCESS && XES*c<=FEXCESS)
+		{
+			x.imul(c);
+			XES*=c;
+			x.norm();
+		}
+		else
+		{
+			DBIG d=x.pxmul(c);
+			x.copy(mod(d));
+			XES=2;
+		}
+*/
+		if (s) {neg(); norm();}
+
+	}
+
+/* this*=this mod Modulus */
+	public void sqr()
+	{
+		DBIG d;
+		if ((long)XES*XES>(long)FEXCESS) reduce();
+
+		d=BIG.sqr(x);	
+		x.copy(mod(d));
+		XES=2;
+	}
+
+/* this+=b */
+	public void add(FP b) {
+		x.add(b.x);
+		XES+=b.XES;
+		if (XES>FEXCESS) reduce();
+	}
+
+// https://graphics.stanford.edu/~seander/bithacks.html
+// constant time log to base 2 (or number of bits in)
+
+	private static int logb2(int v)
+	{
+		int r;
+		v |= v >>> 1;
+		v |= v >>> 2;
+		v |= v >>> 4;
+		v |= v >>> 8;
+		v |= v >>> 16;
+
+		v = v - ((v >>> 1) & 0x55555555);                  
+		v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);  
+		r = ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; 
+		return r;
+	}
+
+/* this = -this mod Modulus */
+	public void neg()
+	{
+		int sb;
+		BIG m=new BIG(ROM.Modulus);
+
+		sb=logb2(XES-1);
+		m.fshl(sb);
+		x.rsub(m);		
+
+		XES=(1<<sb);
+		if (XES>FEXCESS) reduce();
+	}
+
+/* this-=b */
+	public void sub(FP b)
+	{
+		FP n=new FP(b);
+		n.neg();
+		this.add(n);
+	}
+
+	public void rsub(FP b)
+	{
+		FP n=new FP(this);
+		n.neg();
+		this.copy(b);
+		this.add(n);
+	}
+
+/* this/=2 mod Modulus */
+	public void div2()
+	{
+		if (x.parity()==0)
+			x.fshr(1);
+		else
+		{
+			x.add(new BIG(ROM.Modulus));
+			x.norm();
+			x.fshr(1);
+		}
+	}
+
+/* this=1/this mod Modulus */
+	public void inverse()
+	{
+/*
+		BIG r=redc();
+		r.invmodp(p);
+		x.copy(r);
+		nres();
+*/
+		BIG m2=new BIG(ROM.Modulus);
+		m2.dec(2); m2.norm();
+		copy(pow(m2));
+
+	}
+
+/* return TRUE if this==a */
+	public boolean equals(FP a)
+	{
+		FP f=new FP(this);
+		FP s=new FP(a);
+		f.reduce();
+		s.reduce();
+		if (BIG.comp(f.x,s.x)==0) return true;
+		return false;
+	}
+
+/* reduce this mod Modulus */
+	public void reduce()
+	{
+		x.mod(new BIG(ROM.Modulus));
+		XES=1;
+	}
+
+	public FP pow(BIG e)
+	{
+		byte[] w=new byte[1+(BIG.NLEN*BIG.BASEBITS+3)/4];
+		FP [] tb=new FP[16];
+		BIG t=new BIG(e);
+		t.norm();
+		int nb=1+(t.nbits()+3)/4;
+
+		for (int i=0;i<nb;i++)
+		{
+			int lsbs=t.lastbits(4);
+			t.dec(lsbs);
+			t.norm();
+			w[i]=(byte)lsbs;
+			t.fshr(4);
+		}
+		tb[0]=new FP(1);
+		tb[1]=new FP(this);
+		for (int i=2;i<16;i++)
+		{
+			tb[i]=new FP(tb[i-1]);
+			tb[i].mul(this);
+		}
+		FP r=new FP(tb[w[nb-1]]);
+		for (int i=nb-2;i>=0;i--)
+		{
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.sqr();
+			r.mul(tb[w[i]]);
+		}
+		r.reduce();
+		return r;
+	}
+
+/* return this^e mod Modulus 
+	public FP pow(BIG e)
+	{
+		int bt;
+		FP r=new FP(1);
+		e.norm();
+		x.norm();
+		FP m=new FP(this);
+		while (true)
+		{
+			bt=e.parity();
+			e.fshr(1);
+			if (bt==1) r.mul(m);
+			if (e.iszilch()) break;
+			m.sqr();
+		}
+		r.x.mod(p);
+		return r;
+	} */
+
+/* return sqrt(this) mod Modulus */
+	public FP sqrt()
+	{
+		reduce();
+		BIG b=new BIG(ROM.Modulus);
+		if (MOD8==5)
+		{
+			b.dec(5); b.norm(); b.shr(3);
+			FP i=new FP(this); i.x.shl(1);
+			FP v=i.pow(b);
+			i.mul(v); i.mul(v);
+			i.x.dec(1);
+			FP r=new FP(this);
+			r.mul(v); r.mul(i); 
+			r.reduce();
+			return r;
+		}
+		else
+		{
+			b.inc(1); b.norm(); b.shr(2);
+			return pow(b);
+		}
+	}
+
+/* return jacobi symbol (this/Modulus) */
+	public int jacobi()
+	{
+		BIG w=redc();
+		return w.jacobi(new BIG(ROM.Modulus));
+	}
+/*
+	public static void main(String[] args) {
+		BIG m=new BIG(ROM.Modulus);
+		BIG x=new BIG(3);
+		BIG e=new BIG(m);
+		e.dec(1);
+
+		System.out.println("m= "+m.nbits());	
+
+
+		BIG r=x.powmod(e,m);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+		BIG.cswap(m,r,0);
+
+		System.out.println("m= "+m.toString());	
+		System.out.println("r= "+r.toString());	
+
+//		FP y=new FP(3);
+//		FP s=y.pow(e);
+//		System.out.println("s= "+s.toString());	
+
+	} */
+}
diff --git a/src/main/java/org/apache/milagro/amcl/SECP256K1/ROM.java b/src/main/java/org/apache/milagro/amcl/SECP256K1/ROM.java
new file mode 100644
index 0000000..014ebc9
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SECP256K1/ROM.java
@@ -0,0 +1,43 @@
+/*
+	Licensed to the Apache Software Foundation (ASF) under one
+	or more contributor license agreements.  See the NOTICE file
+	distributed with this work for additional information
+	regarding copyright ownership.  The ASF licenses this file
+	to you under the Apache License, Version 2.0 (the
+	"License"); you may not use this file except in compliance
+	with the License.  You may obtain a copy of the License at
+	
+	http://www.apache.org/licenses/LICENSE-2.0
+
+	Unless required by applicable law or agreed to in writing,
+	software distributed under the License is distributed on an
+	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+	KIND, either express or implied.  See the License for the
+	specific language governing permissions and limitations
+	under the License.
+*/
+
+/* Fixed Data in ROM - Field and Curve parameters */
+
+
+package org.apache.milagro.amcl.SECP256K1;
+
+public class ROM
+{
+
+// Base Bits= 56
+public static final long[] Modulus= {0xFFFFFEFFFFFC2FL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+public static final long[] R2modp= {0xA1000000000000L,0x7A2000E90L,0x1L,0x0L,0x0L};
+public static final long MConst= 0x38091DD2253531L;
+
+public static final int CURVE_Cof_I= 1;
+public static final long[] CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};
+public static final int CURVE_A= 0;
+public static final int CURVE_B_I= 7;
+public static final long[] CURVE_B= {0x7L,0x0L,0x0L,0x0L,0x0L};
+public static final long[] CURVE_Order= {0xD25E8CD0364141L,0xDCE6AF48A03BBFL,0xFFFFFFFFFEBAAEL,0xFFFFFFFFFFFFFFL,0xFFFFFFFFL};
+public static final long[] CURVE_Gx= {0xF2815B16F81798L,0xFCDB2DCE28D959L,0x95CE870B07029BL,0xF9DCBBAC55A062L,0x79BE667EL};
+public static final long[] CURVE_Gy= {0x47D08FFB10D4B8L,0xB448A68554199CL,0xFC0E1108A8FD17L,0x26A3C4655DA4FBL,0x483ADA77L};
+
+}
+
diff --git a/src/main/java/org/apache/milagro/amcl/SHA3.java b/src/main/java/org/apache/milagro/amcl/SHA3.java
new file mode 100644
index 0000000..cf335cd
--- /dev/null
+++ b/src/main/java/org/apache/milagro/amcl/SHA3.java
@@ -0,0 +1,255 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ * Implementation of the Secure Hashing Algorithm SHA-3
+
+ * Generates a message digest. It should be impossible to come
+ * come up with two messages that hash to the same value ("collision free").
+ *
+ * For use with byte-oriented messages only. 
+ */
+
+
+package org.apache.milagro.amcl;
+
+public class SHA3 {
+	private long length;
+	private int rate,len;
+	private long[][] S=new long[5][5];
+
+/* Constructor */
+	public SHA3(int olen)
+	{
+		init(olen);
+	}
+
+	public static final int HASH224=28; 
+	public static final int HASH256=32;
+	public static final int HASH384=48;
+	public static final int HASH512=64;
+
+	public static final int SHAKE128=16; 
+	public static final int SHAKE256=32; 
+
+	public static final long[] RC={
+		0x0000000000000001L,0x0000000000008082L,0x800000000000808AL,0x8000000080008000L,
+		0x000000000000808BL,0x0000000080000001L,0x8000000080008081L,0x8000000000008009L,
+		0x000000000000008AL,0x0000000000000088L,0x0000000080008009L,0x000000008000000AL,
+		0x000000008000808BL,0x800000000000008BL,0x8000000000008089L,0x8000000000008003L,
+		0x8000000000008002L,0x8000000000000080L,0x000000000000800AL,0x800000008000000AL,
+		0x8000000080008081L,0x8000000000008080L,0x0000000080000001L,0x8000000080008008L};
+
+	private static final int ROUNDS=24;
+
+
+	private static long rotl(long x,int n)
+	{
+		return (((x)<<n) | ((x)>>>(64-n)));
+	}
+
+	private void transform()
+	{ /* basic transformation step */
+		int i,j,k;
+		long[] C=new long[5];
+		long[] D=new long[5];
+		long[][] B=new long[5][5];
+
+		for (k=0;k<ROUNDS;k++)
+		{
+			C[0]=S[0][0]^S[0][1]^S[0][2]^S[0][3]^S[0][4];
+			C[1]=S[1][0]^S[1][1]^S[1][2]^S[1][3]^S[1][4];
+			C[2]=S[2][0]^S[2][1]^S[2][2]^S[2][3]^S[2][4];
+			C[3]=S[3][0]^S[3][1]^S[3][2]^S[3][3]^S[3][4];
+			C[4]=S[4][0]^S[4][1]^S[4][2]^S[4][3]^S[4][4];
+
+			D[0]=C[4]^rotl(C[1],1);
+			D[1]=C[0]^rotl(C[2],1);
+			D[2]=C[1]^rotl(C[3],1);
+			D[3]=C[2]^rotl(C[4],1);
+			D[4]=C[3]^rotl(C[0],1);
+
+			for (i=0;i<5;i++)
+				for (j=0;j<5;j++)
+					S[i][j]^=D[i];  
+
+			B[0][0]=S[0][0];
+			B[1][3]=rotl(S[0][1],36);
+			B[2][1]=rotl(S[0][2],3);
+			B[3][4]=rotl(S[0][3],41);
+			B[4][2]=rotl(S[0][4],18);
+
+			B[0][2]=rotl(S[1][0],1);
+			B[1][0]=rotl(S[1][1],44);
+			B[2][3]=rotl(S[1][2],10);
+			B[3][1]=rotl(S[1][3],45);
+			B[4][4]=rotl(S[1][4],2);
+
+			B[0][4]=rotl(S[2][0],62);
+			B[1][2]=rotl(S[2][1],6);
+			B[2][0]=rotl(S[2][2],43);
+			B[3][3]=rotl(S[2][3],15);
+			B[4][1]=rotl(S[2][4],61);
+
+			B[0][1]=rotl(S[3][0],28);
+			B[1][4]=rotl(S[3][1],55);
+			B[2][2]=rotl(S[3][2],25);
+			B[3][0]=rotl(S[3][3],21);
+			B[4][3]=rotl(S[3][4],56);
+
+			B[0][3]=rotl(S[4][0],27);
+			B[1][1]=rotl(S[4][1],20);
+			B[2][4]=rotl(S[4][2],39);
+			B[3][2]=rotl(S[4][3],8);
+			B[4][0]=rotl(S[4][4],14);
+
+			for (i=0;i<5;i++)
+				for (j=0;j<5;j++)
+					S[i][j]=B[i][j]^(~B[(i+1)%5][j]&B[(i+2)%5][j]);
+
+			S[0][0]^=RC[k];
+		}
+	} 
+
+/* Re-Initialize. olen is output length in bytes - 
+   should be 28, 32, 48 or 64 (224, 256, 384, 512 bits resp.) */
+
+
+/* Initialise Hash function */
+	public void init(int olen)
+	{ /* initialise */
+		int i,j;
+		for (i=0;i<5;i++) 
+			for (j=0;j<5;j++)
+				S[i][j]=0;    /* 5x5x8 bytes = 200 bytes of state */
+		length=0;
+		len=olen;
+		rate=200-2*olen; /* number of bytes consumed in one gulp. Note that some bytes in the 
+	                        state ("capacity") are not touched. Gulps are smaller for larger digests. 
+							Important that olen<rate */
+	}
+
+/* process a single byte */
+	public void process(int byt)
+	{ /* process the next message byte */
+		int i,j,b,cnt;
+		cnt=(int)(length%rate);
+		b=cnt%8;
+		cnt/=8;
+		i=cnt%5; j=cnt/5;  /* process by columns! */
+		S[i][j]^=((long)(byt&0xff)<<(8*b));
+		length++;
+		if ((length%rate)==0) transform();
+	}
+
+/* squeeze the sponge */
+	public byte[] squeeze(byte[] buff,int olen)
+	{
+		boolean done;
+		int i,j,k,m=0;
+		long el;
+/* extract by columns */
+		done=false;
+		for (;;)
+		{
+			for (j=0;j<5;j++)
+			{
+				for (i=0;i<5;i++)
+				{
+					el=S[i][j];
+					for (k=0;k<8;k++)
+					{
+						buff[m++]=(byte)(el&0xff);
+						if (m>=olen || (m%rate)==0) {done=true; break;} 
+						el>>>=8;
+					}
+					if (done) break;
+				}
+				if (done) break;
+			}
+			if (m>=olen) break;
+			done=false;
+			transform();
+		}
+		return buff;
+	}
+
+	public void hash(byte[] digest)
+	{ /* generate a SHA3 hash of appropriate size */
+		int q=rate-(int)(length%rate);
+		if (q==1) process(0x86); 
+		else
+		{
+			process(0x06);   /* 0x06 for SHA-3 */
+			while (length%rate!=rate-1) process(0x00);
+			process(0x80); /* this will force a final transform */
+		}
+		squeeze(digest,len);
+	}
+
+	public void shake(byte[] digest,int olen)
+	{ /* SHAKE out a buffer of variable length olen */
+		int q=rate-(int)(length%rate);
+		if (q==1) process(0x9f); 
+		else
+		{
+			process(0x1f);   // 0x06 for SHA-3 !!!!
+			while (length%rate!=rate-1) process(0x00);
+			process(0x80); /* this will force a final transform */
+		}
+		squeeze(digest,olen);
+	}
+
+/* test program: should produce digests */
+
+//916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18
+//afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185
+//98be04516c04cc73593fef3ed0352ea9f6443942d6950e29a372a681c3deaf4535423709b02843948684e029010badcc0acd8303fc85fdad3eabf4f78cae165635f57afd28810fc2
+
+/*
+	public static void main(String[] args) {
+
+		byte[] test="abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu".getBytes();
+		byte[] digest=new byte[100];
+		int i;
+
+		SHA3 sh256=new SHA3(SHA3.HASH256);
+		for (i=0;i<test.length;i++)
+			sh256.process(test[i]);
+		sh256.hash(digest);    
+		for (i=0;i<32;i++) System.out.format("%02x",digest[i]);
+		System.out.println("");
+
+		SHA3 sh512=new SHA3(SHA3.HASH512);
+		for (i=0;i<test.length;i++)
+			sh512.process(test[i]);
+		sh512.hash(digest);    
+		for (i=0;i<64;i++) System.out.format("%02x",digest[i]);
+		System.out.println("");
+
+		SHA3 sk256=new SHA3(SHA3.SHAKE256);
+		for (i=0;i<test.length;i++)
+			sk256.process(test[i]);
+		sk256.shake(digest,72);    
+		for (i=0;i<72;i++) System.out.format("%02x",digest[i]);
+		System.out.println("");
+
+	}  
+*/
+}
\ No newline at end of file
diff --git a/src/test/java/org/apache/milagro/amcl/ANSSI/TestECDH.java b/src/test/java/org/apache/milagro/amcl/ANSSI/TestECDH.java
new file mode 100644
index 0000000..c71d32a
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/ANSSI/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.ANSSI;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS24/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BLS24/TestECDH.java
new file mode 100644
index 0000000..9abfde3
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS24/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BLS24;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS24/TestMPIN192.java b/src/test/java/org/apache/milagro/amcl/BLS24/TestMPIN192.java
new file mode 100644
index 0000000..a2c33d1
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS24/TestMPIN192.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BLS24;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN192 extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN192.EGS;
+		int EFS=MPIN192.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=8*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[24*EFS];
+		byte[] F=new byte[24*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[24*EFS];
+		byte[] G2=new byte[24*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN192.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN192.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN192.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN192.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN192.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN192.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN192.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN192.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN192.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN192.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN192.GET_TIME();
+			rtn=MPIN192.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN192.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN192.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN192.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN192.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN192.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN192.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN192.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN192.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN192.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN192.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN192.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN192.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN192.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN192.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN192.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN192.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN192.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN192.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS381/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BLS381/TestECDH.java
new file mode 100644
index 0000000..f653823
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS381/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BLS381;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS381/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/BLS381/TestMPIN.java
new file mode 100644
index 0000000..2312afc
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS381/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BLS381;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS383/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BLS383/TestECDH.java
new file mode 100644
index 0000000..2e3920e
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS383/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BLS383;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS383/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/BLS383/TestMPIN.java
new file mode 100644
index 0000000..8d99bd4
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS383/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BLS383;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS461/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BLS461/TestECDH.java
new file mode 100644
index 0000000..e1514a0
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS461/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BLS461;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS461/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/BLS461/TestMPIN.java
new file mode 100644
index 0000000..2915222
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS461/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BLS461;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS48/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BLS48/TestECDH.java
new file mode 100644
index 0000000..d2f4ded
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS48/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BLS48;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BLS48/TestMPIN256.java b/src/test/java/org/apache/milagro/amcl/BLS48/TestMPIN256.java
new file mode 100644
index 0000000..8dcfe75
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BLS48/TestMPIN256.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BLS48;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN256 extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN256.EGS;
+		int EFS=MPIN256.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=16*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[48*EFS];
+		byte[] F=new byte[48*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[48*EFS];
+		byte[] G2=new byte[48*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN256.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN256.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN256.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN256.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN256.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN256.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN256.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN256.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN256.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN256.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN256.GET_TIME();
+			rtn=MPIN256.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN256.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN256.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN256.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN256.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN256.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN256.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN256.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN256.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN256.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN256.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN256.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN256.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN256.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN256.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN256.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN256.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN256.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN256.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BN254/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BN254/TestECDH.java
new file mode 100644
index 0000000..7a98c55
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BN254/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BN254;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BN254/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/BN254/TestMPIN.java
new file mode 100644
index 0000000..dcd963a
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BN254/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BN254;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BN254CX/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BN254CX/TestECDH.java
new file mode 100644
index 0000000..580ab93
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BN254CX/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BN254CX;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BN254CX/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/BN254CX/TestMPIN.java
new file mode 100644
index 0000000..dc9e688
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BN254CX/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.BN254CX;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/BRAINPOOL/TestECDH.java b/src/test/java/org/apache/milagro/amcl/BRAINPOOL/TestECDH.java
new file mode 100644
index 0000000..ae45c75
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/BRAINPOOL/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.BRAINPOOL;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/C25519/TestECDH.java b/src/test/java/org/apache/milagro/amcl/C25519/TestECDH.java
new file mode 100644
index 0000000..b4f7123
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/C25519/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.C25519;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/C41417/TestECDH.java b/src/test/java/org/apache/milagro/amcl/C41417/TestECDH.java
new file mode 100644
index 0000000..894cc21
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/C41417/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.C41417;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/ED25519/TestECDH.java b/src/test/java/org/apache/milagro/amcl/ED25519/TestECDH.java
new file mode 100644
index 0000000..9373149
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/ED25519/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.ED25519;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/FP256BN/TestECDH.java b/src/test/java/org/apache/milagro/amcl/FP256BN/TestECDH.java
new file mode 100644
index 0000000..1b9c199
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/FP256BN/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.FP256BN;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/FP256BN/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/FP256BN/TestMPIN.java
new file mode 100644
index 0000000..6b140d7
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/FP256BN/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.FP256BN;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/FP512BN/TestECDH.java b/src/test/java/org/apache/milagro/amcl/FP512BN/TestECDH.java
new file mode 100644
index 0000000..0e2013e
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/FP512BN/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.FP512BN;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/FP512BN/TestMPIN.java b/src/test/java/org/apache/milagro/amcl/FP512BN/TestMPIN.java
new file mode 100644
index 0000000..2fa297d
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/FP512BN/TestMPIN.java
@@ -0,0 +1,297 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.FP512BN;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;      //
+import org.apache.milagro.amcl.RAND;
+
+public class TestMPIN extends TestCase //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+
+	static boolean PERMITS=true;
+	static boolean PINERROR=true;
+	static boolean FULL=true;
+	static boolean SINGLE_PASS=false;
+
+	public static void testMPIN()
+	{
+		RAND rng=new RAND();
+		int EGS=MPIN.EGS;
+		int EFS=MPIN.EFS;
+		int G1S=2*EFS+1; /* Group 1 Size */
+		int G2S=4*EFS; /* Group 2 Size */
+
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S = new byte[EGS];
+		byte[] SST = new byte[G2S];
+		byte[] TOKEN = new byte[G1S];
+		byte[] PERMIT = new byte[G1S];
+		byte[] SEC = new byte[G1S];
+		byte[] xID = new byte[G1S];
+		byte[] xCID = new byte[G1S];
+		byte[] X= new byte[EGS];
+		byte[] Y= new byte[EGS];
+		byte[] E=new byte[12*EFS];
+		byte[] F=new byte[12*EFS];
+		byte[] HID=new byte[G1S];
+		byte[] HTID=new byte[G1S];
+
+		byte[] G1=new byte[12*EFS];
+		byte[] G2=new byte[12*EFS];
+		byte[] R=new byte[EGS];
+		byte[] Z=new byte[G1S];
+		byte[] W=new byte[EGS];
+		byte[] T=new byte[G1S];
+		byte[] CK=new byte[ECP.AESKEY];
+		byte[] SK=new byte[ECP.AESKEY];
+
+		byte[] HSID=null;
+		byte[] RAW=new byte[100];
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		System.out.println("Testing MPIN code");
+
+/* Trusted Authority set-up */
+
+		MPIN.RANDOM_GENERATE(rng,S);
+		System.out.print("Master Secret s: 0x");  printBinary(S);
+ 
+ /* Create Client Identity */
+ 		String IDstr = "testUser@miracl.com";
+		byte[] CLIENT_ID = IDstr.getBytes();   
+
+		byte[] HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);  /* Either Client or TA calculates Hash(ID) - you decide! */
+
+		System.out.print("Client ID Hash= "); printBinary(HCID);
+		System.out.print("Client ID= "); printBinary(CLIENT_ID);
+
+/* Client and Server are issued secrets by DTA */
+
+		MPIN.GET_CLIENT_SECRET(S,HCID,TOKEN);
+		System.out.print("Client Secret CS: 0x");        
+		printBinary(TOKEN); 
+
+		MPIN.GET_SERVER_SECRET(S,SST);
+		System.out.print("Server Secret SS: 0x");  printBinary(SST); 
+
+
+/* Client extracts PIN from secret to create Token */
+		int pin=1234;
+		System.out.println("Client extracts PIN= "+pin); 
+		int rtn=MPIN.EXTRACT_PIN(sha,CLIENT_ID,pin,TOKEN);
+		if (rtn != 0)
+			fail("FAILURE: EXTRACT_PIN rtn: " + rtn);
+
+		System.out.print("Client Token TK: 0x"); printBinary(TOKEN);
+
+		if (FULL)
+		{
+			MPIN.PRECOMPUTE(TOKEN,HCID,G1,G2);
+		}
+		int date;
+		if (PERMITS)
+		{
+			date=MPIN.today();
+/* Client gets "Time Token" permit from DTA */ 
+			MPIN.GET_CLIENT_PERMIT(sha,date,S,HCID,PERMIT);
+			System.out.print("Time Permit TP: 0x");  printBinary(PERMIT); 
+
+/* This encoding makes Time permit look random - Elligator squared */
+			MPIN.ENCODING(rng,PERMIT);
+			System.out.print("Encoded Time Permit TP: 0x");  printBinary(PERMIT); 
+			MPIN.DECODING(PERMIT);
+			System.out.print("Decoded Time Permit TP: 0x");  printBinary(PERMIT); 
+		}
+		else date=0;
+
+//		System.out.print("\nPIN= ");
+//		Scanner scan=new Scanner(System.in);
+//		pin=scan.nextInt();
+
+		pin=1234;
+
+/* 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(date|H(CLIENT_ID)))
+Random value x is supplied externally if RNG=null, otherwise generated and passed out by RNG
+
+IMPORTANT: To save space and time..
+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.
+
+
+*/
+
+		byte[] pxID=xID;
+		byte[] pxCID=xCID;
+		byte[] pHID=HID;
+		byte[] pHTID=HTID;
+		byte[] pE=E;
+		byte[] pF=F;
+		byte[] pPERMIT=PERMIT;
+		byte[] prHID;
+
+		if (date!=0)
+		{
+
+			prHID=pHTID;
+			if (!PINERROR)
+			{
+				pxID=null;
+		//		pHID=null;  // new
+			}
+		}
+		else
+		{
+			prHID=pHID;
+			pPERMIT=null;
+			pxCID=null;
+			pHTID=null;
+		}
+		if (!PINERROR)
+		{
+			pE=null;
+			pF=null;
+		}
+                 
+		if (SINGLE_PASS)
+		{
+  			System.out.println("MPIN Single Pass");
+			int timeValue = MPIN.GET_TIME();
+			rtn=MPIN.CLIENT(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT,timeValue,Y);
+			if (rtn != 0)
+  				fail("FAILURE: CLIENT rtn: " + rtn);
+
+			if (FULL)
+			{
+				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,1,R,HCID,Z);  /* Also Send Z=r.ID to Server, remember random r */
+			}
+
+			rtn=MPIN.SERVER(sha,date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF,CLIENT_ID,timeValue);
+			if (rtn != 0)
+  				fail("FAILURE: SERVER rtn: " + rtn);
+
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+				MPIN.GET_G1_MULTIPLE(rng,0,W,prHID,T);  /* Also send T=w.ID to client, remember random w  */
+			}
+		}
+		else
+		{
+  			System.out.println("MPIN Multi Pass");
+                  /* Send U=x.ID to server, and recreate secret from token and pin */
+  			rtn=MPIN.CLIENT_1(sha,date,CLIENT_ID,rng,X,pin,TOKEN,SEC,pxID,pxCID,pPERMIT);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_1 rtn: " + rtn);
+  
+  			if (FULL)
+  			{
+  				HCID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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. */
+  			MPIN.SERVER_1(sha,date,CLIENT_ID,pHID,pHTID);
+  
+                  /* Server generates Random number Y and sends it to Client */
+  			MPIN.RANDOM_GENERATE(rng,Y);
+  
+			if (FULL)
+			{
+				HSID=MPIN.HASH_ID(sha,CLIENT_ID,EFS);
+  				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=MPIN.CLIENT_2(X,Y,SEC);
+  			if (rtn != 0)
+  				fail("FAILURE: CLIENT_2 rtn: " + rtn);
+  
+                  /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */
+                  /* If PIN error not required, set E and F = null */
+  
+  			rtn=MPIN.SERVER_2(date,pHID,pHTID,Y,SST,pxID,pxCID,SEC,pE,pF);
+  
+  			if (rtn != 0)
+  				fail("FAILURE: SERVER_2 rtn: " + rtn);
+		}
+  
+		if (rtn == MPIN.BAD_PIN)
+		{
+			if (PINERROR)
+			{
+				int err=MPIN.KANGAROO(E,F);
+				if (err!=0) fail("Client PIN is out by "+err);
+				else fail("Server says - Bad Pin. I don't know you. Feck off");
+			}
+			else fail("Server says - Bad Pin. I don't know you. Feck off");
+
+		}
+		else System.out.println("Server says - PIN is good! You really are "+IDstr);
+
+
+		if (FULL)
+		{
+			byte[] H=MPIN.HASH_ALL(sha,HCID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.CLIENT_KEY(sha,G1,G2,pin,R,X,H,T,CK);
+			System.out.print("Client Key =  0x");  printBinary(CK); 
+
+			H=MPIN.HASH_ALL(sha,HSID,pxID,pxCID,SEC,Y,Z,T,EFS);
+			MPIN.SERVER_KEY(sha,Z,SST,W,H,pHID,pxID,pxCID,SK);
+			System.out.print("Server Key =  0x");  printBinary(SK); 
+		}
+		System.out.println("");
+	}
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+
+		mpin(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/GOLDILOCKS/TestECDH.java b/src/test/java/org/apache/milagro/amcl/GOLDILOCKS/TestECDH.java
new file mode 100644
index 0000000..1046f3e
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/GOLDILOCKS/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.GOLDILOCKS;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/HIFIVE/TestECDH.java b/src/test/java/org/apache/milagro/amcl/HIFIVE/TestECDH.java
new file mode 100644
index 0000000..8a5733c
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/HIFIVE/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.HIFIVE;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NIST256/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NIST256/TestECDH.java
new file mode 100644
index 0000000..ab2ba14
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NIST256/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NIST256;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NIST384/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NIST384/TestECDH.java
new file mode 100644
index 0000000..be5a5d5
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NIST384/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NIST384;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NIST521/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NIST521/TestECDH.java
new file mode 100644
index 0000000..1c20eff
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NIST521/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NIST521;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS256E/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS256E/TestECDH.java
new file mode 100644
index 0000000..4711a89
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS256E/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS256E;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS256W/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS256W/TestECDH.java
new file mode 100644
index 0000000..0ad38ea
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS256W/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS256W;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS384E/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS384E/TestECDH.java
new file mode 100644
index 0000000..addbcc7
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS384E/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS384E;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS384W/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS384W/TestECDH.java
new file mode 100644
index 0000000..f556ae1
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS384W/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS384W;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS512E/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS512E/TestECDH.java
new file mode 100644
index 0000000..5950ce1
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS512E/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS512E;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/NUMS512W/TestECDH.java b/src/test/java/org/apache/milagro/amcl/NUMS512W/TestECDH.java
new file mode 100644
index 0000000..bf29666
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/NUMS512W/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.NUMS512W;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
diff --git a/src/test/java/org/apache/milagro/amcl/RSA2048/TestRSA.java b/src/test/java/org/apache/milagro/amcl/RSA2048/TestRSA.java
new file mode 100644
index 0000000..392a339
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/RSA2048/TestRSA.java
@@ -0,0 +1,111 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.RSA2048;
+
+import java.util.Scanner;
+import junit.framework.TestCase;
+import org.apache.milagro.amcl.RAND;
+
+public class TestRSA extends TestCase
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testRSA()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		
+		int i;
+		int RFS=RSA.RFS;
+		int sha=RSA.HASH_TYPE;
+
+		String message="Hello World\n";
+
+		public_key pub=new public_key(FF.FFLEN);
+		private_key priv=new private_key(FF.HFLEN);
+
+		byte[] ML=new byte[RFS];
+		byte[] C=new byte[RFS];
+		byte[] S=new byte[RFS];
+
+
+		System.out.println("Testing RSA code");
+
+		System.out.println("Generating public/private key pair");
+		RSA.KEY_PAIR(rng,65537,priv,pub);
+
+		byte[] M=message.getBytes();
+		System.out.print("Encrypting test string\n");
+
+
+		byte[] E=RSA.OAEP_ENCODE(sha,M,rng,null); /* OAEP encode message M to E  */
+
+		if (E.length==0) {
+			fail("Encoding failed");
+		}
+
+		RSA.ENCRYPT(pub,E,C);     /* encrypt encoded message */
+		System.out.print("Ciphertext= 0x"); printBinary(C);
+
+		System.out.print("Decrypting test string\n");
+		RSA.DECRYPT(priv,C,ML); 
+		byte[] MS=RSA.OAEP_DECODE(sha,null,ML); /* OAEP decode message  */
+
+		message=new String(MS);
+		System.out.print(message);
+
+		System.out.println("Signing message");
+		RSA.PKCS15(sha,M,C);
+
+		RSA.DECRYPT(priv,C,S); /* create signature in S */ 
+
+		System.out.print("Signature= 0x"); printBinary(S);
+
+		RSA.ENCRYPT(pub,S,ML); 
+
+		boolean cmp=true;
+		if (C.length!=ML.length) cmp=false;
+		else
+		{
+			for (int j=0;j<C.length;j++)
+				if (C[j]!=ML[j]) cmp=false;
+		}
+		if (cmp) System.out.println("Signature is valid");
+		else fail("Signature is INVALID");
+
+		RSA.PRIVATE_KEY_KILL(priv);
+		System.out.println("");
+
+	}
+}
diff --git a/src/test/java/org/apache/milagro/amcl/RSA3072/TestRSA.java b/src/test/java/org/apache/milagro/amcl/RSA3072/TestRSA.java
new file mode 100644
index 0000000..61109aa
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/RSA3072/TestRSA.java
@@ -0,0 +1,111 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.RSA3072;
+
+import java.util.Scanner;
+import junit.framework.TestCase;
+import org.apache.milagro.amcl.RAND;
+
+public class TestRSA extends TestCase
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testRSA()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		
+		int i;
+		int RFS=RSA.RFS;
+		int sha=RSA.HASH_TYPE;
+
+		String message="Hello World\n";
+
+		public_key pub=new public_key(FF.FFLEN);
+		private_key priv=new private_key(FF.HFLEN);
+
+		byte[] ML=new byte[RFS];
+		byte[] C=new byte[RFS];
+		byte[] S=new byte[RFS];
+
+
+		System.out.println("Testing RSA code");
+
+		System.out.println("Generating public/private key pair");
+		RSA.KEY_PAIR(rng,65537,priv,pub);
+
+		byte[] M=message.getBytes();
+		System.out.print("Encrypting test string\n");
+
+
+		byte[] E=RSA.OAEP_ENCODE(sha,M,rng,null); /* OAEP encode message M to E  */
+
+		if (E.length==0) {
+			fail("Encoding failed");
+		}
+
+		RSA.ENCRYPT(pub,E,C);     /* encrypt encoded message */
+		System.out.print("Ciphertext= 0x"); printBinary(C);
+
+		System.out.print("Decrypting test string\n");
+		RSA.DECRYPT(priv,C,ML); 
+		byte[] MS=RSA.OAEP_DECODE(sha,null,ML); /* OAEP decode message  */
+
+		message=new String(MS);
+		System.out.print(message);
+
+		System.out.println("Signing message");
+		RSA.PKCS15(sha,M,C);
+
+		RSA.DECRYPT(priv,C,S); /* create signature in S */ 
+
+		System.out.print("Signature= 0x"); printBinary(S);
+
+		RSA.ENCRYPT(pub,S,ML); 
+
+		boolean cmp=true;
+		if (C.length!=ML.length) cmp=false;
+		else
+		{
+			for (int j=0;j<C.length;j++)
+				if (C[j]!=ML[j]) cmp=false;
+		}
+		if (cmp) System.out.println("Signature is valid");
+		else fail("Signature is INVALID");
+
+		RSA.PRIVATE_KEY_KILL(priv);
+		System.out.println("");
+
+	}
+}
diff --git a/src/test/java/org/apache/milagro/amcl/RSA4096/TestRSA.java b/src/test/java/org/apache/milagro/amcl/RSA4096/TestRSA.java
new file mode 100644
index 0000000..2b44a68
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/RSA4096/TestRSA.java
@@ -0,0 +1,111 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+package org.apache.milagro.amcl.RSA4096;
+
+import java.util.Scanner;
+import junit.framework.TestCase;
+import org.apache.milagro.amcl.RAND;
+
+public class TestRSA extends TestCase
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testRSA()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		
+		int i;
+		int RFS=RSA.RFS;
+		int sha=RSA.HASH_TYPE;
+
+		String message="Hello World\n";
+
+		public_key pub=new public_key(FF.FFLEN);
+		private_key priv=new private_key(FF.HFLEN);
+
+		byte[] ML=new byte[RFS];
+		byte[] C=new byte[RFS];
+		byte[] S=new byte[RFS];
+
+
+		System.out.println("Testing RSA code");
+
+		System.out.println("Generating public/private key pair");
+		RSA.KEY_PAIR(rng,65537,priv,pub);
+
+		byte[] M=message.getBytes();
+		System.out.print("Encrypting test string\n");
+
+
+		byte[] E=RSA.OAEP_ENCODE(sha,M,rng,null); /* OAEP encode message M to E  */
+
+		if (E.length==0) {
+			fail("Encoding failed");
+		}
+
+		RSA.ENCRYPT(pub,E,C);     /* encrypt encoded message */
+		System.out.print("Ciphertext= 0x"); printBinary(C);
+
+		System.out.print("Decrypting test string\n");
+		RSA.DECRYPT(priv,C,ML); 
+		byte[] MS=RSA.OAEP_DECODE(sha,null,ML); /* OAEP decode message  */
+
+		message=new String(MS);
+		System.out.print(message);
+
+		System.out.println("Signing message");
+		RSA.PKCS15(sha,M,C);
+
+		RSA.DECRYPT(priv,C,S); /* create signature in S */ 
+
+		System.out.print("Signature= 0x"); printBinary(S);
+
+		RSA.ENCRYPT(pub,S,ML); 
+
+		boolean cmp=true;
+		if (C.length!=ML.length) cmp=false;
+		else
+		{
+			for (int j=0;j<C.length;j++)
+				if (C[j]!=ML[j]) cmp=false;
+		}
+		if (cmp) System.out.println("Signature is valid");
+		else fail("Signature is INVALID");
+
+		RSA.PRIVATE_KEY_KILL(priv);
+		System.out.println("");
+
+	}
+}
diff --git a/src/test/java/org/apache/milagro/amcl/SECP256K1/TestECDH.java b/src/test/java/org/apache/milagro/amcl/SECP256K1/TestECDH.java
new file mode 100644
index 0000000..832e272
--- /dev/null
+++ b/src/test/java/org/apache/milagro/amcl/SECP256K1/TestECDH.java
@@ -0,0 +1,192 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* test driver and function exerciser for ECDH/ECIES/ECDSA API Functions */
+
+package org.apache.milagro.amcl.SECP256K1;  //
+
+import java.util.Scanner;
+import junit.framework.TestCase;       //
+import org.apache.milagro.amcl.RAND;
+import org.apache.milagro.amcl.AES;
+
+public class TestECDH extends TestCase   //
+{
+	private static void printBinary(byte[] array)
+	{
+		int i;
+		for (i=0;i<array.length;i++)
+		{
+			System.out.printf("%02x", array[i]);
+		}
+		System.out.println();
+	}    
+
+	public static void testECDH()
+	{
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+		int i,j=0,res;
+		int result;
+		String pp=new String("M0ng00se");
+
+		rng.clean();
+		for (i=0;i<100;i++) RAW[i]=(byte)(i);
+		rng.seed(100,RAW);
+
+		int EGS=ECDH.EGS;
+		int EFS=ECDH.EFS;
+		int EAS=AES.KS;
+		int sha=ECP.HASH_TYPE;
+
+		byte[] S1=new byte[EGS];
+		byte[] W0=new byte[2*EFS+1];
+		byte[] W1=new byte[2*EFS+1];
+		byte[] Z0=new byte[EFS];
+		byte[] Z1=new byte[EFS];
+
+		byte[] SALT=new byte[8];
+		byte[] P1=new byte[3];
+		byte[] P2=new byte[4];
+		byte[] V=new byte[2*EFS+1];
+		byte[] M=new byte[17];
+		byte[] T=new byte[12];
+		byte[] CS=new byte[EGS];
+		byte[] DS=new byte[EGS];
+
+		for (i=0;i<8;i++) SALT[i]=(byte)(i+1);  // set Salt
+
+		System.out.println("Testing ECDH code");
+		System.out.println("Alice's Passphrase= "+pp);
+		byte[] PW=pp.getBytes();
+
+/* private key S0 of size EGS bytes derived from Password and Salt */
+
+		byte[] S0=ECDH.PBKDF2(sha,PW,SALT,1000,EGS);
+
+		System.out.print("Alice's private key= 0x");
+		printBinary(S0);
+
+/* Generate Key pair S/W */
+		ECDH.KEY_PAIR_GENERATE(null,S0,W0); 
+
+		System.out.print("Alice's public key= 0x");
+		printBinary(W0);
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W0);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+/* Random private key for other party */
+		ECDH.KEY_PAIR_GENERATE(rng,S1,W1);
+
+		System.out.print("Servers private key= 0x");
+		printBinary(S1);
+
+		System.out.print("Servers public key= 0x");
+		printBinary(W1);
+
+
+		res=ECDH.PUBLIC_KEY_VALIDATE(W1);
+		if (res!=0)
+		{
+			fail("ECP Public Key is invalid!");
+		}
+
+/* Calculate common key using DH - IEEE 1363 method */
+
+		ECDH.SVDP_DH(S0,W1,Z0);
+		ECDH.SVDP_DH(S1,W0,Z1);
+
+		boolean same=true;
+		for (i=0;i<EFS;i++)
+			if (Z0[i]!=Z1[i]) same=false;
+
+		if (!same)
+		{
+			fail("*** ECPSVDP-DH Failed");
+		}
+
+		byte[] KEY=ECDH.KDF2(sha,Z0,null,EAS);
+
+		System.out.print("Alice's DH Key=  0x"); printBinary(KEY);
+		System.out.print("Servers DH Key=  0x"); printBinary(KEY);
+
+		if (ECP.CURVETYPE!=ECP.MONTGOMERY)
+		{
+			System.out.println("Testing ECIES");
+
+			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]=(byte)i; 
+
+			byte[] C=ECDH.ECIES_ENCRYPT(sha,P1,P2,rng,W1,M,V,T);
+
+			System.out.println("Ciphertext= ");
+			System.out.print("V= 0x"); printBinary(V);
+			System.out.print("C= 0x"); printBinary(C);
+			System.out.print("T= 0x"); printBinary(T);
+
+
+			M=ECDH.ECIES_DECRYPT(sha,P1,P2,V,C,T,S1);
+			if (M.length==0)
+			{
+				fail("*** ECIES Decryption Failed");
+			}
+			else System.out.println("Decryption succeeded");
+
+			System.out.print("Message is 0x"); printBinary(M);
+
+			System.out.println("Testing ECDSA");
+
+			if (ECDH.SP_DSA(sha,rng,S0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Signature Failed");
+			}
+			System.out.println("Signature= ");
+			System.out.print("C= 0x"); printBinary(CS);
+			System.out.print("D= 0x"); printBinary(DS);
+
+			if (ECDH.VP_DSA(sha,W0,M,CS,DS)!=0)
+			{
+				fail("***ECDSA Verification Failed");
+			}
+			else System.out.println("ECDSA Signature/Verification succeeded "+j);
+			System.out.println("");
+
+		}
+	}
+
+/*
+	public static void main(String[] args) 
+	{
+
+		byte[] RAW=new byte[100];
+		RAND rng=new RAND();
+
+		rng.clean();
+		for (int i=0;i<100;i++) RAW[i]=(byte)(i);
+
+		rng.seed(100,RAW);
+		ecdh(rng);
+
+	} */
+}
