You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@milagro.apache.org by km...@apache.org on 2019/08/26 13:25:26 UTC
[incubator-milagro-crypto-c] 02/02: added BLS SSS to BLS library
This is an automated email from the ASF dual-hosted git repository.
kmccusker pushed a commit to branch bls-sss
in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-c.git
commit db8d27d0cc9987bed2d0c9531d6fe605e8833bb4
Author: Kealan McCusker <ke...@gmail.com>
AuthorDate: Mon Aug 26 14:25:04 2019 +0100
added BLS SSS to BLS library
---
VERSION | 2 +-
examples/CMakeLists.txt | 4 +
examples/example_bls_ZZZ.c.in | 16 ++-
examples/example_bls_sss_ZZZ.c.in | 242 +++++++++++++++++++++++++++++++++++++
include/bls.h.in | 57 +++++++--
include/bls192.h.in | 33 ++++++
include/bls256.h.in | 33 ++++++
src/bls.c.in | 216 +++++++++++++++++++++++++++++++++
src/bls192.c.in | 216 +++++++++++++++++++++++++++++++++
src/bls256.c.in | 216 +++++++++++++++++++++++++++++++++
test/CMakeLists.txt | 1 +
test/test_bls_ZZZ.c.in | 6 +-
test/test_bls_sss_ZZZ.c.in | 243 ++++++++++++++++++++++++++++++++++++++
13 files changed, 1265 insertions(+), 20 deletions(-)
diff --git a/VERSION b/VERSION
index 7dea76e..9084fa2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.1
+1.1.0
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index d81e923..785630e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -50,6 +50,10 @@ foreach(curve ${AMCL_CURVE})
amcl_configure_file_curve(example_bls_ZZZ.c.in example_bls_${TC}.c "${curve}" example_bls_${TC}_GEN_SRCS)
add_executable(example_bls_${TC} ${example_bls_${TC}_GEN_SRCS})
target_link_libraries(example_bls_${TC} PRIVATE amcl_bls_${TC})
+
+ amcl_configure_file_curve(example_bls_sss_ZZZ.c.in example_bls_sss_${TC}.c "${curve}" example_bls_sss_${TC}_GEN_SRCS)
+ add_executable(example_bls_sss_${TC} ${example_bls_sss_${TC}_GEN_SRCS})
+ target_link_libraries(example_bls_sss_${TC} PRIVATE amcl_bls_${TC})
endif()
endforeach()
diff --git a/examples/example_bls_ZZZ.c.in b/examples/example_bls_ZZZ.c.in
index 736e54d..d171a9d 100644
--- a/examples/example_bls_ZZZ.c.in
+++ b/examples/example_bls_ZZZ.c.in
@@ -16,9 +16,18 @@ specific language governing permissions and limitations
under the License.
*/
-/* Build executable after installation:
+/*
+ BLS example code.
+
+ Build executable after installation:
- gcc -O0 -g ./testbls_ZZZ.c $(pkg-config --libs --cflags amcl) -o testbls_ZZZ
+ 1. Change headers;
+
+ #include "bls_ZZZ.h" -> #include <amcl/bls_ZZZ.h>
+
+ 2. Build code
+
+ gcc -O0 -g ./example_bls_ZZZ.c $(pkg-config --libs --cflags amcl) -o example_bls_ZZZ
*/
@@ -269,12 +278,11 @@ int main()
OCT_fromHex(&SEED,seedHex);
printf("SEED: ");
OCT_output(&SEED);
- printf("\n");
// initialise strong RNG
CREATE_CSPRNG(&RNG,&SEED);
- printf("\nTesting BLS signature for curve ZZZ\n");
+ printf("\nBLS example for curve ZZZ\n");
bls(&RNG);
KILL_CSPRNG(&RNG);
diff --git a/examples/example_bls_sss_ZZZ.c.in b/examples/example_bls_sss_ZZZ.c.in
new file mode 100644
index 0000000..c325d68
--- /dev/null
+++ b/examples/example_bls_sss_ZZZ.c.in
@@ -0,0 +1,242 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+/*
+ BLS Shamir Secret Sharing example code.
+
+ Build executable after installation:
+
+ 1. Change headers;
+
+ #include "bls_ZZZ.h" -> #include <amcl/bls_ZZZ.h>
+
+ 2. Build code
+
+ gcc -O0 -g ./example_bls_sss_ZZZ.c $(pkg-config --libs --cflags amcl) -o example_bls_sss_ZZZ
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config_curve_ZZZ.h"
+#include "randapi.h"
+
+#if CURVE_SECURITY_ZZZ == 128
+#include "bls_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "bls192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "bls256_ZZZ.h"
+#endif
+
+// Support multiple security levels
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*BFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*BFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*BFS_ZZZ
+#endif
+
+static char message[]="test message";
+
+int bls_sss(csprng *RNG)
+{
+ int rc;
+ int n=4;
+ int k=3;
+
+ char ski[BGS_ZZZ];
+ octet SKI = {0,sizeof(ski),ski};
+ char pki[G2LEN];
+ octet PKI = {0,sizeof(pki),pki};
+
+ char sko[BGS_ZZZ];
+ octet SKO = {sizeof(sko),sizeof(sko),sko};
+ char skr[BGS_ZZZ];
+ octet SKR = {sizeof(skr),sizeof(skr),skr};
+
+ char sigi[BFS_ZZZ+1];
+ octet SIGI = {0,sizeof(sigi),sigi};
+ char sigr[BFS_ZZZ+1];
+ octet SIGR = {0,sizeof(sigr),sigr};
+
+ // Secret shares
+ char x[n][BGS_ZZZ];
+ octet X[n];
+ char y[n][BGS_ZZZ];
+ octet Y[n];
+
+ for(int i=0; i<n; i++)
+ {
+ memset(&y[i], 0, sizeof(y[i]));
+ Y[i].max = BGS_ZZZ;
+ Y[i].len = BGS_ZZZ;
+ Y[i].val = y[i];
+ memset(&x[i], 0, sizeof(x[i]));
+ X[i].max = BGS_ZZZ;
+ X[i].len = BGS_ZZZ;
+ X[i].val = x[i];
+ }
+
+ // Generate key pair
+ BLS_ZZZ_KEY_PAIR_GENERATE(RNG,&SKI,&PKI);
+
+ printf("Private key SKI: ");
+ OCT_output(&SKI);
+ printf("Public key PKI: ");
+ OCT_output(&PKI);
+ printf("\n");
+
+ // Sign the message
+ BLS_ZZZ_SIGN(&SIGI,message,&SKI);
+
+ printf("SIGI: ");
+ OCT_output(&SIGI);
+
+ // Verify signature
+ rc=BLS_ZZZ_VERIFY(&SIGI,message,&PKI);
+ if (rc!=BLS_OK)
+ {
+ printf("Error: Invalid Signature\n");
+ return 1;
+ }
+ printf("Success: Signature is valid\n");
+
+ // Make shares of BLS secret key
+ rc = BLS_ZZZ_MAKE_SHARES(k, n, RNG, X, Y, &SKI, &SKO);
+ if (rc!=BLS_OK)
+ {
+ printf("Error: BLS_ZZZ_MAKE_SHARES\n");
+ return 1;
+ }
+
+ for(int i=0; i<n; i++)
+ {
+ printf("X[%d] ", i);
+ OCT_output(&X[i]);
+ printf("Y[%d] ", i);
+ OCT_output(&Y[i]);
+ }
+
+ printf("SKO: ");
+ OCT_output(&SKO);
+
+ if (!OCT_comp(&SKI,&SKO))
+ {
+ printf("FAILURE SKI != SKO");
+ return 1;
+ }
+
+ // Recover BLS secret key
+ rc = BLS_ZZZ_RECOVER_SECRET(k, X, Y, &SKR);
+ if (rc!=BLS_OK)
+ {
+ printf("Error: BLS_ZZZ_RECOVER_SECRET\n");
+ return 1;
+ }
+ printf("SKR: ");
+ OCT_output(&SKR);
+
+ if (!OCT_comp(&SKR,&SKO))
+ {
+ printf("FAILURE SKR != SKO");
+ return 1;
+ }
+
+ // Generate public keys and signatures using shares
+ char pks[n][G2LEN];
+ octet PKS[n];
+ char sigs[n][BFS_ZZZ+1];
+ octet SIGS[n];
+ for(int i=0; i<n; i++)
+ {
+ memset(&sigs[i], 0, sizeof(sigs[i]));
+ SIGS[i].max = BFS_ZZZ+1;
+ SIGS[i].len = BFS_ZZZ+1;
+ SIGS[i].val = sigs[i];
+ memset(&PKS[i], 0, sizeof(PKS[i]));
+ PKS[i].max = G2LEN;
+ PKS[i].len = G2LEN;
+ PKS[i].val = pks[i];
+ BLS_ZZZ_KEY_PAIR_GENERATE(NULL,&Y[i],&PKS[i]);
+ BLS_ZZZ_SIGN(&SIGS[i],message,&Y[i]);
+ }
+
+ for(int i=0; i<n; i++)
+ {
+ printf("PKS[%d] ", i);
+ OCT_output(&PKS[i]);
+ }
+
+ for(int i=0; i<n; i++)
+ {
+ printf("SIGS[%d] ", i);
+ OCT_output(&SIGS[i]);
+ }
+ printf("\n\n");
+
+ // Recover BLS signature
+ rc = BLS_ZZZ_RECOVER_SIGNATURE(k, X, SIGS, &SIGR);
+ if (rc!=BLS_OK)
+ {
+ printf("Error: BLS_ZZZ_RECOVER_SIGNATURE\n");
+ return 1;
+ }
+ printf("SIGR: ");
+ OCT_output(&SIGR);
+
+ if (!OCT_comp(&SIGR,&SIGI))
+ {
+ printf("FAILURE SIGR != SIGI");
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int main()
+{
+#ifdef DEBUG
+ printf("%d bit build\n",CHUNK);
+#endif
+
+ char* seedHex = "78d0fb6705ce77dee47d03eb5b9c5d30";
+ char seed[16] = {0};
+ octet SEED = {sizeof(seed),sizeof(seed),seed};
+
+ // CSPRNG
+ csprng RNG;
+
+ // fake random source
+ OCT_fromHex(&SEED,seedHex);
+ printf("SEED: ");
+ OCT_output(&SEED);
+
+ // initialise strong RNG
+ CREATE_CSPRNG(&RNG,&SEED);
+
+ printf("\nBLS SSS example for curve ZZZ\n");
+ bls_sss(&RNG);
+
+ KILL_CSPRNG(&RNG);
+}
+
+
diff --git a/include/bls.h.in b/include/bls.h.in
index b500802..13332b2 100644
--- a/include/bls.h.in
+++ b/include/bls.h.in
@@ -75,39 +75,72 @@ int BLS_ZZZ_VERIFY(octet *SIG,char *m,octet *W);
/** @brief Add two members from the group G1
*
- @param R1 member of G1
- @param R2 member of G1
- @param R member of G1. R = R1+R2
+ @param R1 member of G1
+ @param R2 member of G1
+ @param R member of G1. R = R1+R2
@return Zero for success or else an error code
*/
int BLS_ZZZ_ADD_G1(octet *R1,octet *R2,octet *R);
/** @brief Add two members from the group G2
*
- @param W1 member of G2
- @param W2 member of G2
- @param W member of G2. W = W1+W2
+ @param W1 member of G2
+ @param W2 member of G2
+ @param W member of G2. W = W1+W2
@return Zero for success or else an error code
*/
int BLS_ZZZ_ADD_G2(octet *W1,octet *W2,octet *W);
/** @brief Multiply a member group G1 by an integer
*
- @param P integer
- @param R member of G1
- @param T member of G1. T=P*R
+ @param P integer
+ @param R member of G1
+ @param T member of G1. T=P*R
@return Zero for success or else an error code
*/
int BLS_ZZZ_MUL_G1(octet *P,octet *R,octet *T);
/** @brief Multiply a member group G2 by an integer
*
- @param P integer
- @param R member of G2
- @param T member of G2. T=P*R
+ @param P integer
+ @param R member of G2
+ @param T member of G2. T=P*R
@return Zero for success or else an error code
*/
int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T);
+/** @brief Use Shamir's secret sharing to distribute BLS secret keys
+ *
+ @param k Threshold
+ @param n Number of shares
+ @param RNG Pointer to a cryptographically secure random number generator
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SKI Input secret key to be shared. Ignored if set to NULL
+ @param SKO Secret key that is shared
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO);
+
+/** @brief Use Shamir's secret sharing to recover a BLS secret key
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SK Secret key that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK);
+
+/** @brief Use Shamir's secret sharing to recover a BLS signature
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SIG Signature that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG);
+
#endif
diff --git a/include/bls192.h.in b/include/bls192.h.in
index b7d22cc..88355d0 100644
--- a/include/bls192.h.in
+++ b/include/bls192.h.in
@@ -109,6 +109,39 @@ int BLS_ZZZ_MUL_G1(octet *P,octet *R,octet *T);
*/
int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T);
+/** @brief Use Shamir's secret sharing to distribute BLS secret keys
+ *
+ @param k Threshold
+ @param n Number of shares
+ @param RNG Pointer to a cryptographically secure random number generator
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SKI Input secret key to be shared. Ignored if set to NULL
+ @param SKO Secret key that is shared
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO);
+
+/** @brief Use Shamir's secret sharing to recover a BLS secret key
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SK Secret key that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK);
+
+/** @brief Use Shamir's secret sharing to recover a BLS signature
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SIG Signature that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG);
+
#endif
diff --git a/include/bls256.h.in b/include/bls256.h.in
index cc2d94e..b5b8add 100644
--- a/include/bls256.h.in
+++ b/include/bls256.h.in
@@ -109,6 +109,39 @@ int BLS_ZZZ_MUL_G1(octet *P,octet *R,octet *T);
*/
int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T);
+/** @brief Use Shamir's secret sharing to distribute BLS secret keys
+ *
+ @param k Threshold
+ @param n Number of shares
+ @param RNG Pointer to a cryptographically secure random number generator
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SKI Input secret key to be shared. Ignored if set to NULL
+ @param SKO Secret key that is shared
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO);
+
+/** @brief Use Shamir's secret sharing to recover a BLS secret key
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SK Secret key that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK);
+
+/** @brief Use Shamir's secret sharing to recover a BLS signature
+ *
+ @param k Threshold
+ @param X Output X values
+ @param Y Output Y values. Valid BLS secret keys
+ @param SIG Signature that is recovered
+ @return Zero for success or else an error code
+ */
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG);
+
#endif
diff --git a/src/bls.c.in b/src/bls.c.in
index 6868ba8..1903a58 100644
--- a/src/bls.c.in
+++ b/src/bls.c.in
@@ -25,6 +25,61 @@ under the License.
#include <time.h>
#include "bls_ZZZ.h"
+// Polynomial interpolation coefficients
+static int recover_coefficients(int k, octet* X, octet* COEFS)
+{
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX x2[k];
+ BIG_XXX coefs[k];
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(x2[i],X[i].val);
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX numerator;
+ BIG_XXX_one(numerator);
+ BIG_XXX denominator;
+ BIG_XXX_one(denominator);
+ for(int j=0; j<k; j++)
+ {
+ // others = all - current
+ // current = x2[i]
+ if (i != j)
+ {
+ // numerator = numerator * other
+ BIG_XXX_modmul(numerator,numerator,x2[j],r);
+
+ // other - current
+ BIG_XXX s;
+ BIG_XXX c;
+
+ // c = -current
+ BIG_XXX_sub(c,r,x2[i]);
+ BIG_XXX_add(s,x2[j],c);
+
+ // denominator = denominator * s
+ BIG_XXX_modmul(denominator,denominator,s,r);
+
+ }
+
+ }
+ BIG_XXX_moddiv(coefs[i], numerator, denominator, r);
+ }
+
+ // Output coefficients
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_toBytes(COEFS[i].val,coefs[i]);
+ }
+ return 0;
+
+}
+
/* hash a message to an ECP point, using SHA3 */
static void BLS_HASHIT(ECP_ZZZ *P,char *m)
{
@@ -191,3 +246,164 @@ int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T)
return BLS_OK;
}
+
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO)
+{
+ BIG_XXX y2[n];
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ // Generate polynomial: f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ BIG_XXX poly[k];
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_randomnum(poly[i],r,RNG);
+ }
+
+ // Use predefined secret
+ if (SKI != NULL)
+ {
+ BIG_XXX_fromBytes(poly[0],SKI->val);
+ }
+
+ /* Calculate f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ a0 is the secret */
+ int x=0;
+ for(int j=0; j<n; j++)
+ {
+ x++;
+ BIG_XXX xb;
+ BIG_XXX_zero(y2[j]);
+ BIG_XXX_zero(xb);
+ BIG_XXX_inc(xb,x);
+
+ // Output X shares
+ BIG_XXX_toBytes(X[j].val,xb);
+
+ // y2[j] is the accmulator
+ for(int i=k-1; i>=0; i--)
+ {
+ BIG_XXX_modmul(y2[j],y2[j],xb,r);
+ BIG_XXX_add(y2[j],poly[i],y2[j]);
+ }
+ }
+
+ // Output Y shares
+ for(int j=0; j<n; j++)
+ {
+ BIG_XXX_toBytes(Y[j].val,y2[j]);
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SKO->val,poly[0]);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK)
+{
+ int rc=0;
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX y[k];
+ BIG_XXX coefs[k];
+
+ BIG_XXX secret;
+ BIG_XXX prod;
+ BIG_XXX_zero(secret);
+
+ char coefs2[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs2[i], 0, sizeof(coefs2[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs2[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(y[i],Y[i].val);
+ BIG_XXX_fromBytes(coefs[i],COEFS[i].val);
+ BIG_XXX_modmul(prod,y[i],coefs[i],r);
+ BIG_XXX_add(secret, secret, prod);
+
+ if (BIG_XXX_comp(secret,r) == 1)
+ {
+ BIG_XXX_sub(secret,secret,r);
+ }
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SK->val,secret);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG)
+{
+ int rc = 0;
+ char product[k][BFS_ZZZ+1];
+ octet PRODUCT[k];
+
+ char coefs[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs[i], 0, sizeof(coefs[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+
+ for(int i=0; i<k; i++)
+ {
+ memset(&product[i], 0, sizeof(product[i]));
+ PRODUCT[i].max = BFS_ZZZ+1;
+ PRODUCT[i].len = BFS_ZZZ+1;
+ PRODUCT[i].val = product[i];
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ rc = BLS_ZZZ_MUL_G1(&COEFS[i], &Y[i], &PRODUCT[i]);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ BLS_ZZZ_ADD_G1(&PRODUCT[0],&PRODUCT[1],SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+
+ for(int i=2; i<k; i++)
+ {
+ BLS_ZZZ_ADD_G1(&PRODUCT[i],SIG,SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ return BLS_OK;
+}
+
+
diff --git a/src/bls192.c.in b/src/bls192.c.in
index 617a94e..1c86954 100644
--- a/src/bls192.c.in
+++ b/src/bls192.c.in
@@ -25,6 +25,61 @@ under the License.
#include <time.h>
#include "bls192_ZZZ.h"
+// Polynomial interpolation coefficients
+static int recover_coefficients(int k, octet* X, octet* COEFS)
+{
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX x2[k];
+ BIG_XXX coefs[k];
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(x2[i],X[i].val);
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX numerator;
+ BIG_XXX_one(numerator);
+ BIG_XXX denominator;
+ BIG_XXX_one(denominator);
+ for(int j=0; j<k; j++)
+ {
+ // others = all - current
+ // current = x2[i]
+ if (i != j)
+ {
+ // numerator = numerator * other
+ BIG_XXX_modmul(numerator,numerator,x2[j],r);
+
+ // other - current
+ BIG_XXX s;
+ BIG_XXX c;
+
+ // c = -current
+ BIG_XXX_sub(c,r,x2[i]);
+ BIG_XXX_add(s,x2[j],c);
+
+ // denominator = denominator * s
+ BIG_XXX_modmul(denominator,denominator,s,r);
+
+ }
+
+ }
+ BIG_XXX_moddiv(coefs[i], numerator, denominator, r);
+ }
+
+ // Output coefficients
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_toBytes(COEFS[i].val,coefs[i]);
+ }
+ return 0;
+
+}
+
/* hash a message to an ECP point, using SHA3 */
static void BLS_HASHIT(ECP_ZZZ *P,char *m)
{
@@ -191,3 +246,164 @@ int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T)
return BLS_OK;
}
+
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO)
+{
+ BIG_XXX y2[n];
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ // Generate polynomial: f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ BIG_XXX poly[k];
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_randomnum(poly[i],r,RNG);
+ }
+
+ // Use predefined secret
+ if (SKI != NULL)
+ {
+ BIG_XXX_fromBytes(poly[0],SKI->val);
+ }
+
+ /* Calculate f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ a0 is the secret */
+ int x=0;
+ for(int j=0; j<n; j++)
+ {
+ x++;
+ BIG_XXX xb;
+ BIG_XXX_zero(y2[j]);
+ BIG_XXX_zero(xb);
+ BIG_XXX_inc(xb,x);
+
+ // Output X shares
+ BIG_XXX_toBytes(X[j].val,xb);
+
+ // y2[j] is the accmulator
+ for(int i=k-1; i>=0; i--)
+ {
+ BIG_XXX_modmul(y2[j],y2[j],xb,r);
+ BIG_XXX_add(y2[j],poly[i],y2[j]);
+ }
+ }
+
+ // Output Y shares
+ for(int j=0; j<n; j++)
+ {
+ BIG_XXX_toBytes(Y[j].val,y2[j]);
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SKO->val,poly[0]);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK)
+{
+ int rc=0;
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX y[k];
+ BIG_XXX coefs[k];
+
+ BIG_XXX secret;
+ BIG_XXX prod;
+ BIG_XXX_zero(secret);
+
+ char coefs2[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs2[i], 0, sizeof(coefs2[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs2[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(y[i],Y[i].val);
+ BIG_XXX_fromBytes(coefs[i],COEFS[i].val);
+ BIG_XXX_modmul(prod,y[i],coefs[i],r);
+ BIG_XXX_add(secret, secret, prod);
+
+ if (BIG_XXX_comp(secret,r) == 1)
+ {
+ BIG_XXX_sub(secret,secret,r);
+ }
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SK->val,secret);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG)
+{
+ int rc = 0;
+ char product[k][BFS_ZZZ+1];
+ octet PRODUCT[k];
+
+ char coefs[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs[i], 0, sizeof(coefs[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+
+ for(int i=0; i<k; i++)
+ {
+ memset(&product[i], 0, sizeof(product[i]));
+ PRODUCT[i].max = BFS_ZZZ+1;
+ PRODUCT[i].len = BFS_ZZZ+1;
+ PRODUCT[i].val = product[i];
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ rc = BLS_ZZZ_MUL_G1(&COEFS[i], &Y[i], &PRODUCT[i]);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ BLS_ZZZ_ADD_G1(&PRODUCT[0],&PRODUCT[1],SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+
+ for(int i=2; i<k; i++)
+ {
+ BLS_ZZZ_ADD_G1(&PRODUCT[i],SIG,SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ return BLS_OK;
+}
+
+
diff --git a/src/bls256.c.in b/src/bls256.c.in
index 18a8ab2..8e3ca1e 100644
--- a/src/bls256.c.in
+++ b/src/bls256.c.in
@@ -25,6 +25,61 @@ under the License.
#include <time.h>
#include "bls256_ZZZ.h"
+// Polynomial interpolation coefficients
+static int recover_coefficients(int k, octet* X, octet* COEFS)
+{
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX x2[k];
+ BIG_XXX coefs[k];
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(x2[i],X[i].val);
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX numerator;
+ BIG_XXX_one(numerator);
+ BIG_XXX denominator;
+ BIG_XXX_one(denominator);
+ for(int j=0; j<k; j++)
+ {
+ // others = all - current
+ // current = x2[i]
+ if (i != j)
+ {
+ // numerator = numerator * other
+ BIG_XXX_modmul(numerator,numerator,x2[j],r);
+
+ // other - current
+ BIG_XXX s;
+ BIG_XXX c;
+
+ // c = -current
+ BIG_XXX_sub(c,r,x2[i]);
+ BIG_XXX_add(s,x2[j],c);
+
+ // denominator = denominator * s
+ BIG_XXX_modmul(denominator,denominator,s,r);
+
+ }
+
+ }
+ BIG_XXX_moddiv(coefs[i], numerator, denominator, r);
+ }
+
+ // Output coefficients
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_toBytes(COEFS[i].val,coefs[i]);
+ }
+ return 0;
+
+}
+
/* hash a message to an ECP point, using SHA3 */
static void BLS_HASHIT(ECP_ZZZ *P,char *m)
{
@@ -191,3 +246,164 @@ int BLS_ZZZ_MUL_G2(octet *P,octet *R,octet *T)
return BLS_OK;
}
+
+int BLS_ZZZ_MAKE_SHARES(int k, int n, csprng *RNG, octet* X, octet* Y, octet* SKI, octet* SKO)
+{
+ BIG_XXX y2[n];
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ // Generate polynomial: f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ BIG_XXX poly[k];
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_randomnum(poly[i],r,RNG);
+ }
+
+ // Use predefined secret
+ if (SKI != NULL)
+ {
+ BIG_XXX_fromBytes(poly[0],SKI->val);
+ }
+
+ /* Calculate f(x) = a_0 + a_1x + a_2x^2 ... a_{k-1}x^{k-1}
+ a0 is the secret */
+ int x=0;
+ for(int j=0; j<n; j++)
+ {
+ x++;
+ BIG_XXX xb;
+ BIG_XXX_zero(y2[j]);
+ BIG_XXX_zero(xb);
+ BIG_XXX_inc(xb,x);
+
+ // Output X shares
+ BIG_XXX_toBytes(X[j].val,xb);
+
+ // y2[j] is the accmulator
+ for(int i=k-1; i>=0; i--)
+ {
+ BIG_XXX_modmul(y2[j],y2[j],xb,r);
+ BIG_XXX_add(y2[j],poly[i],y2[j]);
+ }
+ }
+
+ // Output Y shares
+ for(int j=0; j<n; j++)
+ {
+ BIG_XXX_toBytes(Y[j].val,y2[j]);
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SKO->val,poly[0]);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SECRET(int k, octet* X, octet* Y, octet* SK)
+{
+ int rc=0;
+ BIG_XXX r;
+ BIG_XXX_rcopy(r,CURVE_Order_ZZZ);
+
+ BIG_XXX y[k];
+ BIG_XXX coefs[k];
+
+ BIG_XXX secret;
+ BIG_XXX prod;
+ BIG_XXX_zero(secret);
+
+ char coefs2[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs2[i], 0, sizeof(coefs2[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs2[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ BIG_XXX_fromBytes(y[i],Y[i].val);
+ BIG_XXX_fromBytes(coefs[i],COEFS[i].val);
+ BIG_XXX_modmul(prod,y[i],coefs[i],r);
+ BIG_XXX_add(secret, secret, prod);
+
+ if (BIG_XXX_comp(secret,r) == 1)
+ {
+ BIG_XXX_sub(secret,secret,r);
+ }
+ }
+
+ // Output secret
+ BIG_XXX_toBytes(SK->val,secret);
+
+ return BLS_OK;
+}
+
+int BLS_ZZZ_RECOVER_SIGNATURE(int k, octet* X, octet* Y, octet* SIG)
+{
+ int rc = 0;
+ char product[k][BFS_ZZZ+1];
+ octet PRODUCT[k];
+
+ char coefs[k][BGS_ZZZ];
+ octet COEFS[k];
+ for(int i=0; i<k; i++)
+ {
+ memset(&coefs[i], 0, sizeof(coefs[i]));
+ COEFS[i].max = BGS_ZZZ;
+ COEFS[i].len = BGS_ZZZ;
+ COEFS[i].val = coefs[i];
+ }
+
+ rc = recover_coefficients(k, X, COEFS);
+ if (rc)
+ {
+ return rc;
+ }
+
+
+ for(int i=0; i<k; i++)
+ {
+ memset(&product[i], 0, sizeof(product[i]));
+ PRODUCT[i].max = BFS_ZZZ+1;
+ PRODUCT[i].len = BFS_ZZZ+1;
+ PRODUCT[i].val = product[i];
+ }
+
+ for(int i=0; i<k; i++)
+ {
+ rc = BLS_ZZZ_MUL_G1(&COEFS[i], &Y[i], &PRODUCT[i]);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ BLS_ZZZ_ADD_G1(&PRODUCT[0],&PRODUCT[1],SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+
+ for(int i=2; i<k; i++)
+ {
+ BLS_ZZZ_ADD_G1(&PRODUCT[i],SIG,SIG);
+ if (rc != BLS_OK)
+ {
+ return rc;
+ }
+ }
+
+ return BLS_OK;
+}
+
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9636194..c350acc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -209,6 +209,7 @@ foreach(curve ${AMCL_CURVE})
################################################
if(BUILD_BLS)
amcl_curve_test(${curve} test_bls_${TC} test_bls_ZZZ.c.in amcl_bls_${TC} "SUCCESS")
+ amcl_curve_test(${curve} test_bls_sss_${TC} test_bls_sss_ZZZ.c.in amcl_bls_${TC} "SUCCESS")
endif()
endif()
diff --git a/test/test_bls_ZZZ.c.in b/test/test_bls_ZZZ.c.in
index 92c4154..6a85fa8 100644
--- a/test/test_bls_ZZZ.c.in
+++ b/test/test_bls_ZZZ.c.in
@@ -44,7 +44,7 @@
static char message[]="test message";
-int bls(csprng *RNG)
+int test(csprng *RNG)
{
int rc;
@@ -278,8 +278,8 @@ int main()
// initialise strong RNG
CREATE_CSPRNG(&RNG,&SEED);
- printf("\nTesting BLS signature for curve ZZZ\n");
- if (!bls(&RNG))
+ printf("\nTest BLS for curve ZZZ\n");
+ if (!test(&RNG))
{
printf("SUCCESS\n");
}
diff --git a/test/test_bls_sss_ZZZ.c.in b/test/test_bls_sss_ZZZ.c.in
new file mode 100644
index 0000000..d7c6fc1
--- /dev/null
+++ b/test/test_bls_sss_ZZZ.c.in
@@ -0,0 +1,243 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+// smoke test for BLS SSS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "config_curve_ZZZ.h"
+#include "randapi.h"
+
+#if CURVE_SECURITY_ZZZ == 128
+#include "bls_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 192
+#include "bls192_ZZZ.h"
+#elif CURVE_SECURITY_ZZZ == 256
+#include "bls256_ZZZ.h"
+#endif
+
+// Support multiple security levels
+#if CURVE_SECURITY_ZZZ == 128
+#define G2LEN 4*BFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 192
+#define G2LEN 8*BFS_ZZZ
+#elif CURVE_SECURITY_ZZZ == 256
+#define G2LEN 16*BFS_ZZZ
+#endif
+
+static char message[]="test message";
+
+int test(csprng *RNG)
+{
+ int rc;
+ int n=4;
+ int k=3;
+
+ char ski[BGS_ZZZ];
+ octet SKI = {0,sizeof(ski),ski};
+ char pki[G2LEN];
+ octet PKI = {0,sizeof(pki),pki};
+
+ char sko[BGS_ZZZ];
+ octet SKO = {sizeof(sko),sizeof(sko),sko};
+ char skr[BGS_ZZZ];
+ octet SKR = {sizeof(skr),sizeof(skr),skr};
+
+ char sigi[BFS_ZZZ+1];
+ octet SIGI = {0,sizeof(sigi),sigi};
+ char sigr[BFS_ZZZ+1];
+ octet SIGR = {0,sizeof(sigr),sigr};
+
+ // Secret shares
+ char x[n][BGS_ZZZ];
+ octet X[n];
+ char y[n][BGS_ZZZ];
+ octet Y[n];
+
+ for(int i=0; i<n; i++)
+ {
+ memset(&y[i], 0, sizeof(y[i]));
+ Y[i].max = BGS_ZZZ;
+ Y[i].len = BGS_ZZZ;
+ Y[i].val = y[i];
+ memset(&x[i], 0, sizeof(x[i]));
+ X[i].max = BGS_ZZZ;
+ X[i].len = BGS_ZZZ;
+ X[i].val = x[i];
+ }
+
+ // Generate key pair
+ BLS_ZZZ_KEY_PAIR_GENERATE(RNG,&SKI,&PKI);
+
+ printf("Private key SKI: ");
+ OCT_output(&SKI);
+ printf("Public key PKI: ");
+ OCT_output(&PKI);
+ printf("\n");
+
+ // Sign the message
+ BLS_ZZZ_SIGN(&SIGI,message,&SKI);
+
+ printf("SIGI: ");
+ OCT_output(&SIGI);
+
+ // Verify signature
+ rc=BLS_ZZZ_VERIFY(&SIGI,message,&PKI);
+ if (rc!=BLS_OK)
+ {
+ printf("Test Failed Invalid Signature\n");
+ return 1;
+ }
+ printf("Test Passed valid signature is valid\n");
+
+ // Make shares of BLS secret key
+ rc = BLS_ZZZ_MAKE_SHARES(k, n, RNG, X, Y, &SKI, &SKO);
+ if (rc!=BLS_OK)
+ {
+ printf("Test Failed BLS_ZZZ_MAKE_SHARES\n");
+ return 1;
+ }
+ printf("Test Passed BLS_ZZZ_MAKE_SHARES\n");
+
+ for(int i=0; i<n; i++)
+ {
+ printf("X[%d] ", i);
+ OCT_output(&X[i]);
+ printf("Y[%d] ", i);
+ OCT_output(&Y[i]);
+ }
+
+ printf("SKO: ");
+ OCT_output(&SKO);
+
+ if (!OCT_comp(&SKI,&SKO))
+ {
+ printf("Test Failed SKI != SKO\n");
+ return 1;
+ }
+ printf("Test Passed SKI == SKO\n");
+
+ // Recover BLS secret key
+ rc = BLS_ZZZ_RECOVER_SECRET(k, X, Y, &SKR);
+ if (rc!=BLS_OK)
+ {
+ printf("Test Failed BLS_ZZZ_RECOVER_SECRET\n");
+ return 1;
+ }
+ printf("Test Passed BLS_ZZZ_RECOVER_SECRET\n");
+ printf("SKR: ");
+ OCT_output(&SKR);
+
+ if (!OCT_comp(&SKR,&SKO))
+ {
+ printf("Test Failed SKR != SKO\n");
+ return 1;
+ }
+ printf("Test Passed SKR == SKO\n");
+
+ // Generate public keys and signatures using shares
+ char pks[n][G2LEN];
+ octet PKS[n];
+ char sigs[n][BFS_ZZZ+1];
+ octet SIGS[n];
+ for(int i=0; i<n; i++)
+ {
+ memset(&sigs[i], 0, sizeof(sigs[i]));
+ SIGS[i].max = BFS_ZZZ+1;
+ SIGS[i].len = BFS_ZZZ+1;
+ SIGS[i].val = sigs[i];
+ memset(&PKS[i], 0, sizeof(PKS[i]));
+ PKS[i].max = G2LEN;
+ PKS[i].len = G2LEN;
+ PKS[i].val = pks[i];
+ BLS_ZZZ_KEY_PAIR_GENERATE(NULL,&Y[i],&PKS[i]);
+ BLS_ZZZ_SIGN(&SIGS[i],message,&Y[i]);
+ }
+
+ for(int i=0; i<n; i++)
+ {
+ printf("PKS[%d] ", i);
+ OCT_output(&PKS[i]);
+ }
+
+ for(int i=0; i<n; i++)
+ {
+ printf("SIGS[%d] ", i);
+ OCT_output(&SIGS[i]);
+ }
+ printf("\n\n");
+
+ // Recover BLS signature
+ rc = BLS_ZZZ_RECOVER_SIGNATURE(k, X, SIGS, &SIGR);
+ if (rc!=BLS_OK)
+ {
+ printf("Test Failed BLS_ZZZ_RECOVER_SIGNATURE\n");
+ return 1;
+ }
+ printf("Test Passed BLS_ZZZ_RECOVER_SIGNATURE\n");
+ printf("SIGR: ");
+ OCT_output(&SIGR);
+
+ if (!OCT_comp(&SIGR,&SIGI))
+ {
+ printf("Test Failed SIGR != SIGI\n");
+ return 1;
+ }
+ printf("Test Passed SIGR == SIGI\n");
+
+ return 0;
+}
+
+
+int main()
+{
+#ifdef DEBUG
+ printf("%d bit build\n",CHUNK);
+#endif
+
+ char* seedHex = "78d0fb6705ce77dee47d03eb5b9c5d30";
+ char seed[16] = {0};
+ octet SEED = {sizeof(seed),sizeof(seed),seed};
+
+ // CSPRNG
+ csprng RNG;
+
+ // fake random source
+ OCT_fromHex(&SEED,seedHex);
+ printf("SEED: ");
+ OCT_output(&SEED);
+
+ // initialise strong RNG
+ CREATE_CSPRNG(&RNG,&SEED);
+
+ printf("\nTest BLS SSS for curve ZZZ\n");
+ if (!test(&RNG))
+ {
+ printf("SUCCESS\n");
+ }
+ else
+ {
+ printf("FAILURE\n");
+ }
+
+ KILL_CSPRNG(&RNG);
+}
+
+