http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/bls192.h
----------------------------------------------------------------------
diff --git a/version3/c/bls192.h b/version3/c/bls192.h
new file mode 100644
index 0000000..1b8394f
--- /dev/null
+++ b/version3/c/bls192.h
@@ -0,0 +1,75 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/**
+ * @file bls.h
+ * @author Mike Scott
+ * @date 28th Novemebr 2018
+ * @brief BLS Header file
+ *
+ * Allows some user configuration
+ * defines structures
+ * declares functions
+ *
+ */
+
+#ifndef BLS_ZZZ_H
+#define BLS_ZZZ_H
+
+#include "pair192_ZZZ.h"
+
+/* Field size is assumed to be greater than or equal to group size */
+
+#define BGS_ZZZ MODBYTES_XXX  /**< BLS Group Size */
+#define BFS_ZZZ MODBYTES_XXX  /**< BLS Field Size */
+
+#define BLS_OK           0  /**< Function completed without error */
+#define BLS_FAIL               -1      /**< Point is NOT on the curve */
+
+/* BLS API functions */
+
+/**    @brief Generate Key Pair
+ *
+       @param RNG is a pointer to a cryptographically secure random number 
generator
+       @param S on output a private key
+       @param V on output a private key = S*G, where G is fixed generator
+       @return BLS_OK
+ */
+int BLS_ZZZ_KEY_PAIR_GENERATE(csprng *RNG,octet* S,octet *W);
+
+/**    @brief Calculate a signature
+ *
+       @param SIG the ouput signature
+       @param m is the message to be signed
+       @param S an input private key
+       @return BLS_OK
+ */
+int BLS_ZZZ_SIGN(octet *SIG,char *m,octet *S);
+
+/**    @brief Verify a signature
+ *
+       @param SIG an input signature
+       @param m is the message whose signature is to be verified.
+       @param W an public key
+       @return BLS_OK if verified, otherwise BLS_FAIL
+ */
+int BLS_ZZZ_VERIFY(octet *SIG,char *m,octet *W);
+
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/bls256.c
----------------------------------------------------------------------
diff --git a/version3/c/bls256.c b/version3/c/bls256.c
new file mode 100644
index 0000000..8f228b2
--- /dev/null
+++ b/version3/c/bls256.c
@@ -0,0 +1,89 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Boneh-Lynn-Shacham signature 256-bit API */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "bls256_ZZZ.h"
+
+/* hash a message to an ECP point, using SHA3 */
+
+static void BLS_HASHIT(ECP_ZZZ *P,char *m)
+{
+       int i;
+    sha3 hs;
+       char h[MODBYTES_XXX];
+    octet HM= {0,sizeof(h),h};
+       SHA3_init(&hs,SHAKE256);
+    for (i=0;m[i]!=0;i++) SHA3_process(&hs,m[i]);
+    SHA3_shake(&hs,HM.val,MODBYTES_XXX);
+       HM.len=MODBYTES_XXX;
+       ECP_ZZZ_mapit(P,&HM);
+}
+
+/* generate key pair, private key S, public key W */
+
+int BLS_ZZZ_KEY_PAIR_GENERATE(csprng *RNG,octet* S,octet *W)
+{
+       ECP8_ZZZ G;
+       BIG_XXX s,q;
+    BIG_XXX_rcopy(q,CURVE_Order_ZZZ);
+       ECP8_ZZZ_generator(&G);
+       BIG_XXX_randomnum(s,q,RNG);
+    BIG_XXX_toBytes(S->val,s);
+    S->len=MODBYTES_XXX;
+    PAIR_ZZZ_G2mul(&G,s);
+       ECP8_ZZZ_toOctet(W,&G);
+       return BLS_OK;
+}
+
+/* Sign message m using private key S to produce signature SIG */
+
+int BLS_ZZZ_SIGN(octet *SIG,char *m,octet *S)
+{
+       BIG_XXX s;
+       ECP_ZZZ D;
+       BLS_HASHIT(&D,m);
+       BIG_XXX_fromBytes(s,S->val);
+       PAIR_ZZZ_G1mul(&D,s);
+       ECP_ZZZ_toOctet(SIG,&D,true); /* compress output */
+       return BLS_OK;
+}
+
+/* Verify signature given message m, the signature SIG, and the public key W */
+
+int BLS_ZZZ_VERIFY(octet *SIG,char *m,octet *W)
+{
+       FP48_YYY v;
+       ECP8_ZZZ G,PK;
+       ECP_ZZZ D,HM;
+       BLS_HASHIT(&HM,m);
+       ECP_ZZZ_fromOctet(&D,SIG);
+       ECP8_ZZZ_generator(&G);
+       ECP8_ZZZ_fromOctet(&PK,W);
+       ECP_ZZZ_neg(&D);
+    PAIR_ZZZ_double_ate(&v,&G,&D,&PK,&HM);
+    PAIR_ZZZ_fexp(&v);
+    if (FP48_YYY_isunity(&v)) return BLS_OK;
+       return BLS_FAIL;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/bls256.h
----------------------------------------------------------------------
diff --git a/version3/c/bls256.h b/version3/c/bls256.h
new file mode 100644
index 0000000..822c58c
--- /dev/null
+++ b/version3/c/bls256.h
@@ -0,0 +1,75 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/**
+ * @file bls.h
+ * @author Mike Scott
+ * @date 28th Novemebr 2018
+ * @brief BLS Header file
+ *
+ * Allows some user configuration
+ * defines structures
+ * declares functions
+ *
+ */
+
+#ifndef BLS_ZZZ_H
+#define BLS_ZZZ_H
+
+#include "pair256_ZZZ.h"
+
+/* Field size is assumed to be greater than or equal to group size */
+
+#define BGS_ZZZ MODBYTES_XXX  /**< BLS Group Size */
+#define BFS_ZZZ MODBYTES_XXX  /**< BLS Field Size */
+
+#define BLS_OK           0  /**< Function completed without error */
+#define BLS_FAIL               -1      /**< Point is NOT on the curve */
+
+/* BLS API functions */
+
+/**    @brief Generate Key Pair
+ *
+       @param RNG is a pointer to a cryptographically secure random number 
generator
+       @param S on output a private key
+       @param V on output a private key = S*G, where G is fixed generator
+       @return BLS_OK
+ */
+int BLS_ZZZ_KEY_PAIR_GENERATE(csprng *RNG,octet* S,octet *W);
+
+/**    @brief Calculate a signature
+ *
+       @param SIG the ouput signature
+       @param m is the message to be signed
+       @param S an input private key
+       @return BLS_OK
+ */
+int BLS_ZZZ_SIGN(octet *SIG,char *m,octet *S);
+
+/**    @brief Verify a signature
+ *
+       @param SIG an input signature
+       @param m is the message whose signature is to be verified.
+       @param W an public key
+       @return BLS_OK if verified, otherwise BLS_FAIL
+ */
+int BLS_ZZZ_VERIFY(octet *SIG,char *m,octet *W);
+
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config16.py
----------------------------------------------------------------------
diff --git a/version3/c/config16.py b/version3/c/config16.py
new file mode 100644
index 0000000..ba77919
--- /dev/null
+++ b/version3/c/config16.py
@@ -0,0 +1,381 @@
+import os
+import sys
+
+deltext=""
+if sys.platform.startswith("linux")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("darwin")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("win") :
+       deltext="del"
+       copytext="copy"
+
+def replace(namefile,oldtext,newtext):
+       f = open(namefile,'r')
+       filedata = f.read()
+       f.close()
+
+       newdata = filedata.replace(oldtext,newtext)
+
+       f = open(namefile,'w')
+       f.write(newdata)
+       f.close()
+
+
+def rsaset(tb,tff,nb,base,ml) :
+       bd=tb+"_"+base
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+       fnameh="config_ff_"+tff+".h"
+       os.system(copytext+" config_ff.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"@ML@",ml);
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ff_"+tff+".c"
+       fnameh="ff_"+tff+".h"
+
+       os.system(copytext+" ff.c "+fnamec)
+       os.system(copytext+" ff.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="rsa_"+tff+".c"
+       fnameh="rsa_"+tff+".h"
+
+       os.system(copytext+" rsa.c "+fnamec)
+       os.system(copytext+" rsa.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
+       bd=tb+"_"+base
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+       fnameh="config_field_"+tf+".h"
+       os.system(copytext+" config_field.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"@NBT@",nbt)
+       replace(fnameh,"@M8@",m8)
+       replace(fnameh,"@MT@",mt)
+
+       ib=int(base)
+       inb=int(nb)
+       inbt=int(nbt)
+       sh=ib*(1+((8*inb-1)//ib))-inbt
+       if sh > 6 :
+               sh=6
+       replace(fnameh,"@SH@",str(sh))
+
+       fnameh="config_curve_"+tc+".h"  
+       os.system(copytext+" config_curve.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"@CT@",ct)
+       replace(fnameh,"@PF@",pf)
+
+       replace(fnameh,"@ST@",stw)
+       replace(fnameh,"@SX@",sx)
+       replace(fnameh,"@CS@",cs)
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="fp_"+tf+".c"
+       fnameh="fp_"+tf+".h"
+
+       os.system(copytext+" fp.c "+fnamec)
+       os.system(copytext+" fp.h "+fnameh)
+
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_field_"+tf+".c");
+
+       fnamec="ecp_"+tc+".c"
+       fnameh="ecp_"+tc+".h"
+
+       os.system(copytext+" ecp.c "+fnamec)
+       os.system(copytext+" ecp.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ecdh_"+tc+".c"
+       fnameh="ecdh_"+tc+".h"
+
+       os.system(copytext+" ecdh.c "+fnamec)
+       os.system(copytext+" ecdh.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_curve_"+tc+".c");
+
+       if pf != "NOT" :
+               fnamec="fp2_"+tf+".c"
+               fnameh="fp2_"+tf+".h"
+
+               os.system(copytext+" fp2.c "+fnamec)
+               os.system(copytext+" fp2.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="fp4_"+tf+".c"
+               fnameh="fp4_"+tf+".h"
+
+               os.system(copytext+" fp4.c "+fnamec)
+               os.system(copytext+" fp4.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="fp12_"+tf+".c"
+               fnameh="fp12_"+tf+".h"
+
+               os.system(copytext+" fp12.c "+fnamec)
+               os.system(copytext+" fp12.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="ecp2_"+tc+".c"
+               fnameh="ecp2_"+tc+".h"
+
+               os.system(copytext+" ecp2.c "+fnamec)
+               os.system(copytext+" ecp2.h "+fnameh)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="pair_"+tc+".c"
+               fnameh="pair_"+tc+".h"
+
+               os.system(copytext+" pair.c "+fnamec)
+               os.system(copytext+" pair.h "+fnameh)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="mpin_"+tc+".c"
+               fnameh="mpin_"+tc+".h"
+
+               os.system(copytext+" mpin.c "+fnamec)
+               os.system(copytext+" mpin.h "+fnameh)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="bls_"+tc+".c"
+               fnameh="bls_"+tc+".h"
+
+               os.system(copytext+" bls.c "+fnamec)
+               os.system(copytext+" bls.h "+fnameh)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+replace("arch.h","@WL@","16")
+print("Elliptic Curves")
+print("1. ED25519")
+print("2. NUMS256E")
+
+print("Pairing-Friendly Elliptic Curves")
+print("3. BN254")
+print("4. BN254CX")
+
+print("RSA")
+print("5. RSA2048")
+
+
+selection=[]
+ptr=0
+max=6
+
+curve_selected=False
+pfcurve_selected=False
+rsa_selected=False
+
+while ptr<max:
+       x=int(input("Choose a Scheme to support - 0 to finish: "))
+       if x == 0:
+               break
+#      print("Choice= ",x)
+       already=False
+       for i in range(0,ptr):
+               if x==selection[i]:
+                       already=True
+                       break
+       if already:
+               continue
+       
+       selection.append(x)
+       ptr=ptr+1
+
+# 
curveset(big,field,curve,big_length_bytes,bits_in_base,modulus_bits,modulus_mod_8,modulus_type,curve_type,pairing_friendly,sextic
 twist,sign of x)
+# for each curve give names for big, field and curve. In many cases the latter 
two will be the same. 
+# Typically "big" is the size in bits, always a multiple of 8, "field" 
describes the modulus, and "curve" is the common name for the elliptic curve   
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 16 bit architectures, as n where the base 
is 2^n (note that these must be fixed for the same "big" name, if is ever 
re-used for another curve)
+# modulus_bits is the bit length of the modulus, typically the same or 
slightly smaller than "big"
+# modulus_mod_8 is the remainder when the modulus is divided by 8
+# modulus_type is NOT_SPECIAL, or PSEUDO_MERSENNE, or MONTGOMERY_Friendly, or 
GENERALISED_MERSENNE (supported for GOLDILOCKS only)
+# curve_type is WEIERSTRASS, EDWARDS or MONTGOMERY
+# pairing_friendly is BN, BLS or NOT (if not pairing friendly)
+# if pairing friendly. M or D type twist, and sign of the family parameter x
+
+       if x==1:
+               
curveset("256","25519","ED25519","32","13","255","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==2:
+               
curveset("256","256PME","NUMS256E","32","13","256","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+
+
+       if x==3:
+               
curveset("256","BN254","BN254","32","13","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==4:
+               
curveset("256","BN254CX","BN254CX","32","13","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+
+# rsaset(big,ring,big_length_bytes,bits_in_base,multiplier)
+# for each choice give distinct names for "big" and "ring".
+# Typically "big" is the length in bits of the underlying big number type
+# "ring" is the RSA modulus size = "big" times 2^m
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 16 bit architecture, as n where the base 
is 2^n
+# multiplier is 2^m (see above)
+
+# There are choices here, different ways of getting the same result, but some 
faster than others
+       if x==5:
+               #256 is slower but may allow reuse of 256-bit BIGs used for 
elliptic curve
+               #512 is faster.. but best is 1024
+               rsaset("256","2048","32","13","8")
+               rsa_selected=True
+
+
+os.system(deltext+" big.*")
+os.system(deltext+" fp.*")
+os.system(deltext+" ecp.*")
+os.system(deltext+" ecdh.*")
+os.system(deltext+" ff.*")
+os.system(deltext+" rsa.*")
+os.system(deltext+" config_big.h")
+os.system(deltext+" config_field.h")
+os.system(deltext+" config_curve.h")
+os.system(deltext+" config_ff.h")
+os.system(deltext+" fp2.*")
+os.system(deltext+" fp4.*")
+os.system(deltext+" fp12.*")
+os.system(deltext+" ecp2.*")
+os.system(deltext+" pair.*")
+os.system(deltext+" mpin.*")
+os.system(deltext+" bls.*")
+
+# create library
+os.system("gcc -O3 -std=c99 -c randapi.c")
+if curve_selected :
+       os.system("gcc -O3 -std=c99 -c ecdh_support.c")
+if rsa_selected :
+       os.system("gcc -O3 -std=c99 -c rsa_support.c")
+if pfcurve_selected :
+       os.system("gcc -O3 -std=c99 -c pbc_support.c")
+
+os.system("gcc -O3 -std=c99 -c hash.c")
+os.system("gcc -O3 -std=c99 -c rand.c")
+os.system("gcc -O3 -std=c99 -c oct.c")
+os.system("gcc -O3 -std=c99 -c aes.c")
+os.system("gcc -O3 -std=c99 -c gcm.c")
+os.system("gcc -O3 -std=c99 -c newhope.c")
+
+if sys.platform.startswith("win") :
+       os.system("for %i in (*.o) do @echo %~nxi >> f.list")
+       os.system("ar rc amcl.a @f.list")
+       os.system(deltext+" f.list")
+
+else :
+       os.system("ar rc amcl.a *.o")
+
+os.system(deltext+" *.o")
+
+
+#print("Your section was ");   
+#for i in range(0,ptr):
+#      print (selection[i])
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config32.py
----------------------------------------------------------------------
diff --git a/version3/c/config32.py b/version3/c/config32.py
new file mode 100644
index 0000000..e848122
--- /dev/null
+++ b/version3/c/config32.py
@@ -0,0 +1,687 @@
+import os
+import sys
+
+deltext=""
+if sys.platform.startswith("linux")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("darwin")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("win") :
+       deltext="del"
+       copytext="copy"
+
+def replace(namefile,oldtext,newtext):
+       f = open(namefile,'r')
+       filedata = f.read()
+       f.close()
+
+       newdata = filedata.replace(oldtext,newtext)
+
+       f = open(namefile,'w')
+       f.write(newdata)
+       f.close()
+
+
+def rsaset(tb,tff,nb,base,ml) :
+       bd=tb+"_"+base
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+       fnameh="config_ff_"+tff+".h"
+       os.system(copytext+" config_ff.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"@ML@",ml);
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ff_"+tff+".c"
+       fnameh="ff_"+tff+".h"
+
+       os.system(copytext+" ff.c "+fnamec)
+       os.system(copytext+" ff.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="rsa_"+tff+".c"
+       fnameh="rsa_"+tff+".h"
+
+       os.system(copytext+" rsa.c "+fnamec)
+       os.system(copytext+" rsa.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
+       bd=tb+"_"+base
+
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+
+       fnameh="config_field_"+tf+".h"
+       os.system(copytext+" config_field.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"@NBT@",nbt)
+       replace(fnameh,"@M8@",m8)
+       replace(fnameh,"@MT@",mt)
+
+       ib=int(base)
+
+       ib=int(base)
+       inb=int(nb)
+       inbt=int(nbt)
+       sh=ib*(1+((8*inb-1)//ib))-inbt
+       if sh > 14 :
+               sh=14
+       replace(fnameh,"@SH@",str(sh))
+
+       fnameh="config_curve_"+tc+".h"  
+       os.system(copytext+" config_curve.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"@CT@",ct)
+       replace(fnameh,"@PF@",pf)
+
+       replace(fnameh,"@ST@",stw)
+       replace(fnameh,"@SX@",sx)
+       replace(fnameh,"@CS@",cs)
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="fp_"+tf+".c"
+       fnameh="fp_"+tf+".h"
+
+       os.system(copytext+" fp.c "+fnamec)
+       os.system(copytext+" fp.h "+fnameh)
+
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_field_"+tf+".c");
+
+       fnamec="ecp_"+tc+".c"
+       fnameh="ecp_"+tc+".h"
+
+       os.system(copytext+" ecp.c "+fnamec)
+       os.system(copytext+" ecp.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ecdh_"+tc+".c"
+       fnameh="ecdh_"+tc+".h"
+
+       os.system(copytext+" ecdh.c "+fnamec)
+       os.system(copytext+" ecdh.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_curve_"+tc+".c");
+
+       if pf != "NOT" :
+               fnamec="fp2_"+tf+".c"
+               fnameh="fp2_"+tf+".h"
+
+               os.system(copytext+" fp2.c "+fnamec)
+               os.system(copytext+" fp2.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="fp4_"+tf+".c"
+               fnameh="fp4_"+tf+".h"
+
+               os.system(copytext+" fp4.c "+fnamec)
+               os.system(copytext+" fp4.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+               if cs == "128" :
+                       fnamec="fp12_"+tf+".c"
+                       fnameh="fp12_"+tf+".h"
+
+                       os.system(copytext+" fp12.c "+fnamec)
+                       os.system(copytext+" fp12.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="ecp2_"+tc+".c"
+                       fnameh="ecp2_"+tc+".h"
+
+                       os.system(copytext+" ecp2.c "+fnamec)
+                       os.system(copytext+" ecp2.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="pair_"+tc+".c"
+                       fnameh="pair_"+tc+".h"
+
+                       os.system(copytext+" pair.c "+fnamec)
+                       os.system(copytext+" pair.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin_"+tc+".c"
+                       fnameh="mpin_"+tc+".h"
+
+                       os.system(copytext+" mpin.c "+fnamec)
+                       os.system(copytext+" mpin.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="bls_"+tc+".c"
+                       fnameh="bls_"+tc+".h"
+
+                       os.system(copytext+" bls.c "+fnamec)
+                       os.system(copytext+" bls.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               if cs == "192" :
+                       fnamec="fp8_"+tf+".c"
+                       fnameh="fp8_"+tf+".h"
+
+                       os.system(copytext+" fp8.c "+fnamec)
+                       os.system(copytext+" fp8.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp24_"+tf+".c"
+                       fnameh="fp24_"+tf+".h"
+
+                       os.system(copytext+" fp24.c "+fnamec)
+                       os.system(copytext+" fp24.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="ecp4_"+tc+".c"
+                       fnameh="ecp4_"+tc+".h"
+
+                       os.system(copytext+" ecp4.c "+fnamec)
+                       os.system(copytext+" ecp4.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="pair192_"+tc+".c"
+                       fnameh="pair192_"+tc+".h"
+
+                       os.system(copytext+" pair192.c "+fnamec)
+                       os.system(copytext+" pair192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin192_"+tc+".c"
+                       fnameh="mpin192_"+tc+".h"
+
+                       os.system(copytext+" mpin192.c "+fnamec)
+                       os.system(copytext+" mpin192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)                
+
+                       fnamec="bls192_"+tc+".c"
+                       fnameh="bls192_"+tc+".h"
+
+                       os.system(copytext+" bls192.c "+fnamec)
+                       os.system(copytext+" bls192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)        
+
+               if cs == "256" :
+
+                       fnamec="fp8_"+tf+".c"
+                       fnameh="fp8_"+tf+".h"
+
+                       os.system(copytext+" fp8.c "+fnamec)
+                       os.system(copytext+" fp8.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="ecp8_"+tc+".c"
+                       fnameh="ecp8_"+tc+".h"
+
+                       os.system(copytext+" ecp8.c "+fnamec)
+                       os.system(copytext+" ecp8.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp16_"+tf+".c"
+                       fnameh="fp16_"+tf+".h"
+
+                       os.system(copytext+" fp16.c "+fnamec)
+                       os.system(copytext+" fp16.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp48_"+tf+".c"
+                       fnameh="fp48_"+tf+".h"
+
+                       os.system(copytext+" fp48.c "+fnamec)
+                       os.system(copytext+" fp48.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="pair256_"+tc+".c"
+                       fnameh="pair256_"+tc+".h"
+
+                       os.system(copytext+" pair256.c "+fnamec)
+                       os.system(copytext+" pair256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin256_"+tc+".c"
+                       fnameh="mpin256_"+tc+".h"
+
+                       os.system(copytext+" mpin256.c "+fnamec)
+                       os.system(copytext+" mpin256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)                
                
+
+                       fnamec="bls256_"+tc+".c"
+                       fnameh="bls256_"+tc+".h"
+
+                       os.system(copytext+" bls256.c "+fnamec)
+                       os.system(copytext+" bls256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+replace("arch.h","@WL@","32")
+print("Elliptic Curves")
+print("1. ED25519")
+print("2. C25519")
+print("3. NIST256")
+print("4. BRAINPOOL")
+print("5. ANSSI")
+print("6. HIFIVE")
+print("7. GOLDILOCKS")
+print("8. NIST384")
+print("9. C41417")
+print("10. NIST521\n")
+print("11. NUMS256W")
+print("12. NUMS256E")
+print("13. NUMS384W")
+print("14. NUMS384E")
+print("15. NUMS512W")
+print("16. NUMS512E")
+print("17. SECP256K1\n")
+
+print("Pairing-Friendly Elliptic Curves")
+print("18. BN254")
+print("19. BN254CX")
+print("20. BLS383")
+print("21. BLS381")
+print("22. FP256BN")
+print("23. FP512BN")
+print("24. BLS461\n")
+print("25. BLS24")
+print("26. BLS48\n")
+
+print("RSA")
+print("27. RSA2048")
+print("28. RSA3072")
+print("29. RSA4096")
+
+selection=[]
+ptr=0
+max=30
+
+curve_selected=False
+pfcurve_selected=False
+rsa_selected=False
+
+while ptr<max:
+       x=int(input("Choose a Scheme to support - 0 to finish: "))
+       if x == 0:
+               break
+#      print("Choice= ",x)
+       already=False
+       for i in range(0,ptr):
+               if x==selection[i]:
+                       already=True
+                       break
+       if already:
+               continue
+       
+       selection.append(x)
+       ptr=ptr+1
+
+# 
curveset(big,field,curve,big_length_bytes,bits_in_base,modulus_bits,modulus_mod_8,modulus_type,curve_type,pairing_friendly,sextic
 twist,sign of x,curve security)
+# for each curve give names for big, field and curve. In many cases the latter 
two will be the same. 
+# Typically "big" is the size in bits, always a multiple of 8, "field" 
describes the modulus, and "curve" is the common name for the elliptic curve   
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 32 bit architectures, as n where the base 
is 2^n (note that these must be fixed for the same "big" name, if is ever 
re-used for another curve)
+# modulus_bits is the bit length of the modulus, typically the same or 
slightly smaller than "big"
+# modulus_mod_8 is the remainder when the modulus is divided by 8
+# modulus_type is NOT_SPECIAL, or PSEUDO_MERSENNE, or MONTGOMERY_Friendly, or 
GENERALISED_MERSENNE (supported for GOLDILOCKS only)
+# curve_type is WEIERSTRASS, EDWARDS or MONTGOMERY
+# pairing_friendly is BN, BLS or NOT (if not pairing friendly)
+# if pairing friendly. M or D type twist, and sign of the family parameter x
+# curve security is AES equiavlent, rounded up.
+
+       if x==1:
+               
curveset("256","25519","ED25519","32","29","255","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==2:
+               
curveset("256","25519","C25519","32","29","255","5","PSEUDO_MERSENNE","MONTGOMERY","NOT","","","128")
+               curve_selected=True
+       if x==3:
+               
curveset("256","NIST256","NIST256","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==4:
+               
curveset("256","BRAINPOOL","BRAINPOOL","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==5:
+               
curveset("256","ANSSI","ANSSI","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+
+       if x==6:
+               
curveset("336","HIFIVE","HIFIVE","42","29","336","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","192")
+               curve_selected=True
+       if x==7:
+               
curveset("448","GOLDILOCKS","GOLDILOCKS","56","29","448","7","GENERALISED_MERSENNE","EDWARDS","NOT","","","256")
+               curve_selected=True
+       if x==8:
+               
curveset("384","NIST384","NIST384","48","29","384","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","192")
+               curve_selected=True
+       if x==9:
+               
curveset("416","C41417","C41417","52","29","414","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","256")
+               curve_selected=True
+       if x==10:
+               
curveset("528","NIST521","NIST521","66","28","521","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","256")
+               curve_selected=True
+
+       if x==11:
+               
curveset("256","256PMW","NUMS256W","32","28","256","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==12:
+               
curveset("256","256PME","NUMS256E","32","29","256","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==13:
+               
curveset("384","384PM","NUMS384W","48","29","384","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","192")
+               curve_selected=True
+       if x==14:
+               
curveset("384","384PM","NUMS384E","48","29","384","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","192")
+               curve_selected=True
+       if x==15:
+               
curveset("512","512PM","NUMS512W","64","29","512","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","256")
+               curve_selected=True
+       if x==16:
+               
curveset("512","512PM","NUMS512E","64","29","512","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","256")
+               curve_selected=True
+
+       if x==17:
+               
curveset("256","SECP256K1","SECP256K1","32","28","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+
+
+       if x==18:
+               
curveset("256","BN254","BN254","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==19:
+               
curveset("256","BN254CX","BN254CX","32","28","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==20:
+               
curveset("384","BLS383","BLS383","48","29","383","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","128")
+               pfcurve_selected=True
+
+       if x==21:
+               
curveset("384","BLS381","BLS381","48","29","381","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+
+       if x==22:
+               
curveset("256","FP256BN","FP256BN","32","28","256","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==23:
+               
curveset("512","FP512BN","FP512BN","64","29","512","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","POSITIVEX","128")
+               pfcurve_selected=True
+# https://eprint.iacr.org/2017/334.pdf
+       if x==24:
+               
curveset("464","BLS461","BLS461","58","28","461","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+
+       if x==25:
+               
curveset("480","BLS24","BLS24","60","29","479","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","192")
+               pfcurve_selected=True
+
+
+       if x==26:
+               
curveset("560","BLS48","BLS48","70","29","556","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","256")
+               pfcurve_selected=True
+
+
+# rsaset(big,ring,big_length_bytes,bits_in_base,multiplier)
+# for each choice give distinct names for "big" and "ring".
+# Typically "big" is the length in bits of the underlying big number type
+# "ring" is the RSA modulus size = "big" times 2^m
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 32 bit architecture, as n where the base 
is 2^n
+# multiplier is 2^m (see above)
+
+# There are choices here, different ways of getting the same result, but some 
faster than others
+       if x==27:
+               #256 is slower but may allow reuse of 256-bit BIGs used for 
elliptic curve
+               #512 is faster.. but best is 1024
+               rsaset("1024","2048","128","28","2")
+               #rsaset("512","2048","64","29","4")
+               #rsaset("256","2048","32","29","8")
+               rsa_selected=True
+       if x==28:
+               rsaset("384","3072","48","28","8")
+               rsa_selected=True
+       if x==29:
+               #rsaset("256","4096","32","29","16")
+               rsaset("512","4096","64","29","8")
+               rsa_selected=True
+
+
+os.system(deltext+" big.*")
+os.system(deltext+" fp.*")
+os.system(deltext+" ecp.*")
+os.system(deltext+" ecdh.*")
+os.system(deltext+" ff.*")
+os.system(deltext+" rsa.*")
+os.system(deltext+" config_big.h")
+os.system(deltext+" config_field.h")
+os.system(deltext+" config_curve.h")
+os.system(deltext+" config_ff.h")
+os.system(deltext+" fp2.*")
+os.system(deltext+" fp4.*")
+os.system(deltext+" fp8.*")
+os.system(deltext+" fp16.*")
+
+
+os.system(deltext+" fp12.*")
+os.system(deltext+" fp24.*")
+os.system(deltext+" fp48.*")
+
+os.system(deltext+" ecp2.*")
+os.system(deltext+" ecp4.*")
+os.system(deltext+" ecp8.*")
+
+os.system(deltext+" pair.*")
+os.system(deltext+" mpin.*")
+os.system(deltext+" bls.*")
+
+os.system(deltext+" pair192.*")
+os.system(deltext+" mpin192.*")
+os.system(deltext+" bls192.*")
+
+os.system(deltext+" pair256.*")
+os.system(deltext+" mpin256.*")
+os.system(deltext+" bls256.*")
+
+# create library
+os.system("gcc -O3 -std=c99 -c randapi.c")
+if curve_selected :
+       os.system("gcc -O3 -std=c99 -c ecdh_support.c")
+if rsa_selected :
+       os.system("gcc -O3 -std=c99 -c rsa_support.c")
+if pfcurve_selected :
+       os.system("gcc -O3 -std=c99 -c pbc_support.c")
+
+os.system("gcc -O3 -std=c99 -c hash.c")
+os.system("gcc -O3 -std=c99 -c rand.c")
+os.system("gcc -O3 -std=c99 -c oct.c")
+os.system("gcc -O3 -std=c99 -c aes.c")
+os.system("gcc -O3 -std=c99 -c gcm.c")
+os.system("gcc -O3 -std=c99 -c newhope.c")
+
+if sys.platform.startswith("win") :
+       os.system("for %i in (*.o) do @echo %~nxi >> f.list")
+       os.system("ar rc amcl.a @f.list")
+       os.system(deltext+" f.list")
+
+else :
+       os.system("ar rc amcl.a *.o")
+       
+os.system(deltext+" *.o")
+
+#print("Your section was ");   
+#for i in range(0,ptr):
+#      print (selection[i])
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config64.py
----------------------------------------------------------------------
diff --git a/version3/c/config64.py b/version3/c/config64.py
new file mode 100644
index 0000000..22fc9b8
--- /dev/null
+++ b/version3/c/config64.py
@@ -0,0 +1,681 @@
+import os
+import sys
+
+deltext=""
+if sys.platform.startswith("linux")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("darwin")  :
+       deltext="rm"
+       copytext="cp"
+if sys.platform.startswith("win") :
+       deltext="del"
+       copytext="copy"
+
+def replace(namefile,oldtext,newtext):
+       f = open(namefile,'r')
+       filedata = f.read()
+       f.close()
+
+       newdata = filedata.replace(oldtext,newtext)
+
+       f = open(namefile,'w')
+       f.write(newdata)
+       f.close()
+
+
+def rsaset(tb,tff,nb,base,ml) :
+       bd=tb+"_"+base
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+       fnameh="config_ff_"+tff+".h"
+       os.system(copytext+" config_ff.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"@ML@",ml);
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ff_"+tff+".c"
+       fnameh="ff_"+tff+".h"
+
+       os.system(copytext+" ff.c "+fnamec)
+       os.system(copytext+" ff.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="rsa_"+tff+".c"
+       fnameh="rsa_"+tff+".h"
+
+       os.system(copytext+" rsa.c "+fnamec)
+       os.system(copytext+" rsa.h "+fnameh)
+
+       replace(fnamec,"WWW",tff)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"WWW",tff)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+def curveset(tb,tf,tc,nb,base,nbt,m8,mt,ct,pf,stw,sx,cs) :
+       bd=tb+"_"+base
+       fnameh="config_big_"+bd+".h"
+       os.system(copytext+" config_big.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"@NB@",nb)
+       replace(fnameh,"@BASE@",base)
+
+       fnameh="config_field_"+tf+".h"
+       os.system(copytext+" config_field.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"@NBT@",nbt)
+       replace(fnameh,"@M8@",m8)
+       replace(fnameh,"@MT@",mt)
+
+       ib=int(base)
+       inb=int(nb)
+       inbt=int(nbt)
+       sh=ib*(1+((8*inb-1)//ib))-inbt
+       if sh > 30 :
+               sh=30
+       replace(fnameh,"@SH@",str(sh))
+
+       fnameh="config_curve_"+tc+".h"  
+       os.system(copytext+" config_curve.h "+fnameh)
+       replace(fnameh,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"@CT@",ct)
+       replace(fnameh,"@PF@",pf)
+
+       replace(fnameh,"@ST@",stw)
+       replace(fnameh,"@SX@",sx)
+       replace(fnameh,"@CS@",cs)
+
+       fnamec="big_"+bd+".c"
+       fnameh="big_"+bd+".h"
+
+       os.system(copytext+" big.c "+fnamec)
+       os.system(copytext+" big.h "+fnameh)
+
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="fp_"+tf+".c"
+       fnameh="fp_"+tf+".h"
+
+       os.system(copytext+" fp.c "+fnamec)
+       os.system(copytext+" fp.h "+fnameh)
+
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_field_"+tf+".c");
+
+       fnamec="ecp_"+tc+".c"
+       fnameh="ecp_"+tc+".h"
+
+       os.system(copytext+" ecp.c "+fnamec)
+       os.system(copytext+" ecp.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       fnamec="ecdh_"+tc+".c"
+       fnameh="ecdh_"+tc+".h"
+
+       os.system(copytext+" ecdh.c "+fnamec)
+       os.system(copytext+" ecdh.h "+fnameh)
+
+       replace(fnamec,"ZZZ",tc)
+       replace(fnamec,"YYY",tf)
+       replace(fnamec,"XXX",bd)
+       replace(fnameh,"ZZZ",tc)
+       replace(fnameh,"YYY",tf)
+       replace(fnameh,"XXX",bd)
+       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+       os.system("gcc -O3 -std=c99 -c rom_curve_"+tc+".c");
+
+       if pf != "NOT" :
+               fnamec="fp2_"+tf+".c"
+               fnameh="fp2_"+tf+".h"
+
+               os.system(copytext+" fp2.c "+fnamec)
+               os.system(copytext+" fp2.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               fnamec="fp4_"+tf+".c"
+               fnameh="fp4_"+tf+".h"
+
+               os.system(copytext+" fp4.c "+fnamec)
+               os.system(copytext+" fp4.h "+fnameh)
+               replace(fnamec,"YYY",tf)
+               replace(fnamec,"XXX",bd)
+               replace(fnamec,"ZZZ",tc)
+               replace(fnameh,"YYY",tf)
+               replace(fnameh,"XXX",bd)
+               replace(fnameh,"ZZZ",tc)
+               os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               if cs == "128" :
+                       fnamec="fp12_"+tf+".c"
+                       fnameh="fp12_"+tf+".h"
+
+                       os.system(copytext+" fp12.c "+fnamec)
+                       os.system(copytext+" fp12.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="ecp2_"+tc+".c"
+                       fnameh="ecp2_"+tc+".h"
+
+                       os.system(copytext+" ecp2.c "+fnamec)
+                       os.system(copytext+" ecp2.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="pair_"+tc+".c"
+                       fnameh="pair_"+tc+".h"
+
+                       os.system(copytext+" pair.c "+fnamec)
+                       os.system(copytext+" pair.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin_"+tc+".c"
+                       fnameh="mpin_"+tc+".h"
+
+                       os.system(copytext+" mpin.c "+fnamec)
+                       os.system(copytext+" mpin.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="bls_"+tc+".c"
+                       fnameh="bls_"+tc+".h"
+
+                       os.system(copytext+" bls.c "+fnamec)
+                       os.system(copytext+" bls.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               if cs == "192" :
+                       fnamec="fp8_"+tf+".c"
+                       fnameh="fp8_"+tf+".h"
+
+                       os.system(copytext+" fp8.c "+fnamec)
+                       os.system(copytext+" fp8.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp24_"+tf+".c"
+                       fnameh="fp24_"+tf+".h"
+
+                       os.system(copytext+" fp24.c "+fnamec)
+                       os.system(copytext+" fp24.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="ecp4_"+tc+".c"
+                       fnameh="ecp4_"+tc+".h"
+
+                       os.system(copytext+" ecp4.c "+fnamec)
+                       os.system(copytext+" ecp4.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="pair192_"+tc+".c"
+                       fnameh="pair192_"+tc+".h"
+
+                       os.system(copytext+" pair192.c "+fnamec)
+                       os.system(copytext+" pair192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin192_"+tc+".c"
+                       fnameh="mpin192_"+tc+".h"
+
+                       os.system(copytext+" mpin192.c "+fnamec)
+                       os.system(copytext+" mpin192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="bls192_"+tc+".c"
+                       fnameh="bls192_"+tc+".h"
+
+                       os.system(copytext+" bls192.c "+fnamec)
+                       os.system(copytext+" bls192.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+               if cs == "256" :
+
+                       fnamec="fp8_"+tf+".c"
+                       fnameh="fp8_"+tf+".h"
+
+                       os.system(copytext+" fp8.c "+fnamec)
+                       os.system(copytext+" fp8.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="ecp8_"+tc+".c"
+                       fnameh="ecp8_"+tc+".h"
+
+                       os.system(copytext+" ecp8.c "+fnamec)
+                       os.system(copytext+" ecp8.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp16_"+tf+".c"
+                       fnameh="fp16_"+tf+".h"
+
+                       os.system(copytext+" fp16.c "+fnamec)
+                       os.system(copytext+" fp16.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="fp48_"+tf+".c"
+                       fnameh="fp48_"+tf+".h"
+
+                       os.system(copytext+" fp48.c "+fnamec)
+                       os.system(copytext+" fp48.h "+fnameh)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+
+                       fnamec="pair256_"+tc+".c"
+                       fnameh="pair256_"+tc+".h"
+
+                       os.system(copytext+" pair256.c "+fnamec)
+                       os.system(copytext+" pair256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="mpin256_"+tc+".c"
+                       fnameh="mpin256_"+tc+".h"
+
+                       os.system(copytext+" mpin256.c "+fnamec)
+                       os.system(copytext+" mpin256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+                       fnamec="bls256_"+tc+".c"
+                       fnameh="bls256_"+tc+".h"
+
+                       os.system(copytext+" bls256.c "+fnamec)
+                       os.system(copytext+" bls256.h "+fnameh)
+                       replace(fnamec,"ZZZ",tc)
+                       replace(fnamec,"YYY",tf)
+                       replace(fnamec,"XXX",bd)
+                       replace(fnameh,"ZZZ",tc)
+                       replace(fnameh,"YYY",tf)
+                       replace(fnameh,"XXX",bd)
+                       os.system("gcc -O3 -std=c99 -c "+fnamec)
+
+replace("arch.h","@WL@","64")
+print("Elliptic Curves")
+print("1. ED25519")
+print("2. C25519")
+print("3. NIST256")
+print("4. BRAINPOOL")
+print("5. ANSSI")
+print("6. HIFIVE")
+print("7. GOLDILOCKS")
+print("8. NIST384")
+print("9. C41417")
+print("10. NIST521\n")
+print("11. NUMS256W")
+print("12. NUMS256E")
+print("13. NUMS384W")
+print("14. NUMS384E")
+print("15. NUMS512W")
+print("16. NUMS512E")
+print("17. SECP256K1\n")
+
+print("Pairing-Friendly Elliptic Curves")
+print("18. BN254")
+print("19. BN254CX")
+print("20. BLS383")
+print("21. BLS381")
+print("22. FP256BN")
+print("23. FP512BN")
+print("24. BLS461\n")
+print("25. BLS24")
+print("26. BLS48\n")
+
+print("RSA")
+print("27. RSA2048")
+print("28. RSA3072")
+print("29. RSA4096")
+
+selection=[]
+ptr=0
+max=30
+
+curve_selected=False
+pfcurve_selected=False
+rsa_selected=False
+
+while ptr<max:
+       x=int(input("Choose a Scheme to support - 0 to finish: "))
+       if x == 0:
+               break
+#      print("Choice= ",x)
+       already=False
+       for i in range(0,ptr):
+               if x==selection[i]:
+                       already=True
+                       break
+       if already:
+               continue
+       
+       selection.append(x)
+       ptr=ptr+1
+
+# 
curveset(big,field,curve,big_length_bytes,bits_in_base,modulus_bits,modulus_mod_8,modulus_type,curve_type,pairing_friendly,sextic
 twist,sign of x,curve security)
+# for each curve give names for big, field and curve. In many cases the latter 
two will be the same. 
+# Typically "big" is the size in bits, always a multiple of 8, "field" 
describes the modulus, and "curve" is the common name for the elliptic curve   
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 64 bit architectures, as n where the base 
is 2^n (note that these must be fixed for the same "big" name, if is ever 
re-used for another curve)
+# modulus_bits is the bit length of the modulus, typically the same or 
slightly smaller than "big"
+# modulus_mod_8 is the remainder when the modulus is divided by 8
+# modulus_type is NOT_SPECIAL, or PSEUDO_MERSENNE, or MONTGOMERY_Friendly, or 
GENERALISED_MERSENNE (supported for GOLDILOCKS only)
+# curve_type is WEIERSTRASS, EDWARDS or MONTGOMERY
+# pairing_friendly is BN, BLS or NOT (if not pairing friendly)
+# if pairing friendly. M or D type twist, and sign of the family parameter x
+# curve security is AES equiavlent, rounded up.
+
+       if x==1:
+               
curveset("256","25519","ED25519","32","56","255","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==2:
+               
curveset("256","25519","C25519","32","56","255","5","PSEUDO_MERSENNE","MONTGOMERY","NOT","","","128")
+               curve_selected=True
+       if x==3:
+               
curveset("256","NIST256","NIST256","32","56","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==4:
+               
curveset("256","BRAINPOOL","BRAINPOOL","32","56","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==5:
+               
curveset("256","ANSSI","ANSSI","32","56","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+
+       if x==6:
+               
curveset("336","HIFIVE","HIFIVE","42","60","336","5","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==7:
+               
curveset("448","GOLDILOCKS","GOLDILOCKS","56","58","448","7","GENERALISED_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==8:
+               
curveset("384","NIST384","NIST384","48","56","384","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==9:
+               
curveset("416","C41417","C41417","52","60","414","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==10:
+               
curveset("528","NIST521","NIST521","66","60","521","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+
+       if x==11:
+               
curveset("256","256PMW","NUMS256W","32","56","256","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==12:
+               
curveset("256","256PME","NUMS256E","32","56","256","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==13:
+               
curveset("384","384PM","NUMS384W","48","56","384","3","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==14:
+               
curveset("384","384PM","NUMS384E","48","56","384","3","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+       if x==15:
+               
curveset("512","512PM","NUMS512W","64","56","512","7","PSEUDO_MERSENNE","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+       if x==16:
+               
curveset("512","512PM","NUMS512E","64","56","512","7","PSEUDO_MERSENNE","EDWARDS","NOT","","","128")
+               curve_selected=True
+
+       if x==17:
+               
curveset("256","SECP256K1","SECP256K1","32","56","256","7","NOT_SPECIAL","WEIERSTRASS","NOT","","","128")
+               curve_selected=True
+
+
+       if x==18:
+               
curveset("256","BN254","BN254","32","56","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==19:
+               
curveset("256","BN254CX","BN254CX","32","56","254","3","NOT_SPECIAL","WEIERSTRASS","BN","D_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==20:
+               
curveset("384","BLS383","BLS383","48","58","383","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","128")
+               pfcurve_selected=True
+
+       if x==21:
+               
curveset("384","BLS381","BLS381","48","58","381","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+
+
+       if x==22:
+               
curveset("256","FP256BN","FP256BN","32","56","256","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+       if x==23:
+               
curveset("512","FP512BN","FP512BN","64","60","512","3","NOT_SPECIAL","WEIERSTRASS","BN","M_TYPE","POSITIVEX","128")
+               pfcurve_selected=True
+# https://eprint.iacr.org/2017/334.pdf
+       if x==24:
+               
curveset("464","BLS461","BLS461","58","60","461","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","NEGATIVEX","128")
+               pfcurve_selected=True
+
+       if x==25:
+               
curveset("480","BLS24","BLS24","60","56","479","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","192")
+               pfcurve_selected=True
+
+       if x==26:
+               
curveset("560","BLS48","BLS48","70","58","556","3","NOT_SPECIAL","WEIERSTRASS","BLS","M_TYPE","POSITIVEX","256")
+               pfcurve_selected=True
+
+
+# rsaset(big,ring,big_length_bytes,bits_in_base,multiplier)
+# for each choice give distinct names for "big" and "ring".
+# Typically "big" is the length in bits of the underlying big number type
+# "ring" is the RSA modulus size = "big" times 2^m
+# big_length_bytes is "big" divided by 8
+# Next give the number base used for 64 bit architecture, as n where the base 
is 2^n
+# multiplier is 2^m (see above)
+
+# There are choices here, different ways of getting the same result, but some 
faster than others
+       if x==27:
+               #256 is slower but may allow reuse of 256-bit BIGs used for 
elliptic curve
+               #512 is faster.. but best is 1024
+               rsaset("1024","2048","128","58","2")
+               #rsaset("512","2048","64","60","4")
+               #rsaset("256","2048","32","56","8")
+               rsa_selected=True
+       if x==28:
+               rsaset("384","3072","48","56","8")
+               rsa_selected=True
+       if x==29:
+               #rsaset("256","4096","32","56","16")
+               rsaset("512","4096","64","60","8")
+               rsa_selected=True
+
+
+os.system(deltext+" big.*")
+os.system(deltext+" fp.*")
+os.system(deltext+" ecp.*")
+os.system(deltext+" ecdh.*")
+os.system(deltext+" ff.*")
+os.system(deltext+" rsa.*")
+os.system(deltext+" config_big.h")
+os.system(deltext+" config_field.h")
+os.system(deltext+" config_curve.h")
+os.system(deltext+" config_ff.h")
+os.system(deltext+" fp2.*")
+os.system(deltext+" fp4.*")
+os.system(deltext+" fp8.*")
+os.system(deltext+" fp16.*")
+
+os.system(deltext+" fp12.*")
+os.system(deltext+" fp24.*")
+os.system(deltext+" fp48.*")
+
+os.system(deltext+" ecp2.*")
+os.system(deltext+" ecp4.*")
+os.system(deltext+" ecp8.*")
+
+os.system(deltext+" pair.*")
+os.system(deltext+" mpin.*")
+os.system(deltext+" bls.*")
+
+os.system(deltext+" pair192.*")
+os.system(deltext+" mpin192.*")
+os.system(deltext+" bls192.*")
+
+os.system(deltext+" pair256.*")
+os.system(deltext+" mpin256.*")
+os.system(deltext+" bls256.*")
+
+# create library
+os.system("gcc -O3 -std=c99 -c randapi.c")
+if curve_selected :
+       os.system("gcc -O3 -std=c99 -c ecdh_support.c")
+if rsa_selected :
+       os.system("gcc -O3 -std=c99 -c rsa_support.c")
+if pfcurve_selected :
+       os.system("gcc -O3 -std=c99 -c pbc_support.c")
+
+os.system("gcc -O3 -std=c99 -c hash.c")
+os.system("gcc -O3 -std=c99 -c rand.c")
+os.system("gcc -O3 -std=c99 -c oct.c")
+os.system("gcc -O3 -std=c99 -c aes.c")
+os.system("gcc -O3 -std=c99 -c gcm.c")
+os.system("gcc -O3 -std=c99 -c newhope.c")
+
+if sys.platform.startswith("win") :
+       os.system("for %i in (*.o) do @echo %~nxi >> f.list")
+       os.system("ar rc amcl.a @f.list")
+       os.system(deltext+" f.list")
+
+else :
+       os.system("ar rc amcl.a *.o")
+
+os.system(deltext+" *.o")
+
+
+#print("Your section was ");   
+#for i in range(0,ptr):
+#      print (selection[i])
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config_big.h
----------------------------------------------------------------------
diff --git a/version3/c/config_big.h b/version3/c/config_big.h
new file mode 100644
index 0000000..76822ed
--- /dev/null
+++ b/version3/c/config_big.h
@@ -0,0 +1,38 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+/**
+ * @file config_big.h
+ * @author Mike Scott
+ * @brief Config BIG  Header File
+ *
+ */
+
+#ifndef CONFIG_BIG_XXX_H
+#define CONFIG_BIG_XXX_H
+
+#include"amcl.h"
+
+// BIG stuff
+
+#define MODBYTES_XXX @NB@      /**< Number of bytes in Modulus */
+#define BASEBITS_XXX @BASE@    /**< Numbers represented to base 2*BASEBITS */
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config_curve.h
----------------------------------------------------------------------
diff --git a/version3/c/config_curve.h b/version3/c/config_curve.h
new file mode 100644
index 0000000..58208df
--- /dev/null
+++ b/version3/c/config_curve.h
@@ -0,0 +1,44 @@
+#ifndef CONFIG_CURVE_ZZZ_H
+#define CONFIG_CURVE_ZZZ_H
+
+#include"amcl.h"
+#include"config_field_YYY.h"
+
+// ECP stuff
+
+#define CURVETYPE_ZZZ @CT@
+#define PAIRING_FRIENDLY_ZZZ @PF@
+#define CURVE_SECURITY_ZZZ @CS@
+
+
+#if PAIRING_FRIENDLY_ZZZ != NOT
+//#define USE_GLV_ZZZ    /**< Note this method is patented (GLV), so maybe you 
want to comment this out */
+//#define USE_GS_G2_ZZZ /**< Well we didn't patent it :) But may be covered by 
GLV patent :( */
+#define USE_GS_GT_ZZZ /**< Not patented, so probably safe to always use this */
+
+#define POSITIVEX 0
+#define NEGATIVEX 1
+
+#define SEXTIC_TWIST_ZZZ @ST@
+#define SIGN_OF_X_ZZZ @SX@
+
+#endif
+
+#if CURVE_SECURITY_ZZZ == 128
+#define AESKEY_ZZZ 16 /**< Symmetric Key size - 128 bits */
+#define HASH_TYPE_ZZZ SHA256  /**< Hash type */
+#endif
+
+#if CURVE_SECURITY_ZZZ == 192
+#define AESKEY_ZZZ 24 /**< Symmetric Key size - 192 bits */
+#define HASH_TYPE_ZZZ SHA384  /**< Hash type */
+#endif
+
+#if CURVE_SECURITY_ZZZ == 256
+#define AESKEY_ZZZ 32 /**< Symmetric Key size - 256 bits */
+#define HASH_TYPE_ZZZ SHA512  /**< Hash type */
+#endif
+
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config_ff.h
----------------------------------------------------------------------
diff --git a/version3/c/config_ff.h b/version3/c/config_ff.h
new file mode 100644
index 0000000..173dab7
--- /dev/null
+++ b/version3/c/config_ff.h
@@ -0,0 +1,38 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+/**
+ * @file config_ff.h
+ * @author Mike Scott
+ * @brief COnfig FF Header File
+ *
+ */
+
+#ifndef CONFIG_RSA_WWW_H
+#define CONFIG_RSA_WWW_H
+
+#include "amcl.h"
+#include "config_big_XXX.h"
+
+// FF stuff
+
+#define FFLEN_WWW @ML@ /**< 2^n multiplier of BIGBITS to specify supported 
Finite Field size, e.g 2048=256*2^3 where BIGBITS=256 */
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/config_field.h
----------------------------------------------------------------------
diff --git a/version3/c/config_field.h b/version3/c/config_field.h
new file mode 100644
index 0000000..2d727f2
--- /dev/null
+++ b/version3/c/config_field.h
@@ -0,0 +1,34 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+#ifndef CONFIG_FIELD_YYY_H
+#define CONFIG_FIELD_YYY_H
+
+#include"amcl.h"
+#include "config_big_XXX.h"
+
+// FP stuff
+
+#define MBITS_YYY @NBT@
+#define MOD8_YYY @M8@
+#define MODTYPE_YYY @MT@
+#define MAXXES_YYY @SH@
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/ecdh.c
----------------------------------------------------------------------
diff --git a/version3/c/ecdh.c b/version3/c/ecdh.c
new file mode 100644
index 0000000..953685d
--- /dev/null
+++ b/version3/c/ecdh.c
@@ -0,0 +1,368 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT 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 Functions - see main program below */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "ecdh_ZZZ.h"
+
+/* Calculate a public/private EC GF(p) key pair. 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 */
+int ECP_ZZZ_KEY_PAIR_GENERATE(csprng *RNG,octet* S,octet *W)
+{
+    BIG_XXX r,gx,gy,s;
+    ECP_ZZZ G;
+    int res=0;
+
+       ECP_ZZZ_generator(&G);
+
+    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+    if (RNG!=NULL)
+    {
+        BIG_XXX_randomnum(s,r,RNG);
+    }
+    else
+    {
+        BIG_XXX_fromBytes(s,S->val);
+        BIG_XXX_mod(s,r);
+    }
+
+#ifdef AES_S
+    BIG_XXX_mod2m(s,2*AES_S);
+#endif
+
+    S->len=EGS_ZZZ;
+    BIG_XXX_toBytes(S->val,s);
+
+    ECP_ZZZ_mul(&G,s);
+
+       ECP_ZZZ_toOctet(W,&G,false);  /* To use point compression on public 
keys, change to true */
+
+    return res;
+}
+
+/* Validate public key */
+int ECP_ZZZ_PUBLIC_KEY_VALIDATE(octet *W)
+{
+    BIG_XXX q,r,wx,k;
+    ECP_ZZZ WP;
+    int valid,nb;
+    int res=0;
+
+    BIG_XXX_rcopy(q,Modulus_YYY);
+    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+       valid=ECP_ZZZ_fromOctet(&WP,W);
+       if (!valid) res=ECDH_INVALID_PUBLIC_KEY;
+
+    if (res==0)
+    { /* Check point is not in wrong group */
+        nb=BIG_XXX_nbits(q);
+        BIG_XXX_one(k);
+        BIG_XXX_shl(k,(nb+4)/2);
+        BIG_XXX_add(k,q,k);
+        BIG_XXX_sdiv(k,r); /* get co-factor */
+
+        while (BIG_XXX_parity(k)==0)
+        {
+            ECP_ZZZ_dbl(&WP);
+            BIG_XXX_fshr(k,1);
+        }
+
+        if (!BIG_XXX_isunity(k)) ECP_ZZZ_mul(&WP,k);
+        if (ECP_ZZZ_isinf(&WP)) res=ECDH_INVALID_PUBLIC_KEY;
+    }
+
+    return res;
+}
+
+/* IEEE-1363 Diffie-Hellman online calculation Z=S.WD */
+int ECP_ZZZ_SVDP_DH(octet *S,octet *WD,octet *Z)
+{
+    BIG_XXX r,s,wx;
+    int valid;
+    ECP_ZZZ W;
+    int res=0;
+
+    BIG_XXX_fromBytes(s,S->val);
+
+       valid=ECP_ZZZ_fromOctet(&W,WD);
+
+    if (!valid) res=ECDH_ERROR;
+    if (res==0)
+    {
+        BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+        BIG_XXX_mod(s,r);
+
+        ECP_ZZZ_mul(&W,s);
+        if (ECP_ZZZ_isinf(&W)) res=ECDH_ERROR;
+        else
+        {
+#if CURVETYPE_ZZZ!=MONTGOMERY
+            ECP_ZZZ_get(wx,wx,&W);
+#else
+            ECP_ZZZ_get(wx,&W);
+#endif
+            Z->len=MODBYTES_XXX;
+            BIG_XXX_toBytes(Z->val,wx);
+        }
+    }
+    return res;
+}
+
+#if CURVETYPE_ZZZ!=MONTGOMERY
+
+/* IEEE ECDSA Signature, C and D are signature on F using private key S */
+int ECP_ZZZ_SP_DSA(int sha,csprng *RNG,octet *K,octet *S,octet *F,octet 
*C,octet *D)
+{
+    char h[128];
+    octet H= {0,sizeof(h),h};
+
+    BIG_XXX gx,gy,r,s,f,c,d,u,vx,w;
+    ECP_ZZZ G,V;
+
+    ehashit(sha,F,-1,NULL,&H,sha);
+
+       ECP_ZZZ_generator(&G);
+
+    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+    BIG_XXX_fromBytes(s,S->val);
+
+    int hlen=H.len;
+    if (H.len>MODBYTES_XXX) hlen=MODBYTES_XXX;
+    BIG_XXX_fromBytesLen(f,H.val,hlen);
+
+       if (RNG!=NULL)
+       {
+               do
+               {
+            BIG_XXX_randomnum(u,r,RNG);
+            BIG_XXX_randomnum(w,r,RNG); /* side channel masking */
+
+#ifdef AES_S
+                       BIG_XXX_mod2m(u,2*AES_S);
+#endif
+                       ECP_ZZZ_copy(&V,&G);
+                       ECP_ZZZ_mul(&V,u);
+
+                       ECP_ZZZ_get(vx,vx,&V);
+
+                       BIG_XXX_copy(c,vx);
+                       BIG_XXX_mod(c,r);
+                       if (BIG_XXX_iszilch(c)) continue;
+                       
+            BIG_XXX_modmul(u,u,w,r);
+
+                       BIG_XXX_invmodp(u,u,r);
+                       BIG_XXX_modmul(d,s,c,r);
+
+                       BIG_XXX_add(d,f,d);
+                       
+            BIG_XXX_modmul(d,d,w,r);
+
+                       BIG_XXX_modmul(d,u,d,r);
+               } while (BIG_XXX_iszilch(d));
+       }
+       else
+       {
+               BIG_XXX_fromBytes(u,K->val);
+               BIG_XXX_mod(u,r);
+
+#ifdef AES_S
+        BIG_XXX_mod2m(u,2*AES_S);
+#endif
+        ECP_ZZZ_copy(&V,&G);
+        ECP_ZZZ_mul(&V,u);
+
+        ECP_ZZZ_get(vx,vx,&V);
+
+        BIG_XXX_copy(c,vx);
+        BIG_XXX_mod(c,r);
+        if (BIG_XXX_iszilch(c)) return ECDH_ERROR;
+ 
+
+        BIG_XXX_invmodp(u,u,r);
+        BIG_XXX_modmul(d,s,c,r);
+
+        BIG_XXX_add(d,f,d);
+
+        BIG_XXX_modmul(d,u,d,r);
+        if (BIG_XXX_iszilch(d)) return ECDH_ERROR;
+    }
+
+    C->len=D->len=EGS_ZZZ;
+
+    BIG_XXX_toBytes(C->val,c);
+    BIG_XXX_toBytes(D->val,d);
+
+    return 0;
+}
+
+/* IEEE1363 ECDSA Signature Verification. Signature C and D on F is verified 
using public key W */
+int ECP_ZZZ_VP_DSA(int sha,octet *W,octet *F, octet *C,octet *D)
+{
+    char h[128];
+    octet H= {0,sizeof(h),h};
+
+    BIG_XXX r,gx,gy,wx,wy,f,c,d,h2;
+    int res=0;
+    ECP_ZZZ G,WP;
+    int valid;
+
+    ehashit(sha,F,-1,NULL,&H,sha);
+
+       ECP_ZZZ_generator(&G);
+
+    BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+    OCT_shl(C,C->len-MODBYTES_XXX);
+    OCT_shl(D,D->len-MODBYTES_XXX);
+
+    BIG_XXX_fromBytes(c,C->val);
+    BIG_XXX_fromBytes(d,D->val);
+
+    int hlen=H.len;
+    if (hlen>MODBYTES_XXX) hlen=MODBYTES_XXX;
+
+    BIG_XXX_fromBytesLen(f,H.val,hlen);
+
+    //BIG_fromBytes(f,H.val);
+
+    if (BIG_XXX_iszilch(c) || BIG_XXX_comp(c,r)>=0 || BIG_XXX_iszilch(d) || 
BIG_XXX_comp(d,r)>=0)
+        res=ECDH_INVALID;
+
+    if (res==0)
+    {
+        BIG_XXX_invmodp(d,d,r);
+        BIG_XXX_modmul(f,f,d,r);
+        BIG_XXX_modmul(h2,c,d,r);
+
+               valid=ECP_ZZZ_fromOctet(&WP,W);
+
+        if (!valid) res=ECDH_ERROR;
+        else
+        {
+            ECP_ZZZ_mul2(&WP,&G,h2,f);
+
+            if (ECP_ZZZ_isinf(&WP)) res=ECDH_INVALID;
+            else
+            {
+                ECP_ZZZ_get(d,d,&WP);
+                BIG_XXX_mod(d,r);
+                if (BIG_XXX_comp(d,c)!=0) res=ECDH_INVALID;
+            }
+        }
+    }
+
+    return res;
+}
+
+/* IEEE1363 ECIES encryption. Encryption of plaintext M uses public key W and 
produces ciphertext V,C,T */
+void ECP_ZZZ_ECIES_ENCRYPT(int sha,octet *P1,octet *P2,csprng *RNG,octet 
*W,octet *M,int tlen,octet *V,octet *C,octet *T)
+{
+
+    int i,len;
+    char 
z[EFS_ZZZ],vz[3*EFS_ZZZ+1],k[2*AESKEY_ZZZ],k1[AESKEY_ZZZ],k2[AESKEY_ZZZ],l2[8],u[EFS_ZZZ];
+    octet Z= {0,sizeof(z),z};
+    octet VZ= {0,sizeof(vz),vz};
+    octet K= {0,sizeof(k),k};
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+    octet L2= {0,sizeof(l2),l2};
+    octet U= {0,sizeof(u),u};
+
+    if (ECP_ZZZ_KEY_PAIR_GENERATE(RNG,&U,V)!=0) return;
+    if (ECP_ZZZ_SVDP_DH(&U,W,&Z)!=0) return;
+
+    OCT_copy(&VZ,V);
+    OCT_joctet(&VZ,&Z);
+
+    KDF2(sha,&VZ,P1,2*AESKEY_ZZZ,&K);
+
+    K1.len=K2.len=AESKEY_ZZZ;
+    for (i=0; i<AESKEY_ZZZ; i++)
+    {
+        K1.val[i]=K.val[i];
+        K2.val[i]=K.val[AESKEY_ZZZ+i];
+    }
+
+    AES_CBC_IV0_ENCRYPT(&K1,M,C);
+
+    OCT_jint(&L2,P2->len,8);
+
+    len=C->len;
+    OCT_joctet(C,P2);
+    OCT_joctet(C,&L2);
+    HMAC(sha,C,&K2,tlen,T);
+    C->len=len;
+}
+
+/* IEEE1363 ECIES decryption. Decryption of ciphertext V,C,T using private key 
U outputs plaintext M */
+int ECP_ZZZ_ECIES_DECRYPT(int sha,octet *P1,octet *P2,octet *V,octet *C,octet 
*T,octet *U,octet *M)
+{
+
+    int i,len;
+    char 
z[EFS_ZZZ],vz[3*EFS_ZZZ+1],k[2*AESKEY_ZZZ],k1[AESKEY_ZZZ],k2[AESKEY_ZZZ],l2[8],tag[32];
+    octet Z= {0,sizeof(z),z};
+    octet VZ= {0,sizeof(vz),vz};
+    octet K= {0,sizeof(k),k};
+    octet K1= {0,sizeof(k1),k1};
+    octet K2= {0,sizeof(k2),k2};
+    octet L2= {0,sizeof(l2),l2};
+    octet TAG= {0,sizeof(tag),tag};
+
+    if (ECP_ZZZ_SVDP_DH(U,V,&Z)!=0) return 0;
+
+    OCT_copy(&VZ,V);
+    OCT_joctet(&VZ,&Z);
+
+    KDF2(sha,&VZ,P1,2*AESKEY_ZZZ,&K);
+
+    K1.len=K2.len=AESKEY_ZZZ;
+    for (i=0; i<AESKEY_ZZZ; i++)
+    {
+        K1.val[i]=K.val[i];
+        K2.val[i]=K.val[AESKEY_ZZZ+i];
+    }
+
+    if (!AES_CBC_IV0_DECRYPT(&K1,C,M)) return 0;
+
+    OCT_jint(&L2,P2->len,8);
+
+    len=C->len;
+    OCT_joctet(C,P2);
+    OCT_joctet(C,&L2);
+    HMAC(sha,C,&K2,T->len,&TAG);
+    C->len=len;
+
+    if (!OCT_ncomp(T,&TAG,T->len)) return 0;
+
+    return 1;
+
+}
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/ecdh.h
----------------------------------------------------------------------
diff --git a/version3/c/ecdh.h b/version3/c/ecdh.h
new file mode 100644
index 0000000..10a1828
--- /dev/null
+++ b/version3/c/ecdh.h
@@ -0,0 +1,146 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/**
+ * @file ecdh.h
+ * @author Mike Scott
+ * @brief ECDH Header file for implementation of standard EC protocols
+ *
+ *
+ */
+
+#ifndef ECDH_ZZZ_H
+#define ECDH_ZZZ_H
+
+#include "ecp_ZZZ.h"
+#include "ecdh_support.h"
+
+
+/*** START OF USER CONFIGURABLE SECTION -  ***/
+
+//#define EAS_ZZZ 16 /**< Symmetric Key size - 128 bits */
+//#define HASH_TYPE_ECC_ZZZ SHA512  /**< Hash type */
+
+/*** END OF USER CONFIGURABLE SECTION ***/
+
+#define EGS_ZZZ MODBYTES_XXX  /**< ECC Group Size in bytes */
+#define EFS_ZZZ MODBYTES_XXX  /**< ECC Field Size in bytes */
+
+#define ECDH_OK                     0     /**< Function completed without 
error */
+/*#define ECDH_DOMAIN_ERROR          -1*/
+#define ECDH_INVALID_PUBLIC_KEY    -2  /**< Public Key is Invalid */
+#define ECDH_ERROR                 -3  /**< ECDH Internal Error */
+#define ECDH_INVALID               -4  /**< ECDH Internal Error */
+/*#define ECDH_DOMAIN_NOT_FOUND      -5
+#define ECDH_OUT_OF_MEMORY         -6
+#define ECDH_DIV_BY_ZERO           -7
+#define ECDH_BAD_ASSUMPTION        -8*/
+
+/* ECDH primitives */
+/**    @brief Generate an ECC public/private key pair
+ *
+       @param R is a pointer to a cryptographically secure random number 
generator
+       @param s the private key, an output internally randomly generated if 
R!=NULL, otherwise must be provided as an input
+       @param W the output public key, which is s.G, where G is a fixed 
generator
+       @return 0 or an error code
+ */
+extern int  ECP_ZZZ_KEY_PAIR_GENERATE(csprng *R,octet *s,octet *W);
+/**    @brief Validate an ECC public key
+ *
+       @param W the input public key to be validated
+       @return 0 if public key is OK, or an error code
+ */
+extern int  ECP_ZZZ_PUBLIC_KEY_VALIDATE(octet *W);
+
+/* ECDH primitives */
+
+/**    @brief Generate Diffie-Hellman shared key
+ *
+       IEEE-1363 Diffie-Hellman shared secret calculation
+       @param s is the input private key,
+       @param W the input public key of the other party
+       @param K the output shared key, in fact the x-coordinate of s.W
+       @return 0 or an error code
+ */
+extern int ECP_ZZZ_SVDP_DH(octet *s,octet *W,octet *K);
+/*extern int ECPSVDP_DHC(octet *,octet *,int,octet *);*/
+
+/*#if CURVETYPE!=MONTGOMERY */
+/* ECIES functions */
+/*#if CURVETYPE!=MONTGOMERY */
+/* ECIES functions */
+/**    @brief ECIES Encryption
+ *
+       IEEE-1363 ECIES Encryption
+       @param h is the hash type
+       @param P1 input Key Derivation parameters
+       @param P2 input Encoding parameters
+       @param R is a pointer to a cryptographically secure random number 
generator
+       @param W the input public key of the recieving party
+       @param M is the plaintext message to be encrypted
+       @param len the length of the HMAC tag
+       @param V component of the output ciphertext
+       @param C the output ciphertext
+       @param T the output HMAC tag, part of the ciphertext
+ */
+extern void ECP_ZZZ_ECIES_ENCRYPT(int h,octet *P1,octet *P2,csprng *R,octet 
*W,octet *M,int len,octet *V,octet *C,octet *T);
+/**    @brief ECIES Decryption
+ *
+       IEEE-1363 ECIES Decryption
+       @param h is the hash type
+       @param P1 input Key Derivation parameters
+       @param P2 input Encoding parameters
+       @param V component of the input ciphertext
+       @param C the input ciphertext
+       @param T the input HMAC tag, part of the ciphertext
+       @param U the input private key for decryption
+       @param M the output plaintext message
+       @return 1 if successful, else 0
+ */
+extern int ECP_ZZZ_ECIES_DECRYPT(int h,octet *P1,octet *P2,octet *V,octet 
*C,octet *T,octet *U,octet *M);
+
+/* ECDSA functions */
+/**    @brief ECDSA Signature
+ *
+       IEEE-1363 ECDSA Signature
+       @param h is the hash type
+       @param R is a pointer to a cryptographically secure random number 
generator
+        @param k Ephemeral key. This value is used when R=NULL
+       @param s the input private signing key
+       @param M the input message to be signed
+       @param c component of the output signature
+       @param d component of the output signature
+
+ */
+extern int ECP_ZZZ_SP_DSA(int h,csprng *R,octet *k,octet *s,octet *M,octet 
*c,octet *d);
+/**    @brief ECDSA Signature Verification
+ *
+       IEEE-1363 ECDSA Signature Verification
+       @param h is the hash type
+       @param W the input public key
+       @param M the input message
+       @param c component of the input signature
+       @param d component of the input signature
+       @return 0 or an error code
+ */
+extern int ECP_ZZZ_VP_DSA(int h,octet *W,octet *M,octet *c,octet *d);
+/*#endif*/
+
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/c25f9e5c/version3/c/ecdh_support.c
----------------------------------------------------------------------
diff --git a/version3/c/ecdh_support.c b/version3/c/ecdh_support.c
new file mode 100644
index 0000000..ee9397b
--- /dev/null
+++ b/version3/c/ecdh_support.c
@@ -0,0 +1,329 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/* Symmetric crypto support functions Functions  */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "ecdh_support.h"
+
+#define ROUNDUP(a,b) ((a)-1)/(b)+1
+
+/* general purpose hash function w=hash(p|n|x|y) */
+/* pad or truncate ouput to length pad if pad!=0 */
+void ehashit(int sha,octet *p,int n,octet *x,octet *w,int pad)
+{
+    int i,c[4],hlen;
+    hash256 sha256;
+    hash512 sha512;
+    char hh[64];
+
+    switch (sha)
+    {
+    case SHA256:
+        HASH256_init(&sha256);
+        break;
+    case SHA384:
+        HASH384_init(&sha512);
+        break;
+    case SHA512:
+        HASH512_init(&sha512);
+        break;
+    }
+
+    hlen=sha;
+
+    for (i=0; i<p->len; i++)
+    {
+        switch(sha)
+        {
+        case SHA256:
+            HASH256_process(&sha256,p->val[i]);
+            break;
+        case SHA384:
+            HASH384_process(&sha512,p->val[i]);
+            break;
+        case SHA512:
+            HASH512_process(&sha512,p->val[i]);
+            break;
+        }
+    }
+    if (n>0)
+    {
+        c[0]=(n>>24)&0xff;
+        c[1]=(n>>16)&0xff;
+        c[2]=(n>>8)&0xff;
+        c[3]=(n)&0xff;
+        for (i=0; i<4; i++)
+        {
+            switch(sha)
+            {
+            case SHA256:
+                HASH256_process(&sha256,c[i]);
+                break;
+            case SHA384:
+                HASH384_process(&sha512,c[i]);
+                break;
+            case SHA512:
+                HASH512_process(&sha512,c[i]);
+                break;
+            }
+        }
+    }
+    if (x!=NULL) for (i=0; i<x->len; i++)
+        {
+            switch(sha)
+            {
+            case SHA256:
+                HASH256_process(&sha256,x->val[i]);
+                break;
+            case SHA384:
+                HASH384_process(&sha512,x->val[i]);
+                break;
+            case SHA512:
+                HASH512_process(&sha512,x->val[i]);
+                break;
+            }
+        }
+
+    switch (sha)
+    {
+    case SHA256:
+        HASH256_hash(&sha256,hh);
+        break;
+    case SHA384:
+        HASH384_hash(&sha512,hh);
+        break;
+    case SHA512:
+        HASH512_hash(&sha512,hh);
+        break;
+    }
+
+    OCT_empty(w);
+    if (!pad)
+        OCT_jbytes(w,hh,hlen);
+    else
+    {
+        if (pad<=hlen)
+            OCT_jbytes(w,hh,pad);
+        else
+        {
+            OCT_jbyte(w,0,pad-hlen);
+            OCT_jbytes(w,hh,hlen);
+
+//            OCT_jbytes(w,hh,hlen);
+//            OCT_jbyte(w,0,pad-hlen);
+        }
+    }
+    return;
+}
+
+/* Hash octet p to octet w */
+void HASH(int sha,octet *p,octet *w)
+{
+    ehashit(sha,p,-1,NULL,w,0);
+}
+
+/* Calculate HMAC of m using key k. HMAC is tag of length olen */
+int HMAC(int sha,octet *m,octet *k,int olen,octet *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 hlen,b;
+    char h[128],k0[128];
+    octet H= {0,sizeof(h),h};
+    octet K0= {0,sizeof(k0),k0};
+
+    hlen=sha;
+    if (hlen>32) b=128;
+    else b=64;
+
+    if (olen<4 /*|| olen>hlen*/) return 0;
+
+    if (k->len > b) ehashit(sha,k,-1,NULL,&K0,0);
+    else            OCT_copy(&K0,k);
+
+    OCT_jbyte(&K0,0,b-K0.len);
+
+    OCT_xorbyte(&K0,0x36);
+
+    ehashit(sha,&K0,-1,m,&H,0);
+
+    OCT_xorbyte(&K0,0x6a);   /* 0x6a = 0x36 ^ 0x5c */
+    ehashit(sha,&K0,-1,&H,&H,olen);
+
+    OCT_empty(tag);
+
+    OCT_jbytes(tag,H.val,olen);
+
+    return 1;
+}
+
+void KDF2(int sha,octet *z,octet *p,int olen,octet *key)
+{
+    /* NOTE: the parameter olen is the length of the output k in bytes */
+    char h[64];
+    octet H= {0,sizeof(h),h};
+    int counter,cthreshold;
+    int hlen=sha;
+
+    OCT_empty(key);
+
+    cthreshold=ROUNDUP(olen,hlen);
+
+    for (counter=1; counter<=cthreshold; counter++)
+    {
+        ehashit(sha,z,counter,p,&H,0);
+        if (key->len+hlen>olen)  OCT_jbytes(key,H.val,olen%hlen);
+        else                     OCT_joctet(key,&H);
+    }
+
+}
+
+/* Password based Key Derivation Function */
+/* Input password p, salt s, and repeat count */
+/* Output key of length olen */
+void PBKDF2(int sha,octet *p,octet *s,int rep,int olen,octet *key)
+{
+    int i,j,len,d=ROUNDUP(olen,sha);
+    char f[64],u[64];
+    octet F= {0,sizeof(f),f};
+    octet U= {0,sizeof(u),u};
+    OCT_empty(key);
+
+    for (i=1; i<=d; i++)
+    {
+        len=s->len;
+        OCT_jint(s,i,4);
+
+        HMAC(sha,s,p,sha,&F);
+
+        s->len=len;
+        OCT_copy(&U,&F);
+        for (j=2; j<=rep; j++)
+        {
+            HMAC(sha,&U,p,sha,&U);
+            OCT_xor(&F,&U);
+        }
+
+        OCT_joctet(key,&F);
+    }
+
+    OCT_chop(key,NULL,olen);
+}
+
+/* AES encryption/decryption. Encrypt byte array M using key K and returns 
ciphertext */
+void AES_CBC_IV0_ENCRYPT(octet *k,octet *m,octet *c)
+{
+    /* 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 */
+    amcl_aes a;
+    int fin;
+    int i,j,ipt,opt;
+    char buff[16];
+    int padlen;
+
+    OCT_clear(c);
+    if (m->len==0) return;
+    AES_init(&a,CBC,k->len,k->val,NULL);
+
+    ipt=opt=0;
+    fin=0;
+    for(;;)
+    {
+        for (i=0; i<16; i++)
+        {
+            if (ipt<m->len) buff[i]=m->val[ipt++];
+            else
+            {
+                fin=1;
+                break;
+            }
+        }
+        if (fin) break;
+        AES_encrypt(&a,buff);
+        for (i=0; i<16; i++)
+            if (opt<c->max) c->val[opt++]=buff[i];
+    }
+
+    /* last block, filled up to i-th index */
+
+    padlen=16-i;
+    for (j=i; j<16; j++) buff[j]=padlen;
+    AES_encrypt(&a,buff);
+    for (i=0; i<16; i++)
+        if (opt<c->max) c->val[opt++]=buff[i];
+    AES_end(&a);
+    c->len=opt;
+}
+
+/* decrypts and returns TRUE if all consistent, else returns FALSE */
+int AES_CBC_IV0_DECRYPT(octet *k,octet *c,octet *m)
+{
+    /* padding is removed */
+    amcl_aes a;
+    int i,ipt,opt,ch;
+    char buff[16];
+    int fin,bad;
+    int padlen;
+    ipt=opt=0;
+
+    OCT_clear(m);
+    if (c->len==0) return 1;
+    ch=c->val[ipt++];
+
+    AES_init(&a,CBC,k->len,k->val,NULL);
+    fin=0;
+
+    for(;;)
+    {
+        for (i=0; i<16; i++)
+        {
+            buff[i]=ch;
+            if (ipt>=c->len)
+            {
+                fin=1;
+                break;
+            }
+            else ch=c->val[ipt++];
+        }
+        AES_decrypt(&a,buff);
+        if (fin) break;
+        for (i=0; i<16; i++)
+            if (opt<m->max) m->val[opt++]=buff[i];
+    }
+    AES_end(&a);
+    bad=0;
+    padlen=buff[15];
+    if (i!=15 || padlen<1 || padlen>16) bad=1;
+    if (padlen>=2 && padlen<=16)
+        for (i=16-padlen; i<16; i++) if (buff[i]!=padlen) bad=1;
+
+    if (!bad) for (i=0; i<16-padlen; i++)
+            if (opt<m->max) m->val[opt++]=buff[i];
+
+    m->len=opt;
+    if (bad) return 0;
+    return 1;
+}

Reply via email to