From ad63fcc85e6e314fb12afa20ffc9315f7bd3aa2a Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 14:39:47 -0500 Subject: [PATCH 01/12] randn4 was not visible causing compile error (not sure why the lines were commented out) --- source/curve/pairing/zzn4.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/curve/pairing/zzn4.h b/source/curve/pairing/zzn4.h index 8044ee9..3317b8d 100644 --- a/source/curve/pairing/zzn4.h +++ b/source/curve/pairing/zzn4.h @@ -1,4 +1,3 @@ - /*************************************************************************** * Copyright 2013 CertiVox IOM Ltd. * @@ -191,8 +190,8 @@ class ZZn4 #endif } }; -//#ifndef MR_NO_RAND -//extern ZZn4 randn4(void); -//#endif +#ifndef MR_NO_RAND +extern ZZn4 randn4(void); +#endif #endif From f0f3d746df40fc607dd527754ea12b9693a9dd43 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 14:48:56 -0500 Subject: [PATCH 02/12] Added serialization methods for the element since spill/restore serialize the precomp only. Serialization is useful when sending the elements over the network --- source/curve/pairing/pairing_3.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/pairing_3.h b/source/curve/pairing/pairing_3.h index ad102c1..71adca3 100644 --- a/source/curve/pairing/pairing_3.h +++ b/source/curve/pairing/pairing_3.h @@ -1,4 +1,3 @@ - /*************************************************************************** * Copyright 2013 CertiVox IOM Ltd. * @@ -131,6 +130,13 @@ class G1 } int spill(char *&); void restore(char *); + /* + * Added serialization methods for the element + * Spill/restore serialize the precomp only + */ + int serialize(char *&); + void deserialize(char *); + friend G1 operator-(const G1&); friend G1 operator+(const G1&,const G1&); friend BOOL operator==(const G1& x,const G1& y) @@ -164,6 +170,12 @@ class G2 } int spill(char *&); void restore(char *); + /* + * Added serialization methods for the element + * Spill/restore serialize the precomp only + */ + int serialize(char *&); + void deserialize(char *); friend G2 operator-(const G2&); friend G2 operator+(const G2&,const G2&); @@ -196,6 +208,13 @@ class GT } int spill(char *&); void restore(char *); + /* + * Added serialization methods for the element + * Spill/restore serialize the precomp only + */ + int serialize(char *&); + void deserialize(char *); + friend GT operator*(const GT&,const GT&); friend GT operator/(const GT&,const GT&); friend BOOL operator==(const GT& x,const GT& y) From 45dbc531c84d2b691ecbba59ab0cad8a9ac92877 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 14:54:37 -0500 Subject: [PATCH 03/12] Implemented serialization methods for the element --- source/curve/pairing/bls_pair.cpp | 314 +++++++++++++++++++++++++++++- 1 file changed, 313 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/bls_pair.cpp b/source/curve/pairing/bls_pair.cpp index ffdae80..9836fa3 100644 --- a/source/curve/pairing/bls_pair.cpp +++ b/source/curve/pairing/bls_pair.cpp @@ -1,4 +1,3 @@ - /*************************************************************************** * Copyright 2013 CertiVox IOM Ltd. * @@ -1353,6 +1352,188 @@ void GT::restore(char *bytes) delete [] bytes; } +/* + * Serialization method for the points + * + */ +int GT::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=24*bytes_per_big; + ZZn8 a,b,c; + ZZn4 f,s; + ZZn2 p,q; + Big x,y; + + bytes=new char[len]; + + g.get(a,b,c); + a.get(f,s); + f.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(f,s); + f.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + c.get(f,s); + f.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(p,q); + p.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + q.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * Deserialization method for the points + * This will reset the element precomp + * + */ +void GT::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=24*bytes_per_big; + ZZn8 a,b,c; + ZZn4 f,s; + ZZn2 p,q; + Big x,y; + if (etable!=NULL){ + delete [] etable; + etable = NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + f.set(p,q); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + s.set(p,q); + a.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + f.set(p,q); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + s.set(p,q); + b.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + f.set(p,q); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + p.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + q.set(x,y); + s.set(p,q); + c.set(f,s); + + g.set(a,b,c); + + delete [] bytes; +} + G1 operator+(const G1& x,const G1& y) { G1 z=x; @@ -1418,6 +1599,52 @@ void G1::restore(char *bytes) delete [] bytes; } +/* + * Serialization method for the point x,y + * + */ +int G1::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} +/* + * Deserialization method for the point x,y + * This will reset the element to point x,y + * + */ +void G1::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + g.set(x,y); + + delete [] bytes; +} + + G2 operator+(const G2& x,const G2& y) { G2 z=x; @@ -1524,6 +1751,91 @@ void G2::restore(char *bytes) delete [] bytes; } +/* + * Serialization method for the points + * + */ +int G2::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=8*bytes_per_big; + ZZn4 a,b; + ZZn2 f,s; + Big x,y; + + bytes=new char[len]; + + g.get(a,b); + a.get(f,s); + f.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(f,s); + f.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * Deserialization method for the points + * This will reset the element precomp + * + */ +void G2::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=8*bytes_per_big; + ZZn4 a,b; + ZZn2 f,s; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y); + a.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y); + b.set(f,s); + g.set(a,b); + + delete [] bytes; +} // Fast group membership check for GT // check if r is of order q From 99656e546b4dc97c58a3652e123b255926ff0724 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:00:25 -0500 Subject: [PATCH 04/12] Implemented serialization methods for the element --- source/curve/pairing/bn_pair.cpp | 223 ++++++++++++++++++++++++++++++- 1 file changed, 221 insertions(+), 2 deletions(-) diff --git a/source/curve/pairing/bn_pair.cpp b/source/curve/pairing/bn_pair.cpp index b5a0ff1..02bffca 100644 --- a/source/curve/pairing/bn_pair.cpp +++ b/source/curve/pairing/bn_pair.cpp @@ -1,7 +1,8 @@ /*************************************************************************** - * -Copyright 2013 CertiVox IOM Ltd. * +This file has been modified by Raytheon BBN Technologies - January 2013. * + * +Copyright 2013 CertiVox IOM Ltd. * This file is part of CertiVox MIRACL Crypto SDK. * * @@ -1234,6 +1235,59 @@ int GT::spill(char *& bytes) return len; } +/* + * jkhoury@bbn.com + * Serialization method for the points + * + */ +int GT::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=12*bytes_per_big; + ZZn4 a,b,c; + ZZn2 f,s; + Big x,y; + + bytes=new char[len]; + + g.get(a,b,c); + a.get(f,s); + f.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(f,s); + f.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + c.get(f,s); + f.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} + // // restore precomputation for GT from byte array // @@ -1289,6 +1343,62 @@ void GT::restore(char *bytes) delete [] bytes; } +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ +void GT::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=12*bytes_per_big; + ZZn4 a,b,c; + ZZn2 f,s; + Big x,y; + if (etable!=NULL){ + delete [] etable; + etable = NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y); + a.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y); + b.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y); + c.set(f,s); + g.set(a,b,c); + + delete [] bytes; +} + // // spill precomputation on G1 to byte array // @@ -1340,6 +1450,53 @@ void G1::restore(char *bytes) delete [] bytes; } +/* + * jkhoury@bbn.com + * Serialization method for the point x,y + * + */ +int G1::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the point x,y + * This will reset the element to point x,y + * + */ +void G1::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + g.set(x,y); + + delete [] bytes; +} + G1 operator+(const G1& x,const G1& y) { G1 z=x; @@ -1392,6 +1549,35 @@ int G2::spill(char *& bytes) // restore precomputation for G2 from byte array // +/* + * jkhoury@bbn.com + * Serialization method for the 2 points + * + */ +int G2::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=4*bytes_per_big; + Big x,y; + ZZn2 a,b; + + bytes=new char[len]; + + g.get(a,b); + a.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} + void G2::restore(char *bytes) { int i,j,n=(1<nib-1); + int len=4*bytes_per_big; + ZZn2 a,b; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + a.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + b.set(x,y); + g.set(a,b); + + delete [] bytes; +} + G2 operator+(const G2& x,const G2& y) { G2 z=x; From 45ab085ceebf19303ce5c88bdb00edd32a1a8401 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:01:11 -0500 Subject: [PATCH 05/12] added modified statement --- source/curve/pairing/bls_pair.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/bls_pair.cpp b/source/curve/pairing/bls_pair.cpp index 9836fa3..1908cdd 100644 --- a/source/curve/pairing/bls_pair.cpp +++ b/source/curve/pairing/bls_pair.cpp @@ -1,5 +1,6 @@ /*************************************************************************** - * +This file has been modified by Raytheon BBN Technologies - January 2013. * + Copyright 2013 CertiVox IOM Ltd. * * This file is part of CertiVox MIRACL Crypto SDK. * From 44ee0b85a308846a89987c1f6edcc60a117ab0fe Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:04:53 -0500 Subject: [PATCH 06/12] Implemented serialization methods for the element --- source/curve/pairing/cp_pair.cpp | 158 ++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/cp_pair.cpp b/source/curve/pairing/cp_pair.cpp index 045bb4a..e63f52b 100644 --- a/source/curve/pairing/cp_pair.cpp +++ b/source/curve/pairing/cp_pair.cpp @@ -1,5 +1,7 @@ /* - * + +This file has been modified by Raytheon BBN Technologies - January 2013. + * cp_pair.cpp * * Cocks-Pinch curve, Tate pairing embedding degree 2, ideal for security level AES-80 @@ -751,6 +753,53 @@ int GT::spill(char *& bytes) // restore precomputation for GT from byte array // +/* + * jkhoury@bbn.com + * Serialization method for the points + * + */ +int GT::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ +void GT::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + if (etable!=NULL){ + delete [] etable; + etable = NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + g.set(x,y); + + delete [] bytes; +} + void GT::restore(char *bytes) { int i,j,n=(1<nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the point x,y + * This will reset the element to point x,y + * + */ +void G1::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + g.set(x,y); + + delete [] bytes; +} + G2 operator+(const G2& x,const G2& y) { G2 z=x; @@ -912,6 +1008,66 @@ void G2::restore(char *bytes) delete [] bytes; } +// +// jkhoury@bbn.com +// serialize element to byte array +// + +int G2::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + //x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} + +// jkhoury@bbn.com +// restore element from byte array +// reset the precomp +// + +void G2::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y,B; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + + B=getB(); + B=-B; + ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move to twist + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + + g.set(x,y); + + + B=-B; + ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move back + delete [] bytes; +} + BOOL PFC::member(const GT& z) { ZZn2 r=z.g; From 495775b959f738f2d06561e1a71dcde6dc8754eb Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:06:27 -0500 Subject: [PATCH 07/12] Implemented serialization methods for the element --- source/curve/pairing/cp_pair.cpp | 906 +++++++++++++++++++++---------- 1 file changed, 606 insertions(+), 300 deletions(-) diff --git a/source/curve/pairing/cp_pair.cpp b/source/curve/pairing/cp_pair.cpp index e63f52b..490022b 100644 --- a/source/curve/pairing/cp_pair.cpp +++ b/source/curve/pairing/cp_pair.cpp @@ -1,10 +1,51 @@ -/* - -This file has been modified by Raytheon BBN Technologies - January 2013. - * cp_pair.cpp +/*************************************************************************** +This file has been modified by Raytheon BBN Technologies - January 2013. * + * +Copyright 2013 CertiVox IOM Ltd. * + * +This file is part of CertiVox MIRACL Crypto SDK. * + * +The CertiVox MIRACL Crypto SDK provides developers with an * +extensive and efficient set of cryptographic functions. * +For further information about its features and functionalities please * +refer to http://www.certivox.com * + * +* The CertiVox MIRACL Crypto SDK is free software: you can * + redistribute it and/or modify it under the terms of the * + GNU Affero General Public License as published by the * + Free Software Foundation, either version 3 of the License, * + or (at your option) any later version. * + * +* The CertiVox MIRACL Crypto SDK is distributed in the hope * + that it will be useful, but WITHOUT ANY WARRANTY; without even the * + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + See the GNU Affero General Public License for more details. * + * +* You should have received a copy of the GNU Affero General Public * + License along with CertiVox MIRACL Crypto SDK. * + If not, see . * + * +You can be released from the requirements of the license by purchasing * +a commercial license. Buying such a license is mandatory as soon as you * +develop commercial activities involving the CertiVox MIRACL Crypto SDK * +without disclosing the source code of your own applications, or shipping * +the CertiVox MIRACL Crypto SDK with a closed source product. * + * +***************************************************************************/ +/* * - * Cocks-Pinch curve, Tate pairing embedding degree 2, ideal for security level AES-80 + * mnt_pair.cpp + * + * MNT curve, ate pairing embedding degree 6, ideal for security level AES-80 + * + * + * Irreducible binomial MUST be of the form x^6+2. This excludes many of the curves + * found using the mnt utility! + * NOTE: This version uses a "compositum". That is the ZZn6 class is a cubic tower over ZZn2, but can + * also be considered as a quadratic tower over ZZn3. The routine shuffle converts from one form to the other. + * The former is fastest for ZZn6 arithmetic, the latter form is required for handling the second parameter + * to the pairing, which is on the quadratic twist E(Fp3) * * Provides high level interface to pairing functions * @@ -12,21 +53,20 @@ This file has been modified by Raytheon BBN Technologies - January 2013. * * This is calculated on a Pairing Friendly Curve (PFC), which must first be defined. * - * G1 is a point over the base field, G2 is a point on the quadratic twist - * GT is a finite field point over the 2nd extension, where 2 is the embedding degree. + * G1 is a point over the base field, and G2 is a point over an extension field of degree 3 + * GT is a finite field point over the 6-th extension, where 6 is the embedding degree. * */ -#define MR_PAIRING_CP +#define MR_PAIRING_MNT #include "pairing_3.h" -// Cocks-Pinch curve parameters, A,B and n, where p=3 mod 4 // AES_SECURITY=80 bit curve -// Curve E:y^2=x^3-3x+B, #E=COF*order, modulus p - -static char MODtext[]="8D5006492B424C09D2FEBE717EE382A57EBE3A352FC383E1AC79F21DDB43706CFB192333A7E9CF644636332E83D90A1E56EFBAE8715AA07883483F8267E80ED3"; -static char Btext[]="609993837367998001C95B87A6BA872135E26906DB4C192D6E038486177A3EDF6C50B9BB20DF881F2BD05842F598F3E037B362DBF89F0A62E5871D41D951BF8E"; -static char COFtext[]="11AA00C9256849813A5FD7CE2FDC7054AFD7809E7F7FD948C4B9C1C1E76FFEFF4ECAB83C950112DECB41D6EDA"; +// MNT curve parameters, x,A,B +// Thanks to Drew Sutherland for providing the MNT curve +// irreducible poly is x^6+2 +static char param[]="-D285DA0CFEF02F06F812"; +static char curveB[]="77479D33943B5B1F590B54258B72F316B3261D45"; void read_only_error(void) { @@ -34,28 +74,46 @@ void read_only_error(void) exit(0); } -// Using SHA256 as basic hash algorithm +void set_frobenius_constant(ZZn2 &X) +{ + Big p=get_modulus(); + switch (get_mip()->pmod8) + { + case 5: + X.set((Big)0,(Big)1); // = (sqrt(-2)^(p-1)/2 + break; + case 3: // = (1+sqrt(-1))^(p-1)/2 + X.set((Big)1,(Big)1); + break; + case 7: + X.set((Big)2,(Big)1); // = (2+sqrt(-1))^(p-1)/2 + default: break; + } + X=pow(X,(p-1)/3); +} + +// Using SHA as basic hash algorithm // // Hash function // -#define HASH_LEN 32 +#define HASH_LEN 20 Big H1(char *string) { // Hash a zero-terminated string to a number < modulus Big h,p; char s[HASH_LEN]; int i,j; - sha256 sh; + sha sh; - shs256_init(&sh); + shs_init(&sh); for (i=0;;i++) { if (string[i]==0) break; - shs256_process(&sh,string[i]); + shs_process(&sh,string[i]); } - shs256_hash(&sh,s); + shs_hash(&sh,s); p=get_modulus(); h=1; j=0; i=1; forever @@ -71,56 +129,68 @@ Big H1(char *string) void PFC::start_hash(void) { - shs256_init(&SH); + shs_init(&SH); } Big PFC::finish_hash_to_group(void) { Big hash; char s[HASH_LEN]; - shs256_hash(&SH,s); + shs_hash(&SH,s); hash=from_binary(HASH_LEN,s); return hash%(*ord); } void PFC::add_to_hash(const GT& x) -{ // compress it and add - ZZn2 u=x.g; - Big a; - int m; +{ + ZZn6 u=x.g; + ZZn2 v; + ZZn l,h; + Big a,xx[2]; + int i,j,m; - u.get(a); - - while (a>0) + u.get(v); + v.get(l,h); + xx[0]=l; xx[1]=h; + + for (i=0;i<2;i++) { - m=a%256; - shs256_process(&SH,m); - a/=256; + a=xx[i]; + while (a>0) + { + m=a%256; + shs_process(&SH,m); + a/=256; + } } + } -void PFC::add_to_hash(const G1& x) +void PFC::add_to_hash(const G2& x) { - Big a,X,Y; + ZZn3 X,Y; + ECn3 v=x.g; + Big a; + ZZn xx[6]; + int i,m; - x.g.get(X,Y); - a=X; - while (a>0) - { - m=a%256; - shs256_process(&SH,m); - a/=256; - } - a=Y; - while (a>0) + + v.get(X,Y); + X.get(xx[0],xx[1],xx[2]); + Y.get(xx[3],xx[4],xx[5]); + for (i=0;i<6;i++) { - m=a%256; - shs256_process(&SH,m); - a/=256; + a=(Big)xx[i]; + while (a>0) + { + m=a%256; + shs_process(&SH,m); + a/=256; + } } } -void PFC::add_to_hash(const G2& x) +void PFC::add_to_hash(const G1& x) { Big a,X,Y; int i,m; @@ -129,14 +199,14 @@ void PFC::add_to_hash(const G2& x) while (a>0) { m=a%256; - shs256_process(&SH,m); + shs_process(&SH,m); a/=256; } a=Y; while (a>0) { m=a%256; - shs256_process(&SH,m); + shs_process(&SH,m); a/=256; } } @@ -148,28 +218,36 @@ void PFC::add_to_hash(const Big& x) while (a>0) { m=a%256; - shs256_process(&SH,m); + shs_process(&SH,m); a/=256; } } -Big H2(ZZn2 y) -{ // Hash and compress an Fp2 to a big number - sha256 sh; - Big a,h; +Big H2(ZZn6 y) +{ // Hash and compress an Fp6 to a big number + sha sh; + ZZn u,v,w; + ZZn2 x; + Big a,h,xx[2]; char s[HASH_LEN]; - int m; + int i,j,m; - shs256_init(&sh); - y.get(a); + shs_init(&sh); + y.get(x); + x.get(u,v); + xx[0]=u; xx[1]=v; - while (a>0) + for (i=0;i<2;i++) { - m=a%256; - shs256_process(&sh,m); - a/=256; + a=xx[i]; + while (a>0) + { + m=a%256; + shs_process(&sh,m); + a/=256; + } } - shs256_hash(&sh,s); + shs_hash(&sh,s); h=from_binary(HASH_LEN,s); return h; } @@ -209,12 +287,57 @@ void extract(ECn& A,ZZn& x,ZZn& y) y=(A.get_point())->Y; } -void extractZ(ECn& A,ZZn& z) -{ - big t; - t=(A.get_point())->Z; - if (A.get_status()!=MR_EPOINT_GENERAL) z=1; - else z=t; + +ZZn6 shuffle(const ZZn3 &first, const ZZn3 &second) +{ // shuffle from a pair ZZn3's to three ZZn2's, as required by ZZn6 + ZZn6 w; + ZZn x0,x1,x2,x3,x4,x5; + ZZn2 t0,t1,t2; + first.get(x0,x2,x4); + second.get(x1,x3,x5); + t0.set(x0,x3); + t1.set(x1,x4); + t2.set(x2,x5); + w.set(t0,t1,t2); + return w; +} + +void unshuffle(ZZn6 &S,ZZn3 &first,ZZn3 &second) +{ // unshuffle a ZZn6 into two ZZn3's + ZZn x0,x1,x2,x3,x4,x5; + ZZn2 t0,t1,t2; + S.get(t0,t1,t2); + t0.get(x0,x3); + t1.get(x1,x4); + t2.get(x2,x5); + first.set(x0,x2,x4); + second.set(x1,x3,x5); +} + +// Calculate q*P. P(X,Y) -> P(X^p,Y^p)) + +void q_power_frobenius(ECn3 &S,ZZn2& X) +{ + ZZn6 X1,X2,Y1,Y2; + ZZn3 Sx,Sy,T; + + int qnr=get_mip()->cnr; + + S.get(Sx,Sy); + + // untwist + Sx=Sx/qnr; + Sy=tx(Sy); + Sy=Sy/(qnr*qnr); + + X1=shuffle(Sx,(ZZn3)0); Y1=shuffle((ZZn3)0,Sy); + X1.powq(X); Y1.powq(X); + unshuffle(X1,Sx,T); unshuffle(Y1,T,Sy); + + // twist + Sx=qnr*Sx; + Sy=txd(Sy*qnr*qnr); + S.set(Sx,Sy); } // @@ -224,34 +347,33 @@ void extractZ(ECn& A,ZZn& z) // Now evaluate at Q -> return (Qy-y)-slope.(Qx-x) // -ZZn2 line(ECn& A,ECn& C,ECn& B,int type,ZZn& slope,ZZn& ex1,ZZn& ex2,ZZn& Px,ZZn& Py) -{ - ZZn2 w; - ZZn x,y,z3; - - extractZ(C,z3); - if (type==MR_ADD) - { - extract(B,x,y); - w.set(slope*(x+Px)-z3*y,z3*Py); - } - if (type==MR_DOUBLE) - { - extract(A,x,y); - w.set(-(slope*ex2)*Px-slope*x+ex1,-(z3*ex2)*Py); - } - -/* - extract(A,x,y,z); - x*=z; t=z; z*=z; z*=t; // 9 ZZn muls - n*=z; n+=x; n*=slope; - d*=z; w.set(-y,d); - extractZ(C,z3); - - w*=z3; w+=n; -*/ - -// w.set(Px*z*z*z*slope+slope*x*z-y*z3,Py*z*z*z*z3); +ZZn6 line(ECn3& A,ECn3& C,ECn3& B,int type,ZZn3& slope,ZZn3& ex1,ZZn3& ex2,ZZn& Px,ZZn& Py) +{ + ZZn6 w; + ZZn3 d; + ZZn3 x,y; +#ifdef MR_ECN3_PROJECTIVE + ZZn3 z,z3,t; + C.getZ(z3); + d.set1(Py); + + if (type==MR_ADD) + { // exploit that B is in affine + ZZn3 x2,y2; + B.get(x2,y2); + y2*=z3; d*=z3; + w=shuffle(y2-slope*(Px+x2),d); + } + if (type==MR_DOUBLE) + { // use extra information from point doubling + A.get(x,y,z); + w=shuffle(ex1-slope*(Px*ex2+x),d*z3*ex2); + } +#else + A.get(x,y); + d.set1(Py); + w=shuffle(y-slope*(Px+x),d); +#endif return w; } @@ -260,29 +382,26 @@ ZZn2 line(ECn& A,ECn& C,ECn& B,int type,ZZn& slope,ZZn& ex1,ZZn& ex2,ZZn& Px,ZZn // Return line function value // -ZZn2 g(ECn& A,ECn& B,ZZn& Px,ZZn& Py) +ZZn6 g(ECn3& A,ECn3& B,ZZn& Px,ZZn& Py) { - int type; - ZZn lam,extra1,extra2; - ZZn2 u; - ECn P=A; - big ptr,ex1,ex2; + BOOL type; + ZZn3 lam,ex1,ex2; + ECn3 Q=A; - type=A.add(B,&ptr,&ex1,&ex2); - if (!type) return (ZZn2)1; - lam=ptr; - extra1=ex1; - extra2=ex2; - - return line(P,A,B,type,lam,extra1,extra2,Px,Py); +// Evaluate line from A to A+B + type=A.add(B,lam,&ex1,&ex2); + + return line(Q,A,B,type,lam,ex1,ex2,Px,Py); } // if multiples of G2 can be precalculated, its a lot faster! -ZZn2 gp(ZZn* ptable,int &j,ZZn& Px,ZZn& Py) +ZZn6 gp(ZZn3* ptable,int &j,ZZn& Px,ZZn& Py) { - ZZn2 w; - w.set(ptable[j]*Px+ptable[j+1],Py); + ZZn6 w; + ZZn3 d; + d.set1(Py); + w=shuffle(ptable[j]*Px+ptable[j+1],d); j+=2; return w; } @@ -293,17 +412,25 @@ ZZn2 gp(ZZn* ptable,int &j,ZZn& Px,ZZn& Py) int PFC::spill(G2& w,char *& bytes) { - int i,j,n=2*(bits(*ord-1)-2+ham(*ord)); + int i,j,len,m; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - int len=n*bytes_per_big; - Big x; + + ZZn a,b,c; + Big X=*x; if (w.ptable==NULL) return 0; + m=2*(bits(X)-2+ham(X)); + len=m*3*bytes_per_big; + bytes=new char[len]; - for (i=j=0;inib-1); - int len=n*bytes_per_big; - Big x; - + + ZZn a,b,c; + Big X=*x; if (w.ptable!=NULL) return; - w.ptable=new ZZn[n]; - for (i=j=0;icoord=MR_AFFINE; + len=2*(nb-2+ham(X)); + w.ptable=new ZZn3[len]; + get_mip()->coord=MR_AFFINE; // switch to affine for (i=nb-2;i>=0;i--) { Q=A; // Evaluate line from A to A+B - A.add(A,&ptr); - lam=ptr; - extract(Q,x,y); - w.ptable[j++]=lam; w.ptable[j++]=lam*x-y; + A.add(A,lam,NULL,NULL); + Q.get(x1,y1); + w.ptable[j++]=-lam; w.ptable[j++]=y1-lam*x1; - if (bit(iters,i)==1) + if (bit(X,i)==1) { Q=A; - A.add(B,&ptr); - lam=ptr; - extract(Q,x,y); - w.ptable[j++]=lam; w.ptable[j++]=lam*x-y; + type=A.add(B,lam,NULL,NULL); + Q.get(x1,y1); + w.ptable[j++]=-lam; w.ptable[j++]=y1-lam*x1; } } - get_mip()->coord=MR_PROJECTIVE; + get_mip()->coord=MR_PROJECTIVE; return len; } @@ -382,28 +513,36 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) GT z; ZZn *Px,*Py; int i,j,*k,nb; - ECn *Q,*A; + ECn3 *Q,*A; ECn P; - ZZn2 res; - Big iters=*ord-1; + ZZn6 res; + Big X=*x; Px=new ZZn[n]; Py=new ZZn[n]; - Q=new ECn[n]; - A=new ECn[n]; + Q=new ECn3[n]; + A=new ECn3[n]; k=new int[n]; - nb=bits(iters); + nb=bits(X); res=1; for (j=0;jg; normalise(P); Q[j]=QQ[j]->g; normalise(Q[j]); + P=PP[j]->g; normalise(P); Q[j]=QQ[j]->g; extract(P,Px[j],Py[j]); + Px[j]+=Px[j]; + Py[j]+=Py[j]; } - for (j=0;j=0;i--) { @@ -415,7 +554,7 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) else res*=gp(QQ[j]->ptable,k[j],Px[j],Py[j]); } - if (bit(iters,i)==1) + if (bit(X,i)==1) for (j=0;jptable==NULL) @@ -437,35 +576,41 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) } // -// Tate Pairing G1 x G1 -> GT +// R-ate Pairing G2 x G1 -> GT // -// P and Q are points of order q in G1. +// P is a point of order q in G1. Q(x,y) is a point of order q in G2. +// Note that Q is a point on the sextic twist of the curve over Fp^2, P(x,y) is a point on the +// curve over the base field Fp // GT PFC::miller_loop(const G2& QQ,const G1& PP) { GT z; int i,j,n,nb,nbw,nzs; - ECn A,Q; + ECn3 A,Q; ECn P; ZZn Px,Py; BOOL precomp; - ZZn2 res; - Big iters=*ord-1; // can omit last addition + ZZn6 res; + Big X=*x; P=PP.g; Q=QQ.g; +#ifdef MR_ECN3_PROJECTIVE + Q.norm(); +#endif precomp=FALSE; if (QQ.ptable!=NULL) precomp=TRUE; normalise(P); - normalise(Q); extract(P,Px,Py); - //Px=-Px; + + Px+=Px; // because x^6+2 is irreducible.. simplifies line function calculation + Py+=Py; res=1; A=Q; // reset A - nb=bits(iters); - + nb=bits(X); + res.mark_as_miller(); j=0; for (i=nb-2;i>=0;i--) @@ -474,7 +619,7 @@ GT PFC::miller_loop(const G2& QQ,const G1& PP) if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,A,Px,Py); - if (bit(iters,i)==1) + if (bit(X,i)==1) { if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,Q,Px,Py); @@ -488,11 +633,28 @@ GT PFC::miller_loop(const G2& QQ,const G1& PP) GT PFC::final_exp(const GT& z) { GT y; - ZZn2 res; + ZZn6 w,res; + Big X=*x; res=z.g; - res=conj(res)/res; - res=pow(res,(*mod+1)/(*ord)); // raise to power of (p^2-1)/q + + w=res; + w.powq(*frob); + res*=w; // ^(p+1) + + w=res; + w.powq(*frob); w.powq(*frob); w.powq(*frob); + res=w/res; // ^(p^3-1) + +// exploit the clever "trick" for a half-length exponentiation! + + res.mark_as_unitary(); + + w=res; + res.powq(*frob); // res*=res; // res=pow(res,CF); + + if (X<0) res/=powu(w,-X); + else res*=powu(w,X); y.g=res; @@ -502,14 +664,12 @@ GT PFC::final_exp(const GT& z) PFC::PFC(int s, csprng *rng) { int mod_bits,words; - if (s!=80) { cout << "No suitable curve available" << endl; exit(0); } - - mod_bits=512; + mod_bits=2*s; if (mod_bits%MIRACL==0) words=(mod_bits/MIRACL); @@ -524,35 +684,43 @@ PFC::PFC(int s, csprng *rng) #endif B=new Big; + x=new Big; mod=new Big; ord=new Big; cof=new Big; npoints=new Big; trace=new Big; + frob=new ZZn2; - *B=Btext; - - *cof=COFtext; - *ord=pow((Big)2,159)+pow((Big)2,17)+1; - *npoints=*cof*(*ord); - + *B=curveB; S=s; - *mod=MODtext; - *trace=*mod+1-*npoints; - + *x=param; + Big X=*x; + + *mod=X*X+1; + *npoints=X*X-X+1; + *trace=X+1; + *cof=X*X+X+1; + *ord=*npoints; ecurve(-3,*B,*mod,MR_PROJECTIVE); + set_frobenius_constant(*frob); + Big sru=pow((ZZn)-2,(*mod-1)/6); // x^6+2 is irreducible + set_zzn3(-2,sru); + mip->TWIST=MR_QUADRATIC; // twisted curve E'(ZZn3) - RNG=rng; + RNG = rng; } PFC::~PFC() { delete B; + delete x; delete mod; delete ord; delete cof; delete npoints; delete trace; + delete frob; mirexit(); } @@ -561,11 +729,10 @@ G1 PFC::mult(const G1& w,const Big& k) G1 z; if (w.mtable!=NULL) { // we have precomputed values - Big e=k; if (k<0) e=-e; - int i,j,t=w.mtbits; // MR_ROUNDUP(2*S,WINDOW_SIZE); + int i,j,t=w.mtbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.mtable[j]; for (i=t-2;i>=0;i--) @@ -584,16 +751,18 @@ G1 PFC::mult(const G1& w,const Big& k) return z; } +// GLV + Galbraith-Scott + G2 PFC::mult(const G2& w,const Big& k) { G2 z; + Big X=*x; if (w.mtable!=NULL) { // we have precomputed values - Big e=k; if (k<0) e=-e; - int i,j,t=w.mtbits; // MR_ROUNDUP(2*S,WINDOW_SIZE); + int i,j,t=w.mtbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.mtable[j]; for (i=t-2;i>=0;i--) @@ -606,20 +775,25 @@ G2 PFC::mult(const G2& w,const Big& k) } else { - z.g=w.g; - z.g*=k; + ECn3 v=w.g; + q_power_frobenius(v,*frob); + z.g=mul(v,k/X,w.g,k%X); } return z; } +// GLV method + Galbraith-Scott idea + GT PFC::power(const GT& w,const Big& k) { GT z; - Big e=k; - if (k<0) e=-e; + Big X=*x; if (w.etable!=NULL) { // precomputation is available - int i,j,t=w.etbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); + Big e=k; + if (k<0) e=-e; + + int i,j,t=w.etbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.etable[j]; for (i=t-2;i>=0;i--) @@ -628,16 +802,56 @@ GT PFC::power(const GT& w,const Big& k) z.g*=z.g; if (j>0) z.g*=w.etable[j]; } + if (k<0) z.g=inverse(z.g); } else { - z.g=powu(w.g,e); + ZZn6 y=w.g; + y.powq(*frob); + z.g=powu(y,k/X,w.g,k%X); } - if (k<0) z.g=conj(z.g); return z; } -// random group member +// Use Scott et al. idea - http://eprint.iacr.org/2008/530.pdf +// Map to point of correct order + +void map(ECn3 &S,Big x, ZZn2& X) +{ // S=Phi(2xP)+phi^2(2xP) + ZZn6 X1,X2,Y1,Y2; + ZZn3 Sx,Sy,T; + ECn3 S2; + int qnr=get_mip()->cnr; + + S*=x; S+=S; // hard work done here + + S.get(Sx,Sy); + + // untwist + Sx=Sx/qnr; + Sy=tx(Sy); + Sy=Sy/(qnr*qnr); + + X1=shuffle(Sx,(ZZn3)0); Y1=shuffle((ZZn3)0,Sy); + X1.powq(X); Y1.powq(X); + X2=X1; Y2=Y1; + X2.powq(X); Y2.powq(X); + unshuffle(X1,Sx,T); unshuffle(Y1,T,Sy); + + // twist + Sx=qnr*Sx; + Sy=txd(Sy*qnr*qnr); + S.set(Sx,Sy); + unshuffle(X2,Sx,T); unshuffle(Y2,T,Sy); + + //twist (again, like we did last summer...) + Sx=qnr*Sx; + Sy=txd(Sy*qnr*qnr); + S2.set(Sx,Sy); + S+=S2; +} + +// random group element void PFC::random(Big& w) { @@ -649,51 +863,61 @@ void PFC::random(Big& w) void PFC::rankey(Big& k) { - if (RNG==NULL) k=rand(S,2); - else k=strong_rand(RNG,S,2); -} - -// Can be done deterministicly - -void PFC::hash_and_map(G1& w,char *ID) -{ - Big x0=H1(ID); - while (!w.g.set(x0,x0)) x0+=1; - w.g*=*cof; + if (RNG==NULL) k=rand(S,2); + else k=strong_rand(RNG,S,2); } void PFC::hash_and_map(G2& w,char *ID) { + int i; + ZZn3 XX; + Big X=*x; + Big x0=H1(ID); - *B=-(*B); - ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move to twist - while (!w.g.set(x0,x0)) x0+=1; - w.g*=(*mod+1+*trace)/(*ord); - *B=-(*B); - ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move back + forever + { + x0+=1; + XX.set2((ZZn)x0); + if (!w.g.set(XX)) continue; + + break; + } + map(w.g,X,*frob); } -void PFC::random(G1& w) +void PFC::random(G2& w) { + int i; + ZZn3 XX; + Big X=*x; Big x0; - if (RNG==NULL) x0=rand(*mod); + + if (RNG==NULL) x0=rand(*mod); else x0=strong_rand(RNG,*mod); - while (!w.g.set(x0,x0)) x0+=1; - w.g*=*cof; + forever + { + x0+=1; + XX.set2((ZZn)x0); + if (!w.g.set(XX)) continue; + + break; + } + map(w.g,X,*frob); } -void PFC::random(G2& w) +void PFC::hash_and_map(G1& w,char *ID) +{ + Big x0=H1(ID); + while (!w.g.set(x0,x0)) x0+=1; +} + +void PFC::random(G1& w) { Big x0; if (RNG==NULL) x0=rand(*mod); else x0=strong_rand(RNG,*mod); - *B=-(*B); - ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move to twist - while (!w.g.set(x0,x0)) x0+=1; - w.g*=(*mod+1+*trace)/(*ord); - *B=-(*B); - ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move back + while (!w.g.set(x0,x0)) x0+=1; } Big PFC::hash_to_aes_key(const GT& w) @@ -718,7 +942,7 @@ GT operator*(const GT& x,const GT& y) GT operator/(const GT& x,const GT& y) { GT z=x; - z.g*=conj(y.g); // elements in GT are unitary + z.g/=y.g; return z; } @@ -730,7 +954,8 @@ int GT::spill(char *& bytes) { int i,j,n=(1<nib-1); - int len=n*2*bytes_per_big; + int len=n*6*bytes_per_big; + ZZn2 a,b,c; Big x,y; if (etable==NULL) return 0; @@ -738,7 +963,18 @@ int GT::spill(char *& bytes) bytes=new char[len]; for (i=j=0;inib-1); - int len=2*bytes_per_big; + int len=6*bytes_per_big; + ZZn2 a,b,c; Big x,y; bytes=new char[len]; - g.get(x,y); + g.get(a,b,c); + a.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + c.get(x,y); to_binary(x,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary(y,bytes_per_big,&bytes[j],TRUE); @@ -785,7 +1029,8 @@ void GT::deserialize(char *bytes) { int j=0; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - int len=2*bytes_per_big; + int len=6*bytes_per_big; + ZZn2 a,b,c; Big x,y; if (etable!=NULL){ delete [] etable; @@ -795,31 +1040,60 @@ void GT::deserialize(char *bytes) j+=bytes_per_big; y=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - g.set(x,y); + a.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c.set(x,y); + + g.set(a,b,c); delete [] bytes; } +// +// restore precomputation for GT from byte array +// + void GT::restore(char *bytes) { int i,j,n=(1<nib-1); - int len=n*2*bytes_per_big; + int len=n*6*bytes_per_big; + ZZn2 a,b,c; Big x,y; if (etable!=NULL) return; - etable=new ZZn2[1<nib-1); - int len=n*2*bytes_per_big; - Big x,y; + int len=n*6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; if (mtable==NULL) return 0; bytes=new char[len]; - for (i=j=0;inib-1); - int len=n*2*bytes_per_big; - Big x,y,B; + int len=n*6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; if (mtable!=NULL) return; - mtable=new ECn[1<nib-1); - int len=2*bytes_per_big; - Big x,y; + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; - bytes=new char[len]; + bytes=new char[len]; g.get(x,y); - to_binary(x,bytes_per_big,&bytes[j],TRUE); - //x=from_binary(bytes_per_big,&bytes[j]); + x.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; - to_binary(y,bytes_per_big,&bytes[j],TRUE); + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + y.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; return len; } - -// jkhoury@bbn.com -// restore element from byte array -// reset the precomp -// - +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ void G2::deserialize(char *bytes) { int j=0; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - int len=2*bytes_per_big; - Big x,y,B; + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; //reset precomp if (mtable!=NULL){ delete [] mtable; mtable=NULL; } - - B=getB(); - B=-B; - ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move to twist - - x=from_binary(bytes_per_big,&bytes[j]); + a=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - y=from_binary(bytes_per_big,&bytes[j]); + b=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + x.set(a,b,c); + a=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y.set(a,b,c); g.set(x,y); - - B=-B; - ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move back delete [] bytes; } BOOL PFC::member(const GT& z) { - ZZn2 r=z.g; - - if (pow(r,*ord)!=(ZZn2)1) return FALSE; - - return TRUE; + ZZn6 r=z.g; + ZZn6 w=z.g; + Big X=*x; + if (!r.is_unitary()) return FALSE; + if (r*conj(r)!=(ZZn6)1) return FALSE; // not unitary + w.powq(*frob); + if (X<0) r=powu(inverse(r),-X); + else r=powu(r,X); + if (r==w) return TRUE; + return FALSE; } GT PFC::pairing(const G2& x,const G1& y) @@ -1134,24 +1436,28 @@ int PFC::precomp_for_mult(G1& w,BOOL small) int PFC::precomp_for_mult(G2& w,BOOL small) { - ECn v; + ECn3 v; + + ZZn3 x,y; int i,j,k,bp,is,t; if (small) t=MR_ROUNDUP(2*S,WINDOW_SIZE); else t=MR_ROUNDUP(bits(*ord),WINDOW_SIZE); - normalise(w.g); + w.g.norm(); v=w.g; - w.mtable=new ECn[1< Date: Tue, 5 Mar 2013 15:09:25 -0500 Subject: [PATCH 08/12] implemented serialization methods for the element --- source/curve/pairing/mnt_pair.cpp | 194 +++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/mnt_pair.cpp b/source/curve/pairing/mnt_pair.cpp index 2922767..490022b 100644 --- a/source/curve/pairing/mnt_pair.cpp +++ b/source/curve/pairing/mnt_pair.cpp @@ -1,6 +1,7 @@ /*************************************************************************** - * +This file has been modified by Raytheon BBN Technologies - January 2013. * + * Copyright 2013 CertiVox IOM Ltd. * * This file is part of CertiVox MIRACL Crypto SDK. * @@ -984,6 +985,78 @@ int GT::spill(char *& bytes) return len; } +/* + * jkhoury@bbn.com + * Serialization method for the points + * + */ +int GT::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn2 a,b,c; + Big x,y; + + bytes=new char[len]; + + g.get(a,b,c); + a.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + c.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ +void GT::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn2 a,b,c; + Big x,y; + if (etable!=NULL){ + delete [] etable; + etable = NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + a.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b.set(x,y); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c.set(x,y); + + g.set(a,b,c); + + delete [] bytes; +} + // // restore precomputation for GT from byte array // @@ -1086,6 +1159,53 @@ void G1::restore(char *bytes) delete [] bytes; } +/* + * jkhoury@bbn.com + * Serialization method for the point x,y + * + */ +int G1::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the point x,y + * This will reset the element to point x,y + * + */ +void G1::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + g.set(x,y); + + delete [] bytes; +} + G2 operator+(const G2& x,const G2& y) { G2 z=x; @@ -1173,6 +1293,78 @@ void G2::restore(char *bytes) delete [] bytes; } +/* + * jkhoury@bbn.com + * Serialization method for the points + * + */ +int G2::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; + + + bytes=new char[len]; + + g.get(x,y); + x.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + y.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ +void G2::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + a=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + x.set(a,b,c); + a=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y.set(a,b,c); + g.set(x,y); + + delete [] bytes; +} + BOOL PFC::member(const GT& z) { ZZn6 r=z.g; From 0d2178ecf514e1d38230cd0a71410881caea1329 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:11:06 -0500 Subject: [PATCH 09/12] reverted last change (had overriden by mistake) --- source/curve/pairing/cp_pair.cpp | 906 ++++++++++--------------------- 1 file changed, 300 insertions(+), 606 deletions(-) diff --git a/source/curve/pairing/cp_pair.cpp b/source/curve/pairing/cp_pair.cpp index 490022b..6824ded 100644 --- a/source/curve/pairing/cp_pair.cpp +++ b/source/curve/pairing/cp_pair.cpp @@ -1,51 +1,10 @@ - -/*************************************************************************** -This file has been modified by Raytheon BBN Technologies - January 2013. * - * -Copyright 2013 CertiVox IOM Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ /* + +This file has been modified by Raytheon BBN Technologies - January 2013. + + * cp_pair.cpp * - * mnt_pair.cpp - * - * MNT curve, ate pairing embedding degree 6, ideal for security level AES-80 - * - * - * Irreducible binomial MUST be of the form x^6+2. This excludes many of the curves - * found using the mnt utility! - * NOTE: This version uses a "compositum". That is the ZZn6 class is a cubic tower over ZZn2, but can - * also be considered as a quadratic tower over ZZn3. The routine shuffle converts from one form to the other. - * The former is fastest for ZZn6 arithmetic, the latter form is required for handling the second parameter - * to the pairing, which is on the quadratic twist E(Fp3) + * Cocks-Pinch curve, Tate pairing embedding degree 2, ideal for security level AES-80 * * Provides high level interface to pairing functions * @@ -53,20 +12,21 @@ the CertiVox MIRACL Crypto SDK with a closed source product. * * * This is calculated on a Pairing Friendly Curve (PFC), which must first be defined. * - * G1 is a point over the base field, and G2 is a point over an extension field of degree 3 - * GT is a finite field point over the 6-th extension, where 6 is the embedding degree. + * G1 is a point over the base field, G2 is a point on the quadratic twist + * GT is a finite field point over the 2nd extension, where 2 is the embedding degree. * */ -#define MR_PAIRING_MNT +#define MR_PAIRING_CP #include "pairing_3.h" +// Cocks-Pinch curve parameters, A,B and n, where p=3 mod 4 // AES_SECURITY=80 bit curve -// MNT curve parameters, x,A,B -// Thanks to Drew Sutherland for providing the MNT curve -// irreducible poly is x^6+2 -static char param[]="-D285DA0CFEF02F06F812"; -static char curveB[]="77479D33943B5B1F590B54258B72F316B3261D45"; +// Curve E:y^2=x^3-3x+B, #E=COF*order, modulus p + +static char MODtext[]="8D5006492B424C09D2FEBE717EE382A57EBE3A352FC383E1AC79F21DDB43706CFB192333A7E9CF644636332E83D90A1E56EFBAE8715AA07883483F8267E80ED3"; +static char Btext[]="609993837367998001C95B87A6BA872135E26906DB4C192D6E038486177A3EDF6C50B9BB20DF881F2BD05842F598F3E037B362DBF89F0A62E5871D41D951BF8E"; +static char COFtext[]="11AA00C9256849813A5FD7CE2FDC7054AFD7809E7F7FD948C4B9C1C1E76FFEFF4ECAB83C950112DECB41D6EDA"; void read_only_error(void) { @@ -74,46 +34,28 @@ void read_only_error(void) exit(0); } -void set_frobenius_constant(ZZn2 &X) -{ - Big p=get_modulus(); - switch (get_mip()->pmod8) - { - case 5: - X.set((Big)0,(Big)1); // = (sqrt(-2)^(p-1)/2 - break; - case 3: // = (1+sqrt(-1))^(p-1)/2 - X.set((Big)1,(Big)1); - break; - case 7: - X.set((Big)2,(Big)1); // = (2+sqrt(-1))^(p-1)/2 - default: break; - } - X=pow(X,(p-1)/3); -} - -// Using SHA as basic hash algorithm +// Using SHA256 as basic hash algorithm // // Hash function // -#define HASH_LEN 20 +#define HASH_LEN 32 Big H1(char *string) { // Hash a zero-terminated string to a number < modulus Big h,p; char s[HASH_LEN]; int i,j; - sha sh; + sha256 sh; - shs_init(&sh); + shs256_init(&sh); for (i=0;;i++) { if (string[i]==0) break; - shs_process(&sh,string[i]); + shs256_process(&sh,string[i]); } - shs_hash(&sh,s); + shs256_hash(&sh,s); p=get_modulus(); h=1; j=0; i=1; forever @@ -129,68 +71,56 @@ Big H1(char *string) void PFC::start_hash(void) { - shs_init(&SH); + shs256_init(&SH); } Big PFC::finish_hash_to_group(void) { Big hash; char s[HASH_LEN]; - shs_hash(&SH,s); + shs256_hash(&SH,s); hash=from_binary(HASH_LEN,s); return hash%(*ord); } void PFC::add_to_hash(const GT& x) -{ - ZZn6 u=x.g; - ZZn2 v; - ZZn l,h; - Big a,xx[2]; - int i,j,m; - - u.get(v); - v.get(l,h); - xx[0]=l; xx[1]=h; +{ // compress it and add + ZZn2 u=x.g; + Big a; + int m; - for (i=0;i<2;i++) + u.get(a); + + while (a>0) { - a=xx[i]; - while (a>0) - { - m=a%256; - shs_process(&SH,m); - a/=256; - } + m=a%256; + shs256_process(&SH,m); + a/=256; } - } -void PFC::add_to_hash(const G2& x) +void PFC::add_to_hash(const G1& x) { - ZZn3 X,Y; - ECn3 v=x.g; - Big a; - ZZn xx[6]; - + Big a,X,Y; int i,m; - - v.get(X,Y); - X.get(xx[0],xx[1],xx[2]); - Y.get(xx[3],xx[4],xx[5]); - for (i=0;i<6;i++) + x.g.get(X,Y); + a=X; + while (a>0) { - a=(Big)xx[i]; - while (a>0) - { - m=a%256; - shs_process(&SH,m); - a/=256; - } + m=a%256; + shs256_process(&SH,m); + a/=256; + } + a=Y; + while (a>0) + { + m=a%256; + shs256_process(&SH,m); + a/=256; } } -void PFC::add_to_hash(const G1& x) +void PFC::add_to_hash(const G2& x) { Big a,X,Y; int i,m; @@ -199,14 +129,14 @@ void PFC::add_to_hash(const G1& x) while (a>0) { m=a%256; - shs_process(&SH,m); + shs256_process(&SH,m); a/=256; } a=Y; while (a>0) { m=a%256; - shs_process(&SH,m); + shs256_process(&SH,m); a/=256; } } @@ -218,36 +148,28 @@ void PFC::add_to_hash(const Big& x) while (a>0) { m=a%256; - shs_process(&SH,m); + shs256_process(&SH,m); a/=256; } } -Big H2(ZZn6 y) -{ // Hash and compress an Fp6 to a big number - sha sh; - ZZn u,v,w; - ZZn2 x; - Big a,h,xx[2]; +Big H2(ZZn2 y) +{ // Hash and compress an Fp2 to a big number + sha256 sh; + Big a,h; char s[HASH_LEN]; - int i,j,m; + int m; - shs_init(&sh); - y.get(x); - x.get(u,v); - xx[0]=u; xx[1]=v; + shs256_init(&sh); + y.get(a); - for (i=0;i<2;i++) + while (a>0) { - a=xx[i]; - while (a>0) - { - m=a%256; - shs_process(&sh,m); - a/=256; - } + m=a%256; + shs256_process(&sh,m); + a/=256; } - shs_hash(&sh,s); + shs256_hash(&sh,s); h=from_binary(HASH_LEN,s); return h; } @@ -287,57 +209,12 @@ void extract(ECn& A,ZZn& x,ZZn& y) y=(A.get_point())->Y; } - -ZZn6 shuffle(const ZZn3 &first, const ZZn3 &second) -{ // shuffle from a pair ZZn3's to three ZZn2's, as required by ZZn6 - ZZn6 w; - ZZn x0,x1,x2,x3,x4,x5; - ZZn2 t0,t1,t2; - first.get(x0,x2,x4); - second.get(x1,x3,x5); - t0.set(x0,x3); - t1.set(x1,x4); - t2.set(x2,x5); - w.set(t0,t1,t2); - return w; -} - -void unshuffle(ZZn6 &S,ZZn3 &first,ZZn3 &second) -{ // unshuffle a ZZn6 into two ZZn3's - ZZn x0,x1,x2,x3,x4,x5; - ZZn2 t0,t1,t2; - S.get(t0,t1,t2); - t0.get(x0,x3); - t1.get(x1,x4); - t2.get(x2,x5); - first.set(x0,x2,x4); - second.set(x1,x3,x5); -} - -// Calculate q*P. P(X,Y) -> P(X^p,Y^p)) - -void q_power_frobenius(ECn3 &S,ZZn2& X) -{ - ZZn6 X1,X2,Y1,Y2; - ZZn3 Sx,Sy,T; - - int qnr=get_mip()->cnr; - - S.get(Sx,Sy); - - // untwist - Sx=Sx/qnr; - Sy=tx(Sy); - Sy=Sy/(qnr*qnr); - - X1=shuffle(Sx,(ZZn3)0); Y1=shuffle((ZZn3)0,Sy); - X1.powq(X); Y1.powq(X); - unshuffle(X1,Sx,T); unshuffle(Y1,T,Sy); - - // twist - Sx=qnr*Sx; - Sy=txd(Sy*qnr*qnr); - S.set(Sx,Sy); +void extractZ(ECn& A,ZZn& z) +{ + big t; + t=(A.get_point())->Z; + if (A.get_status()!=MR_EPOINT_GENERAL) z=1; + else z=t; } // @@ -347,33 +224,34 @@ void q_power_frobenius(ECn3 &S,ZZn2& X) // Now evaluate at Q -> return (Qy-y)-slope.(Qx-x) // -ZZn6 line(ECn3& A,ECn3& C,ECn3& B,int type,ZZn3& slope,ZZn3& ex1,ZZn3& ex2,ZZn& Px,ZZn& Py) -{ - ZZn6 w; - ZZn3 d; - ZZn3 x,y; -#ifdef MR_ECN3_PROJECTIVE - ZZn3 z,z3,t; - C.getZ(z3); - d.set1(Py); - - if (type==MR_ADD) - { // exploit that B is in affine - ZZn3 x2,y2; - B.get(x2,y2); - y2*=z3; d*=z3; - w=shuffle(y2-slope*(Px+x2),d); - } - if (type==MR_DOUBLE) - { // use extra information from point doubling - A.get(x,y,z); - w=shuffle(ex1-slope*(Px*ex2+x),d*z3*ex2); - } -#else - A.get(x,y); - d.set1(Py); - w=shuffle(y-slope*(Px+x),d); -#endif +ZZn2 line(ECn& A,ECn& C,ECn& B,int type,ZZn& slope,ZZn& ex1,ZZn& ex2,ZZn& Px,ZZn& Py) +{ + ZZn2 w; + ZZn x,y,z3; + + extractZ(C,z3); + if (type==MR_ADD) + { + extract(B,x,y); + w.set(slope*(x+Px)-z3*y,z3*Py); + } + if (type==MR_DOUBLE) + { + extract(A,x,y); + w.set(-(slope*ex2)*Px-slope*x+ex1,-(z3*ex2)*Py); + } + +/* + extract(A,x,y,z); + x*=z; t=z; z*=z; z*=t; // 9 ZZn muls + n*=z; n+=x; n*=slope; + d*=z; w.set(-y,d); + extractZ(C,z3); + + w*=z3; w+=n; +*/ + +// w.set(Px*z*z*z*slope+slope*x*z-y*z3,Py*z*z*z*z3); return w; } @@ -382,26 +260,29 @@ ZZn6 line(ECn3& A,ECn3& C,ECn3& B,int type,ZZn3& slope,ZZn3& ex1,ZZn3& ex2,ZZn& // Return line function value // -ZZn6 g(ECn3& A,ECn3& B,ZZn& Px,ZZn& Py) +ZZn2 g(ECn& A,ECn& B,ZZn& Px,ZZn& Py) { - BOOL type; - ZZn3 lam,ex1,ex2; - ECn3 Q=A; + int type; + ZZn lam,extra1,extra2; + ZZn2 u; + ECn P=A; + big ptr,ex1,ex2; -// Evaluate line from A to A+B - type=A.add(B,lam,&ex1,&ex2); - - return line(Q,A,B,type,lam,ex1,ex2,Px,Py); + type=A.add(B,&ptr,&ex1,&ex2); + if (!type) return (ZZn2)1; + lam=ptr; + extra1=ex1; + extra2=ex2; + + return line(P,A,B,type,lam,extra1,extra2,Px,Py); } // if multiples of G2 can be precalculated, its a lot faster! -ZZn6 gp(ZZn3* ptable,int &j,ZZn& Px,ZZn& Py) +ZZn2 gp(ZZn* ptable,int &j,ZZn& Px,ZZn& Py) { - ZZn6 w; - ZZn3 d; - d.set1(Py); - w=shuffle(ptable[j]*Px+ptable[j+1],d); + ZZn2 w; + w.set(ptable[j]*Px+ptable[j+1],Py); j+=2; return w; } @@ -412,25 +293,17 @@ ZZn6 gp(ZZn3* ptable,int &j,ZZn& Px,ZZn& Py) int PFC::spill(G2& w,char *& bytes) { - int i,j,len,m; + int i,j,n=2*(bits(*ord-1)-2+ham(*ord)); int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - - ZZn a,b,c; - Big X=*x; + int len=n*bytes_per_big; + Big x; if (w.ptable==NULL) return 0; - m=2*(bits(X)-2+ham(X)); - len=m*3*bytes_per_big; - bytes=new char[len]; - for (i=j=0;inib-1); - - ZZn a,b,c; - Big X=*x; - if (w.ptable!=NULL) return; + int len=n*bytes_per_big; + Big x; - m=2*(bits(X)-2+ham(X)); - len=m*3*bytes_per_big; + if (w.ptable!=NULL) return; - w.ptable=new ZZn3[m]; - for (i=j=0;icoord=MR_AFFINE; // switch to affine + len=2*(nb-2+ham(*ord)); + w.ptable=new ZZn[len]; + get_mip()->coord=MR_AFFINE; for (i=nb-2;i>=0;i--) { Q=A; // Evaluate line from A to A+B - A.add(A,lam,NULL,NULL); - Q.get(x1,y1); - w.ptable[j++]=-lam; w.ptable[j++]=y1-lam*x1; + A.add(A,&ptr); + lam=ptr; + extract(Q,x,y); + w.ptable[j++]=lam; w.ptable[j++]=lam*x-y; - if (bit(X,i)==1) + if (bit(iters,i)==1) { Q=A; - type=A.add(B,lam,NULL,NULL); - Q.get(x1,y1); - w.ptable[j++]=-lam; w.ptable[j++]=y1-lam*x1; + A.add(B,&ptr); + lam=ptr; + extract(Q,x,y); + w.ptable[j++]=lam; w.ptable[j++]=lam*x-y; } } - get_mip()->coord=MR_PROJECTIVE; + get_mip()->coord=MR_PROJECTIVE; return len; } @@ -513,36 +382,28 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) GT z; ZZn *Px,*Py; int i,j,*k,nb; - ECn3 *Q,*A; + ECn *Q,*A; ECn P; - ZZn6 res; - Big X=*x; + ZZn2 res; + Big iters=*ord-1; Px=new ZZn[n]; Py=new ZZn[n]; - Q=new ECn3[n]; - A=new ECn3[n]; + Q=new ECn[n]; + A=new ECn[n]; k=new int[n]; - nb=bits(X); + nb=bits(iters); res=1; for (j=0;jg; normalise(P); Q[j]=QQ[j]->g; + P=PP[j]->g; normalise(P); Q[j]=QQ[j]->g; normalise(Q[j]); extract(P,Px[j],Py[j]); - Px[j]+=Px[j]; - Py[j]+=Py[j]; } - for (j=0;j=0;i--) { @@ -554,7 +415,7 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) else res*=gp(QQ[j]->ptable,k[j],Px[j],Py[j]); } - if (bit(X,i)==1) + if (bit(iters,i)==1) for (j=0;jptable==NULL) @@ -576,41 +437,35 @@ GT PFC::multi_miller(int n,G2** QQ,G1** PP) } // -// R-ate Pairing G2 x G1 -> GT +// Tate Pairing G1 x G1 -> GT // -// P is a point of order q in G1. Q(x,y) is a point of order q in G2. -// Note that Q is a point on the sextic twist of the curve over Fp^2, P(x,y) is a point on the -// curve over the base field Fp +// P and Q are points of order q in G1. // GT PFC::miller_loop(const G2& QQ,const G1& PP) { GT z; int i,j,n,nb,nbw,nzs; - ECn3 A,Q; + ECn A,Q; ECn P; ZZn Px,Py; BOOL precomp; - ZZn6 res; - Big X=*x; + ZZn2 res; + Big iters=*ord-1; // can omit last addition P=PP.g; Q=QQ.g; -#ifdef MR_ECN3_PROJECTIVE - Q.norm(); -#endif precomp=FALSE; if (QQ.ptable!=NULL) precomp=TRUE; normalise(P); + normalise(Q); extract(P,Px,Py); - - Px+=Px; // because x^6+2 is irreducible.. simplifies line function calculation - Py+=Py; + //Px=-Px; res=1; A=Q; // reset A - nb=bits(X); - res.mark_as_miller(); + nb=bits(iters); + j=0; for (i=nb-2;i>=0;i--) @@ -619,7 +474,7 @@ GT PFC::miller_loop(const G2& QQ,const G1& PP) if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,A,Px,Py); - if (bit(X,i)==1) + if (bit(iters,i)==1) { if (precomp) res*=gp(QQ.ptable,j,Px,Py); else res*=g(A,Q,Px,Py); @@ -633,28 +488,11 @@ GT PFC::miller_loop(const G2& QQ,const G1& PP) GT PFC::final_exp(const GT& z) { GT y; - ZZn6 w,res; - Big X=*x; + ZZn2 res; res=z.g; - - w=res; - w.powq(*frob); - res*=w; // ^(p+1) - - w=res; - w.powq(*frob); w.powq(*frob); w.powq(*frob); - res=w/res; // ^(p^3-1) - -// exploit the clever "trick" for a half-length exponentiation! - - res.mark_as_unitary(); - - w=res; - res.powq(*frob); // res*=res; // res=pow(res,CF); - - if (X<0) res/=powu(w,-X); - else res*=powu(w,X); + res=conj(res)/res; + res=pow(res,(*mod+1)/(*ord)); // raise to power of (p^2-1)/q y.g=res; @@ -664,12 +502,14 @@ GT PFC::final_exp(const GT& z) PFC::PFC(int s, csprng *rng) { int mod_bits,words; + if (s!=80) { cout << "No suitable curve available" << endl; exit(0); } - mod_bits=2*s; + + mod_bits=512; if (mod_bits%MIRACL==0) words=(mod_bits/MIRACL); @@ -684,43 +524,35 @@ PFC::PFC(int s, csprng *rng) #endif B=new Big; - x=new Big; mod=new Big; ord=new Big; cof=new Big; npoints=new Big; trace=new Big; - frob=new ZZn2; - *B=curveB; + *B=Btext; + + *cof=COFtext; + *ord=pow((Big)2,159)+pow((Big)2,17)+1; + *npoints=*cof*(*ord); + S=s; - *x=param; - Big X=*x; - - *mod=X*X+1; - *npoints=X*X-X+1; - *trace=X+1; - *cof=X*X+X+1; - *ord=*npoints; + *mod=MODtext; + *trace=*mod+1-*npoints; + ecurve(-3,*B,*mod,MR_PROJECTIVE); - set_frobenius_constant(*frob); - Big sru=pow((ZZn)-2,(*mod-1)/6); // x^6+2 is irreducible - set_zzn3(-2,sru); - mip->TWIST=MR_QUADRATIC; // twisted curve E'(ZZn3) - RNG = rng; + RNG=rng; } PFC::~PFC() { delete B; - delete x; delete mod; delete ord; delete cof; delete npoints; delete trace; - delete frob; mirexit(); } @@ -729,10 +561,11 @@ G1 PFC::mult(const G1& w,const Big& k) G1 z; if (w.mtable!=NULL) { // we have precomputed values + Big e=k; if (k<0) e=-e; - int i,j,t=w.mtbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); + int i,j,t=w.mtbits; // MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.mtable[j]; for (i=t-2;i>=0;i--) @@ -751,18 +584,16 @@ G1 PFC::mult(const G1& w,const Big& k) return z; } -// GLV + Galbraith-Scott - G2 PFC::mult(const G2& w,const Big& k) { G2 z; - Big X=*x; if (w.mtable!=NULL) { // we have precomputed values + Big e=k; if (k<0) e=-e; - int i,j,t=w.mtbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); + int i,j,t=w.mtbits; // MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.mtable[j]; for (i=t-2;i>=0;i--) @@ -775,25 +606,20 @@ G2 PFC::mult(const G2& w,const Big& k) } else { - ECn3 v=w.g; - q_power_frobenius(v,*frob); - z.g=mul(v,k/X,w.g,k%X); + z.g=w.g; + z.g*=k; } return z; } -// GLV method + Galbraith-Scott idea - GT PFC::power(const GT& w,const Big& k) { GT z; - Big X=*x; + Big e=k; + if (k<0) e=-e; if (w.etable!=NULL) { // precomputation is available - Big e=k; - if (k<0) e=-e; - - int i,j,t=w.etbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); + int i,j,t=w.etbits; //MR_ROUNDUP(2*S,WINDOW_SIZE); j=recode(e,t,WINDOW_SIZE,t-1); z.g=w.etable[j]; for (i=t-2;i>=0;i--) @@ -802,56 +628,16 @@ GT PFC::power(const GT& w,const Big& k) z.g*=z.g; if (j>0) z.g*=w.etable[j]; } - if (k<0) z.g=inverse(z.g); } else { - ZZn6 y=w.g; - y.powq(*frob); - z.g=powu(y,k/X,w.g,k%X); + z.g=powu(w.g,e); } + if (k<0) z.g=conj(z.g); return z; } -// Use Scott et al. idea - http://eprint.iacr.org/2008/530.pdf -// Map to point of correct order - -void map(ECn3 &S,Big x, ZZn2& X) -{ // S=Phi(2xP)+phi^2(2xP) - ZZn6 X1,X2,Y1,Y2; - ZZn3 Sx,Sy,T; - ECn3 S2; - int qnr=get_mip()->cnr; - - S*=x; S+=S; // hard work done here - - S.get(Sx,Sy); - - // untwist - Sx=Sx/qnr; - Sy=tx(Sy); - Sy=Sy/(qnr*qnr); - - X1=shuffle(Sx,(ZZn3)0); Y1=shuffle((ZZn3)0,Sy); - X1.powq(X); Y1.powq(X); - X2=X1; Y2=Y1; - X2.powq(X); Y2.powq(X); - unshuffle(X1,Sx,T); unshuffle(Y1,T,Sy); - - // twist - Sx=qnr*Sx; - Sy=txd(Sy*qnr*qnr); - S.set(Sx,Sy); - unshuffle(X2,Sx,T); unshuffle(Y2,T,Sy); - - //twist (again, like we did last summer...) - Sx=qnr*Sx; - Sy=txd(Sy*qnr*qnr); - S2.set(Sx,Sy); - S+=S2; -} - -// random group element +// random group member void PFC::random(Big& w) { @@ -863,52 +649,28 @@ void PFC::random(Big& w) void PFC::rankey(Big& k) { - if (RNG==NULL) k=rand(S,2); - else k=strong_rand(RNG,S,2); + if (RNG==NULL) k=rand(S,2); + else k=strong_rand(RNG,S,2); } -void PFC::hash_and_map(G2& w,char *ID) -{ - int i; - ZZn3 XX; - Big X=*x; - - Big x0=H1(ID); - forever - { - x0+=1; - XX.set2((ZZn)x0); - if (!w.g.set(XX)) continue; - - break; - } - map(w.g,X,*frob); -} +// Can be done deterministicly -void PFC::random(G2& w) +void PFC::hash_and_map(G1& w,char *ID) { - int i; - ZZn3 XX; - Big X=*x; - Big x0; - - if (RNG==NULL) x0=rand(*mod); - else x0=strong_rand(RNG,*mod); - forever - { - x0+=1; - XX.set2((ZZn)x0); - if (!w.g.set(XX)) continue; - - break; - } - map(w.g,X,*frob); + Big x0=H1(ID); + while (!w.g.set(x0,x0)) x0+=1; + w.g*=*cof; } -void PFC::hash_and_map(G1& w,char *ID) +void PFC::hash_and_map(G2& w,char *ID) { Big x0=H1(ID); + *B=-(*B); + ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move to twist while (!w.g.set(x0,x0)) x0+=1; + w.g*=(*mod+1+*trace)/(*ord); + *B=-(*B); + ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move back } void PFC::random(G1& w) @@ -916,8 +678,22 @@ void PFC::random(G1& w) Big x0; if (RNG==NULL) x0=rand(*mod); else x0=strong_rand(RNG,*mod); - while (!w.g.set(x0,x0)) x0+=1; + w.g*=*cof; +} + +void PFC::random(G2& w) +{ + Big x0; + if (RNG==NULL) x0=rand(*mod); + else x0=strong_rand(RNG,*mod); + + *B=-(*B); + ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move to twist + while (!w.g.set(x0,x0)) x0+=1; + w.g*=(*mod+1+*trace)/(*ord); + *B=-(*B); + ecurve((Big)-3,*B,*mod,MR_PROJECTIVE); // move back } Big PFC::hash_to_aes_key(const GT& w) @@ -942,7 +718,7 @@ GT operator*(const GT& x,const GT& y) GT operator/(const GT& x,const GT& y) { GT z=x; - z.g/=y.g; + z.g*=conj(y.g); // elements in GT are unitary return z; } @@ -954,8 +730,7 @@ int GT::spill(char *& bytes) { int i,j,n=(1<nib-1); - int len=n*6*bytes_per_big; - ZZn2 a,b,c; + int len=n*2*bytes_per_big; Big x,y; if (etable==NULL) return 0; @@ -963,18 +738,7 @@ int GT::spill(char *& bytes) bytes=new char[len]; for (i=j=0;inib-1); - int len=6*bytes_per_big; - ZZn2 a,b,c; + int len=2*bytes_per_big; Big x,y; bytes=new char[len]; - g.get(a,b,c); - a.get(x,y); - to_binary(x,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - to_binary(y,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - b.get(x,y); - to_binary(x,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - to_binary(y,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - c.get(x,y); + g.get(x,y); to_binary(x,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; to_binary(y,bytes_per_big,&bytes[j],TRUE); @@ -1029,8 +785,7 @@ void GT::deserialize(char *bytes) { int j=0; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - int len=6*bytes_per_big; - ZZn2 a,b,c; + int len=2*bytes_per_big; Big x,y; if (etable!=NULL){ delete [] etable; @@ -1040,60 +795,31 @@ void GT::deserialize(char *bytes) j+=bytes_per_big; y=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - a.set(x,y); - x=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - y=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - b.set(x,y); - x=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - y=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - c.set(x,y); - - g.set(a,b,c); + g.set(x,y); delete [] bytes; } -// -// restore precomputation for GT from byte array -// - void GT::restore(char *bytes) { int i,j,n=(1<nib-1); - int len=n*6*bytes_per_big; - ZZn2 a,b,c; + int len=n*2*bytes_per_big; Big x,y; if (etable!=NULL) return; - etable=new ZZn6[1<nib-1); - int len=n*6*bytes_per_big; - ZZn3 x,y; - ZZn a,b,c; + int len=n*2*bytes_per_big; + Big x,y; if (mtable==NULL) return 0; bytes=new char[len]; + for (i=j=0;inib-1); - int len=n*6*bytes_per_big; - ZZn3 x,y; - ZZn a,b,c; + int len=n*2*bytes_per_big; + Big x,y,B; if (mtable!=NULL) return; - mtable=new ECn3[1<nib-1); - int len=6*bytes_per_big; - ZZn3 x,y; - ZZn a,b,c; - + int len=2*bytes_per_big; + Big x,y; bytes=new char[len]; + g.get(x,y); - x.get(a,b,c); - to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - y.get(a,b,c); - to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); - j+=bytes_per_big; - to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + //x=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + to_binary(y,bytes_per_big,&bytes[j],TRUE); j+=bytes_per_big; return len; } -/* - * jkhoury@bbn.com - * Deserialization method for the points - * This will reset the element precomp - * - */ + +// jkhoury@bbn.com +// restore element from byte array +// reset the precomp +// + void G2::deserialize(char *bytes) { int j=0; int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); - int len=6*bytes_per_big; - ZZn3 x,y; - ZZn a,b,c; + int len=2*bytes_per_big; + Big x,y,B; //reset precomp if (mtable!=NULL){ delete [] mtable; mtable=NULL; } - a=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - b=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - c=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - x.set(a,b,c); - a=from_binary(bytes_per_big,&bytes[j]); - j+=bytes_per_big; - b=from_binary(bytes_per_big,&bytes[j]); + + B=getB(); + B=-B; + ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move to twist + + x=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - c=from_binary(bytes_per_big,&bytes[j]); + y=from_binary(bytes_per_big,&bytes[j]); j+=bytes_per_big; - y.set(a,b,c); + g.set(x,y); + + B=-B; + ecurve((Big)-3,B,get_modulus(),MR_PROJECTIVE); // move back delete [] bytes; } BOOL PFC::member(const GT& z) { - ZZn6 r=z.g; - ZZn6 w=z.g; - Big X=*x; - if (!r.is_unitary()) return FALSE; - if (r*conj(r)!=(ZZn6)1) return FALSE; // not unitary - w.powq(*frob); - if (X<0) r=powu(inverse(r),-X); - else r=powu(r,X); - if (r==w) return TRUE; - return FALSE; + ZZn2 r=z.g; + + if (pow(r,*ord)!=(ZZn2)1) return FALSE; + + return TRUE; } GT PFC::pairing(const G2& x,const G1& y) @@ -1436,28 +1134,24 @@ int PFC::precomp_for_mult(G1& w,BOOL small) int PFC::precomp_for_mult(G2& w,BOOL small) { - ECn3 v; - - ZZn3 x,y; + ECn v; int i,j,k,bp,is,t; if (small) t=MR_ROUNDUP(2*S,WINDOW_SIZE); else t=MR_ROUNDUP(bits(*ord),WINDOW_SIZE); - w.g.norm(); + normalise(w.g); v=w.g; - w.mtable=new ECn3[1< Date: Tue, 5 Mar 2013 15:13:01 -0500 Subject: [PATCH 10/12] implemented serialization methods for the element --- source/curve/pairing/kss_pair.cpp | 263 +++++++++++++++++++++++++++++- 1 file changed, 262 insertions(+), 1 deletion(-) diff --git a/source/curve/pairing/kss_pair.cpp b/source/curve/pairing/kss_pair.cpp index 09a6d47..50199cd 100644 --- a/source/curve/pairing/kss_pair.cpp +++ b/source/curve/pairing/kss_pair.cpp @@ -1,6 +1,7 @@ /*************************************************************************** - * +This file has been modified by Raytheon BBN Technologies - January 2013. * + * Copyright 2013 CertiVox IOM Ltd. * * This file is part of CertiVox MIRACL Crypto SDK. * @@ -1399,6 +1400,146 @@ int GT::spill(char *& bytes) // restore precomputation for GT from byte array // +/* + * jkhoury@bbn.com + * Serialization method for the points + * + */ +int GT::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=18*bytes_per_big; + ZZn6 a,b,c; + ZZn3 f,s; + ZZn x,y,z; + + bytes=new char[len]; + + g.get(a,b,c); + a.get(f,s); + f.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + s.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + b.get(f,s); + f.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + s.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + c.get(f,s); + f.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + s.get(x,y,z); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(z,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the points + * This will reset the element precomp + * + */ +void GT::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=18*bytes_per_big; + ZZn6 a,b,c; + ZZn3 f,s; + ZZn x,y,z; + if (etable!=NULL){ + delete [] etable; + etable = NULL; + } + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + f.set(x,y,z); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + s.set(x,y,z); + a.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + + f.set(x,y,z); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + + s.set(x,y,z); + b.set(f,s); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + + f.set(x,y,z); + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + z=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + + s.set(x,y,z); + c.set(f,s); + g.set(a,b,c); + + delete [] bytes; +} + void GT::restore(char *bytes) { int i,j,n=(1<nib-1); + int len=2*bytes_per_big; + Big x,y; + + bytes=new char[len]; + + g.get(x,y); + to_binary(x,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary(y,bytes_per_big,&bytes[j],TRUE); + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the point x,y + * This will reset the element to point x,y + * + */ +void G1::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=2*bytes_per_big; + Big x,y; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + x=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y=from_binary(bytes_per_big,&bytes[j]); + g.set(x,y); + + delete [] bytes; +} + + G2 operator+(const G2& x,const G2& y) { G2 z=x; @@ -1621,6 +1810,78 @@ void G2::restore(char *bytes) } +/* + * jkhoury@bbn.com + * Serialization method for the 2 points + * + */ +int G2::serialize(char *& bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; + + + bytes=new char[len]; + + g.get(x,y); + x.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + y.get(a,b,c); + to_binary((Big)a,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)b,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + to_binary((Big)c,bytes_per_big,&bytes[j],TRUE); + j+=bytes_per_big; + + return len; +} +/* + * jkhoury@bbn.com + * Deserialization method for the 2 points + * This will reset the element precomp + * + */ +void G2::deserialize(char *bytes) +{ + int j=0; + int bytes_per_big=(MIRACL/8)*(get_mip()->nib-1); + int len=6*bytes_per_big; + ZZn3 x,y; + ZZn a,b,c; + //reset precomp + if (mtable!=NULL){ + delete [] mtable; + mtable=NULL; + } + + a=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + x.set(a,b,c); + a=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + b=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + c=from_binary(bytes_per_big,&bytes[j]); + j+=bytes_per_big; + y.set(a,b,c); + g.set(x,y); + + delete [] bytes; +} + // test if a ZZn18 element is of order q // can't think of a faster way to do this.. From b09f5fc48e739bd0c3e6cb8ab97d90532131ae90 Mon Sep 17 00:00:00 2001 From: jkhoury Date: Tue, 5 Mar 2013 15:17:08 -0500 Subject: [PATCH 11/12] updated revision history --- update.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/update.txt b/update.txt index 63f684d..5b5d3ce 100644 --- a/update.txt +++ b/update.txt @@ -1,4 +1,3 @@ - Version 4.0 The main changes from the earlier version 3.xx is the introduction of the @@ -440,3 +439,7 @@ Version 5.6.1 New MIRACL module mrzzn4.c +Version 5.6.1.1 (Raytheon BBN Technologies) + +Added functions serialize() and deserialize() to all pairing +files {cp,mnt,bn,bls,kss}_pair.cpp and to header From cd57e01053225db4edda38f44019fc0602929fb7 Mon Sep 17 00:00:00 2001 From: jk Date: Tue, 5 Mar 2013 16:08:03 -0500 Subject: [PATCH 12/12] Ehnacements: automated builds with optimizations and multithreading; and a benchmark utility --- Makefile | 237 +++++++++++++++++ README-makefile.txt | 85 ++++++ include/miracl_wrapper.h | 69 +++++ include/mirdef.comba10 | 18 ++ include/mirdef.comba3 | 18 ++ include/mirdef.comba4 | 18 ++ include/mirdef.comba8 | 18 ++ include/mirdef.default | 15 ++ include/mirdef.defaultMT | 16 ++ install-sh | 322 +++++++++++++++++++++++ source/curve/pairing/benchmark.cpp | 215 +++++++++++++++ source/curve/pairing/benchmarkthread.cpp | 251 ++++++++++++++++++ 12 files changed, 1282 insertions(+) create mode 100644 Makefile create mode 100644 README-makefile.txt create mode 100644 include/miracl_wrapper.h create mode 100644 include/mirdef.comba10 create mode 100644 include/mirdef.comba3 create mode 100644 include/mirdef.comba4 create mode 100644 include/mirdef.comba8 create mode 100644 include/mirdef.default create mode 100644 include/mirdef.defaultMT create mode 100755 install-sh create mode 100644 source/curve/pairing/benchmark.cpp create mode 100644 source/curve/pairing/benchmarkthread.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6421693 --- /dev/null +++ b/Makefile @@ -0,0 +1,237 @@ +#============================= +#JKHOURY@BBN.COM +# always compiles multi-threaded version +# disable comba optimization using flag comba=n +#============================= +top_srcdir = . +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin +libdir = ${exec_prefix}/lib +includedir = ${prefix}/include +mandir = ${prefix}/share/man +type=dynamic +curve=bn +comba=y + +CC = gcc +CPP = g++ +AR = ar +UNAME := $(shell uname) + +HEADERS = mirdef.h miracl.h big.h pairing_3.h zzn.h zzn2.h zzn3.h zzn4.h \ + zzn6.h zzn6a.h zzn8.h zzn12a.h zzn18.h zzn24.h \ + ecn.h ec2.h ecn2.h ecn3.h ecn4.h +DIST=miracl$(curve) +DISTNAME = $(addprefix lib, $(DIST)) +CURVEPREFIX=mrpfc +CURVEDIST=$(CURVEPREFIX)$(curve) +CURVEDISTNAME=lib$(CURVEDIST) +TARGETS = copyfiles $(DISTNAME) $(CURVEDISTNAME) pclean +ifeq ($(curve), kss) + WORDS = 8 +else ifeq ($(curve), mnt) + WORDS = 3 +else ifeq ($(curve), cp) + WORDS = 8 +else ifeq ($(curve), bn) + WORDS = 4 +else ifeq ($(curve), bls) + WORDS = 10 +else + TARGETS = exit +endif + +MIRDEF = mirdef.defaultMT +ifeq ($(strip $(comba)), y) + MIRDEF = mirdef.comba$(WORDS) + CPPFLAG = -DZZNS=$(WORDS) + C_COMBA_OBJECT = mrcomba.o +endif + +CFLAG = -D_REENTRANT +LDFLAGMT = -lpthread + +ifeq ($(strip $(type)), static) + CFLAGS = $(CFLAG) + DISTNAME = $(addprefix lib,$(addsuffix .a, $(DIST))) + DISTS = $(DISTNAME).a $(CURVEDISTNAME).a +else #dynamic + CFLAGS = -fPIC $(CFLAG) +ifeq ($(strip $(UNAME)), Darwin) + DISTS = $(DISTNAME).dylib $(CURVEDISTNAME).dylib +else + DISTS = $(DISTNAME).so $(CURVEDISTNAME).so +endif + +endif + +LDFLAG = -L. -l$(DIST) +LDFLAGS = $(LDFLAG) -l$(CURVEDIST) $(LDFLAGMT) + +#TARGETS = copyfiles $(DISTNAME) libmrpfccp libmrpfcmnt libmrpfcbn libmrpfckss libmrpfcbls libmrpfcss2 pclean + +MANUALS = $(TARGETS:=.1) +HTMLMANS = $(MANUALS:.1=.html) + +C_OBJECTS = mrcore.o mrarth0.o mrarth1.o mrarth2.o mralloc.o mrsmall.o mrzzn2.o mrzzn3.o \ + mrio1.o mrio2.o mrjack.o mrgcd.o mrxgcd.o mrarth3.o mrbits.o mrecn2.o mrzzn4.o \ + mrrand.o mrprime.o mrcrt.o mrscrt.o mrmonty.o mrcurve.o mrsroot.o mrzzn2b.o \ + mrpower.o mrfast.o mrshs.o mrshs256.o mraes.o mrlucas.o mrstrong.o mrgcm.o \ + mrflash.o mrfrnd.o mrdouble.o mrround.o mrbuild.o \ + mrflsh1.o mrpi.o mrflsh2.o mrflsh3.o mrflsh4.o \ + mrbrick.o mrebrick.o mrec2m.o mrgf2m.o mrmuldv.o mrshs512.o $(C_COMBA_OBJECT) + +CPP_OBJECTS = big.o gf2m4x.o gf2m.o \ + ecn.o ec2.o ecn2.o ecn3.o ecn4.o \ + zzn.o zzn2.o zzn3.o zzn4.o zzn6.o zzn6a.o zzn8.o zzn12a.o zzn18.o zzn24.o \ + cp_pair.o mnt_pair.o bn_pair.o kss_pair.o bls_pair.o ss2_pair.o \ + benchmark.o cpabe.o ipe.o cpabethread.o + +cp_OBJECTS = cp_pair.o zzn2.o big.o zzn.o ecn.o +mnt_OBJECTS = mnt_pair.o zzn6a.o ecn3.o zzn3.o zzn2.o big.o zzn.o ecn.o +bn_OBJECTS = bn_pair.o zzn12a.o zzn4.o ecn2.o zzn2.o big.o zzn.o ecn.o +kss_OBJECTS = kss_pair.o zzn18.o zzn6.o ecn3.o zzn3.o big.o zzn.o ecn.o +bls_OBJECTS = bls_pair.o zzn24.o zzn8.o zzn4.o zzn2.o ecn4.o big.o zzn.o ecn.o +ss2_OBJECTS = ss2_pair.o ec2.o gf2m4x.o gf2m.o big.o + +# default target +all: $(TARGETS) + +mex: mex.c + $(CC) -m64 -O2 -o $@ $^ + + +copyfiles: mex + echo "building for OS $(UNAME), curve $(curve)" + cp $(MIRDEF) mirdef.h + ./mex $(WORDS) amd64 mrcomba + cp -p mrmuldv.g64 mrmuldv.c +#ifeq ($(strip $(UNAME)), Darwin) +# cp -p mrmuldv.macs64 mrmuldv.s64 +#else #assume Linux +# cp -p mrmuldv.linuxs64 mrmuldv.s64 +#endif + + +$(DISTNAME): $(C_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $@ $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CC) -dynamiclib -m64 -O2 -o $(addsuffix .dylib, $@) $^ +else #assume Linux + $(CC) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 -o $(addsuffix .so, $@) $^ +endif +endif + +libmrpfccp: $(cp_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +libmrpfcmnt: $(mnt_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +libmrpfcbn: $(bn_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +libmrpfckss: $(kss_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +libmrpfcbls: $(bls_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +libmrpfcss2: $(ss2_OBJECTS) +ifeq ($(strip $(type)), static) + $(AR) r $(addsuffux .a, $@) $^ +else +ifeq ($(strip $(UNAME)), Darwin) + $(CPP) -dynamiclib -framework JavaVM -m64 -O2 $(CPPFLAG) -o $(addsuffix .dylib, $@) $^ $(LDFLAG) +else #assume Linux + $(CPP) -shared -Wl,-soname,$(addsuffix .so, $@) -m64 -O2 $(CPPFLAG) -o $(addsuffix .so, $@) $^ $(LDFLAG) +endif +endif + +benchmarkthread cpabethread: + $(CPP) -m64 -O2 $(CPPFLAG) -o $@ $(addsuffix .cpp, $@) $(LDFLAGS) + +$(CPP_OBJECTS): + $(CPP) -Wall -c -m64 -O2 $(CFLAGS) $(CPPFLAG) -o $@ $(subst .o,.cpp,$@) + +mrcomba.o: + $(CC) -Wall -c -m64 -O2 $(CFLAGS) -o $@ mrcomba.c + +%.o: %.c +ifeq ($(strip $(wildcard $<)),) + $(CC) -Wall -c -m64 -O2 $(CFLAGS) -o $@ $< +else + $(CPP) -c -m64 -O2 $(CFLAGS) $(CPPFLAG) -o $@ $(addsuffix pp, $<) +endif + +exit: + echo "You need to specify a correct curve: make curve= where curve=cp|mnt|bn|kss|bls" + +pclean: + rm *.o + +# installation +install: $(DISTS) $(HEADERS) + mkdir -p $(libdir) + mkdir -p $(includedir) + $(top_srcdir)/install-sh -m 755 $(DISTS) $(libdir) + $(top_srcdir)/install-sh -m 644 $(HEADERS) $(includedir) + +uninstall: + for HEADER in $(HEADERS); \ + do \ + /bin/rm -f $(includedir)/$$HEADER; \ + done + for LIB in $(DISTS); \ + do \ + /bin/rm -f $(libdir)/$$LIB; \ + done + +# cleanup + +# remove everything an installing user can rebuild +clean: pclean + rm -f $(DISTS) *.tar.gz *~ diff --git a/README-makefile.txt b/README-makefile.txt new file mode 100644 index 0000000..97a4b30 --- /dev/null +++ b/README-makefile.txt @@ -0,0 +1,85 @@ +author: Joud Khoury jkhoury@bbn.com + +============== +Introduction +============== +We have implemented a Makelfiles to automate building the standard library. +This make file builds shared objects for Mac and Linux. It takes care of linking the correct +objects depending on specified curve. It creates a separate library per curve to expose the standard +miracl PFC interface to external applications. +Note that to optimize the Miracl implementation based on the specific architecture, +we used the comba optimizations. Comba optimization depends on the modulus p of the curve being used. +To implement comba we need to specify the number of words n +which should be n=ceil(p/word size) where word size depends on the architecture (64 bit or 32 bit). +For the MNT curve for example, where p=160bits n=3 whereas for the CP curve p=512 and hence n=8. +For additional info see https://certivox.jira.com/wiki/display/MIRACLPUBLIC/MIRACL+User%27s+Manual + +By default all libraries are compiled with multi-threading and COMBA support + +============= +INSTALLATION +============= +We shall different curves with the make below. Here is a list of the allows curves to specify for below + := [cp | mnt | bn | kss | bls | ss2 ] +Anytime curve is specified, make sure to set the same curve in the header of the miracl_wrapper.h + +First flat unzip the miracl code + unzip -j -aa -L miracl.zip + +Now we are ready to make: + +Makefile with optimizations for Intel and AMD64 architecture (e.g. cluster nodes) with comba optimizations, and multi-threading +for both osx and linux + #uninstall first if different version previosuly installed) + $make clean + #make a separate library per curve + $make curve=cp + $make curve=mnt + $make curve=bn + $make curve=kss + $make curve=bls + #install each one (same applies for uninstall) + # libdir and includedir have to specified only when user does not have root access + # and in that case LD_LIBRARY_PATH must include libdir + $sudo make install curve=cp libdir= includedir= + $sudo make install curve=mnt libdir= includedir= + $sudo make install curve=bn libdir= includedir= + $sudo make install curve=kss libdir= includedir= + $sudo make install curve=bls libdir= includedir= + #test it: first set correctly in miracl_wrapper.h and build multi-threaded benchmark as follows + $make benchmarkthread curve= + $./benchmarkthread + +Makefile withOUT optimizations + #same as above except pass comba=n to the make + + #To test the single threaded version run (only if single threaded libs were built above i.e. no mthreading flag passed) + $make cpabe curve= comba=n + $./cpabe + + + #To create single-threaded benchmark + #set the curve in the header of the miracl_wrapper.h; this is what benchmark.cpp will be linked against, then + $make benchmark curve= comba=n + $./benchmark + +============= +Other NOTES +============= +[For record only - do not make these changes, already in the makefile] +To compile an optimized version of the library, we had to implement the following changes +1- define MR_COMBA n in mirdef.h +2- generate mrcomba.c using mex utility e.g. ./mex n amd64 mrcomba (requires compiling mex.c first) +3- use the correct muldiv.c depending on architecture (check use guide) +4- compile mrcomba.c and muldiv.c and include it in the miracle.a library +5- use the -DZZNS=n flag when compiling the c++ libraries + +To compile with multithreading support, pass mthreading=true to the make + +We extended the PFC implementations for G1 , G2, and GT to support serialize/deserialize of elements. +We need that for over the network crypto that we do. The spill/restore functionality only serialized +precomputations which we are less interested in (we can pre comp at the destiantions). + +- [Completed 10/2012] Update AMD makefile to support compiling all curve linbraries (instead of specifying curve) +- [Completed 10/2012] Update AMD makefile to support multi-threading compile +- [Completed 10/2012] Create same for optimized intel \ No newline at end of file diff --git a/include/miracl_wrapper.h b/include/miracl_wrapper.h new file mode 100644 index 0000000..d55bb16 --- /dev/null +++ b/include/miracl_wrapper.h @@ -0,0 +1,69 @@ +/* + Quick Benchmark utility + jkhoury@bbn.com + + Compile with modules as specified below + +TYPE 1 curves +============ + For MR_PAIRING_SS2 curves + ss2_pair.cpp ec2.cpp gf2m4x.cpp gf2m.cpp big.cpp miracl.lib + + For MR_PAIRING_SSP curves + ssp_pair.cpp ecn.cpp zzn2.cpp zzn.cpp big.cpp miracl.lib + +TYPE 3 curves +============= + For MR_PAIRING_CP curve + cp_pair.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib + + For MR_PAIRING_MNT curve + mnt_pair.cpp zzn6a.cpp ecn3.cpp zzn3.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib + + For MR_PAIRING_BN curve + bn_pair.cpp zzn12a.cpp ecn2.cpp zzn4.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib + + For MR_PAIRING_KSS curve + kss_pair.cpp zzn18.cpp zzn6.cpp ecn3.cpp zzn3.cpp big.cpp zzn.cpp ecn.cpp miracl.lib + + For MR_PAIRING_BLS curve + bls_pair.cpp zzn24.cpp zzn8.cpp zzn4.cpp zzn2.cpp ecn4.cpp big.cpp zzn.cpp ecn.cpp miracl.lib + +*/ +#define TYPE3 + +#ifdef TYPE3 +#define GROUP_NAME G2 +//********* choose just one of these pairs ********** +//#define MR_PAIRING_CP // AES-80 security +//#define AES_SECURITY 80 + +//#define MR_PAIRING_MNT // AES-80 security +//#define AES_SECURITY 80 + +#define MR_PAIRING_BN // AES-128 or AES-192 security **** +#define AES_SECURITY 128 +//#define AES_SECURITY 192 + +//#define MR_PAIRING_KSS // AES-192 security +//#define AES_SECURITY 192 + +//#define MR_PAIRING_BLS // AES-256 security +//#define AES_SECURITY 256 +//********************************************* +#include "pairing_3.h" +#endif + +#ifdef TYPE1 +#define GROUP_NAME G1 +//********* choose just one of these ********** +#define MR_PAIRING_SS2 // AES-80 or AES-128 security GF(2^m) curve +#define AES_SECURITY 80 // OR +//#define AES_SECURITY 128 + +//#define MR_PAIRING_SSP // AES-80 or AES-128 security GF(p) curve +//#define AES_SECURITY 80 // OR +//#define AES_SECURITY 128 +//********************************************* +#include "pairing_1.h" +#endif diff --git a/include/mirdef.comba10 b/include/mirdef.comba10 new file mode 100644 index 0000000..b31e50b --- /dev/null +++ b/include/mirdef.comba10 @@ -0,0 +1,18 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MR_ALWAYS_BINARY +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 +#define MR_COMBA 10 +#define MR_UNIX_MT diff --git a/include/mirdef.comba3 b/include/mirdef.comba3 new file mode 100644 index 0000000..8824814 --- /dev/null +++ b/include/mirdef.comba3 @@ -0,0 +1,18 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MR_ALWAYS_BINARY +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 +#define MR_COMBA 3 +#define MR_UNIX_MT \ No newline at end of file diff --git a/include/mirdef.comba4 b/include/mirdef.comba4 new file mode 100644 index 0000000..66479ce --- /dev/null +++ b/include/mirdef.comba4 @@ -0,0 +1,18 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MR_ALWAYS_BINARY +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 +#define MR_COMBA 4 +#define MR_UNIX_MT \ No newline at end of file diff --git a/include/mirdef.comba8 b/include/mirdef.comba8 new file mode 100644 index 0000000..aff7605 --- /dev/null +++ b/include/mirdef.comba8 @@ -0,0 +1,18 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MR_ALWAYS_BINARY +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 +#define MR_COMBA 8 +#define MR_UNIX_MT \ No newline at end of file diff --git a/include/mirdef.default b/include/mirdef.default new file mode 100644 index 0000000..631d0ed --- /dev/null +++ b/include/mirdef.default @@ -0,0 +1,15 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 diff --git a/include/mirdef.defaultMT b/include/mirdef.defaultMT new file mode 100644 index 0000000..78bbf94 --- /dev/null +++ b/include/mirdef.defaultMT @@ -0,0 +1,16 @@ +/* + * MIRACL compiler/hardware definitions - mirdef.h + * Copyright (c) 1988-2008 Shamus Software Ltd. + */ + +#define MR_LITTLE_ENDIAN +#define MIRACL 64 +#define mr_utype long +#define mr_unsign64 unsigned long +#define MR_IBITS 32 +#define MR_LBITS 64 +#define mr_unsign32 unsigned int +#define MR_FLASH 52 +#define MAXBASE ((mr_small)1<<(MIRACL-1)) +#define MR_BITSINCHAR 8 +#define MR_UNIX_MT \ No newline at end of file diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..dd97db7 --- /dev/null +++ b/install-sh @@ -0,0 +1,322 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2004-09-10.20 + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +chmodcmd="$chmodprog 0755" +chowncmd= +chgrpcmd= +stripcmd= +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src= +dst= +dir_arg= +dstarg= +no_target_directory= + +usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: +-c (ignored) +-d create directories instead of installing files. +-g GROUP $chgrpprog installed files to GROUP. +-m MODE $chmodprog installed files to MODE. +-o USER $chownprog installed files to USER. +-s $stripprog installed files. +-t DIRECTORY install into DIRECTORY. +-T report an error if DSTFILE is a directory. +--help display this help and exit. +--version display version info and exit. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG +" + +while test -n "$1"; do + case $1 in + -c) shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + --help) echo "$usage"; exit 0;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -s) stripcmd=$stripprog + shift + continue;; + + -t) dstarg=$2 + shift + shift + continue;; + + -T) no_target_directory=true + shift + continue;; + + --version) echo "$0 $scriptversion"; exit 0;; + + *) # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + test -n "$dir_arg$dstarg" && break + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dstarg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dstarg" + shift # fnord + fi + shift # arg + dstarg=$arg + done + break;; + esac +done + +if test -z "$1"; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src ;; + esac + + if test -n "$dir_arg"; then + dst=$src + src= + + if test -d "$dst"; then + mkdircmd=: + chmodcmd= + else + mkdircmd=$mkdirprog + fi + else + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dstarg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dstarg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst ;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dstarg: Is a directory" >&2 + exit 1 + fi + dst=$dst/`basename "$src"` + fi + fi + + # This sed command emulates the dirname command. + dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + + # Make sure that the destination directory exists. + + # Skip lots of stat calls in the usual case. + if test ! -d "$dstdir"; then + defaultIFS=' + ' + IFS="${IFS-$defaultIFS}" + + oIFS=$IFS + # Some sh's can't handle IFS=/ for some reason. + IFS='%' + set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` + IFS=$oIFS + + pathcomp= + + while test $# -ne 0 ; do + pathcomp=$pathcomp$1 + shift + if test ! -d "$pathcomp"; then + $mkdirprog "$pathcomp" + # mkdir can fail with a `File exist' error in case several + # install-sh are creating the directory concurrently. This + # is OK. + test -d "$pathcomp" || exit + fi + pathcomp=$pathcomp/ + done + fi + + if test -n "$dir_arg"; then + $doit $mkdircmd "$dst" \ + && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } + + else + dstfile=`basename "$dst"` + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + trap '(exit $?); exit' 1 2 13 15 + + # Copy the file name to the temp name. + $doit $cpprog "$src" "$dsttmp" && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ + && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ + && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ + && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && + + # Now rename the file to the real destination. + { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ + || { + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + if test -f "$dstdir/$dstfile"; then + $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ + || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ + || { + echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 + (exit 1); exit + } + else + : + fi + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" + } + } + fi || { (exit 1); exit; } +done + +# The final little trick to "correctly" pass the exit status to the exit trap. +{ + (exit 0); exit +} + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/source/curve/pairing/benchmark.cpp b/source/curve/pairing/benchmark.cpp new file mode 100644 index 0000000..303e2dc --- /dev/null +++ b/source/curve/pairing/benchmark.cpp @@ -0,0 +1,215 @@ +/* + Quick Benchmark utility + jkhoury@bbn.com + + +*/ +#include "miracl_wrapper.h" + +#include +#include +#include + +int main(int argc, char* argv[]) +{ + const int NUM_GROUPS = 4, NUM_TIMES=11; + int i,j=0, n=20; + double t[NUM_TIMES], elapsed; + clock_t start; + + + PFC pfc(AES_SECURITY); // initialise pairing-friendly curve + miracl* mip=get_mip(); + + time_t seed; + + if(argc == 2) + n = atoi(argv[1]); + + string group_names[NUM_GROUPS ] = {"G1","G2","GT","Zp"}; + string headers[NUM_TIMES] = {"avg pairing time (ms): ", "one more multi_pairing (ms)", + "avg pairing precomp time (ms): ", "avg pairing w/ precomp time (ms): ", "one more multi_pairing x2 w/precomp (ms)", "one more multi_pairing x3 w/precomp (ms)", + "avg multiply_G1 time (ms): ", "avg multiply_GT time (ms): ", + "avg exp time (ms): ", "avg exp precomp time (ms): ", "avg exp w/ precomp time (ms): " + }; + G1 g1[n], h1[n], H1[n], l1[n], r1[n], P1[n]; + G1 *mg1 [2]; + G1* mmg1[3]; + GROUP_NAME g2[n], h2[n], r2[n]; + GROUP_NAME *mg2[2]; + GROUP_NAME *mmg2[3]; + GT *L = new GT[n]; + GT *ML = new GT[n]; + GT *R = new GT[n]; + GT *MR = new GT[n]; + Big b1[n], b2[n]; + + time(&seed); + irand((long)seed); + + Big order=pfc.order(); + for(int i=0; i< NUM_TIMES; i++){ + t[i] = 0; + } + cout << "Starting pairing and multiplication benchmark, n=" << n << " iterations" << endl; + for(int i=0; i +#include +#include +#include +#include + +void *execute(void *id) +//void execute( long id) +{ + long myid = (long)id; + const int NUM_GROUPS = 4, NUM_TIMES=11; + int i,j=0, n=20; + double t[NUM_TIMES], elapsed; + clock_t start; + ostringstream stream; + + stream << "creating thread: " << myid << " ..."<< endl; + PFC pfc(AES_SECURITY); // initialise pairing-friendly curve + miracl* mip=get_mip(); + + time_t seed; + + n = 100; + + string group_names[NUM_GROUPS ] = {"G1","G2","GT","Zp"}; + string headers[NUM_TIMES] = {"avg pairing time (ms): ", "one more multi_pairing (ms)", + "avg pairing precomp time (ms): ", "avg pairing w/ precomp time (ms): ", "one more multi_pairing x2 w/precomp (ms)", "one more multi_pairing x3 w/precomp (ms)", + "avg multiply_G1 time (ms): ", "avg multiply_GT time (ms): ", + "avg exp time (ms): ", "avg exp precomp time (ms): ", "avg exp w/ precomp time (ms): " + }; + G1 g1[n], h1[n], H1[n], l1[n], r1[n], P1[n]; + G1 *mg1 [2]; + G1* mmg1[3]; + GROUP_NAME g2[n], h2[n], r2[n]; + GROUP_NAME *mg2[2]; + GROUP_NAME *mmg2[3]; + GT *L = new GT[n]; + GT *ML = new GT[n]; + GT *R = new GT[n]; + GT *MR = new GT[n]; + Big b1[n], b2[n]; + + time(&seed); + irand((long)(seed+myid)); + + Big order=pfc.order(); + for(int i=0; i< NUM_TIMES; i++){ + t[i] = 0; + } + stream << "Starting pairing and multiplication benchmark, n=" << n << " iterations" << endl; + for(int i=0; i