From: Christoph Egger Date: Thu, 16 Jan 2020 22:39:09 +0000 (+0100) Subject: Fixes for actually working with multi-authorities, non-trivial threshold X-Git-Url: https://git.siccegge.de//index.cgi?p=software%2FDIPE.git;a=commitdiff_plain;h=1456d1c666d403b51244d39bde73e8b4a129695a Fixes for actually working with multi-authorities, non-trivial threshold --- diff --git a/include/DIPE.h b/include/DIPE.h index a983fc2..651cf36 100644 --- a/include/DIPE.h +++ b/include/DIPE.h @@ -15,7 +15,7 @@ extern "C" { void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, const char* cid, element_t* y, dipe_secretkey_t* sk); void dipe_encrypt(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* mpk, size_t threshold, element_t* x, size_t ptxt_len, char* ptxt, size_t ctxt_len, char* ctxt); - size_t dipe_decrypt(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, const char* cid, element_t* y, size_t ctxt_len, char* ctxt, char* ptxt); + size_t dipe_decrypt(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, size_t sharecount, const char* cid, element_t* y, size_t ctxt_len, char* ctxt, char* ptxt); size_t dipe_ciphertext_overhead(dipe_param_t param, size_t dimension, size_t shares); void dipe_encap(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* mpk, size_t threshold, element_t* x, diff --git a/src/DIPE.cxx b/src/DIPE.cxx index 7b13147..c593ae0 100644 --- a/src/DIPE.cxx +++ b/src/DIPE.cxx @@ -272,9 +272,6 @@ void dipe_encap(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* mp } element_t tmp; - for (size_t i = 0; i < (*ctxt)->sharecount; ++i) { - element_init_G1((*ctxt)->cx[i], param->pairing); - } element_init_G1(tmp, param->pairing); dipe_ss_share(param, mpkcount, aid, (*ctxt)->sharecount, faid, (*ctxt)->dimension, kshares, (*ctxt)->cx, kdummyshares); @@ -341,7 +338,6 @@ void dipe_decap(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, const element_set1(innerp); for (size_t j = 0; j < sk[0]->dimension; ++j) { element_pow_zn(hy, h, y[j]); - element_printf("%B %B\n", ctxt->shares[i].cx[j], hy); pairing_apply(tmp, ctxt->shares[i].cx[j], hy, param->pairing); element_mul(innerp, innerp, tmp); } @@ -395,14 +391,14 @@ void dipe_encrypt(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* element_clear(key); } -size_t dipe_decrypt(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, const char* cid, element_t* y, size_t ctxt_len, char* ctxt, char* ptxt) { +size_t dipe_decrypt(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, size_t sharecount, const char* cid, element_t* y, size_t ctxt_len, char* ctxt, char* ptxt) { dipe_ctxt_t cap; uint8_t aes[32]; element_t key; size_t cap_len; element_init_GT(key, param->pairing); - cap_len = dipe_deserialize_ctxt(param, sk[0]->dimension, 0, &cap, (uint8_t*)ctxt); + cap_len = dipe_deserialize_ctxt(param, sk[0]->dimension, sharecount, &cap, (uint8_t*)ctxt); ctxt += cap_len; ctxt_len -= cap_len; dipe_decap(param, skcount, sk, cid, y, cap, key); @@ -486,6 +482,18 @@ size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, size_t shares buffer += element_length_in_bytes((*ctxt)->shares[j].aid); bytes_read += element_length_in_bytes((*ctxt)->shares[j].aid); + (*ctxt)->shares[j].cx = (element_t*)calloc(dimension, sizeof(element_t)); + for (size_t i = 0; i < dimension; ++i) { + element_init_G1((*ctxt)->shares[j].cx[i], param->pairing); + element_from_bytes_compressed((*ctxt)->shares[j].cx[i], buffer); + buffer += element_length_in_bytes_compressed((*ctxt)->shares[j].cx[i]); + bytes_read += element_length_in_bytes_compressed((*ctxt)->shares[j].cx[i]); + } + + element_init_GT((*ctxt)->shares[j].c, param->pairing); + element_from_bytes((*ctxt)->shares[j].c, buffer); + buffer += element_length_in_bytes((*ctxt)->shares[j].c); + bytes_read += element_length_in_bytes((*ctxt)->shares[j].c); } return bytes_read; @@ -508,6 +516,11 @@ size_t dipe_ciphertext_overhead(dipe_param_t param, size_t dimension, size_t sha overhead += (1+shares) * element_length_in_bytes(t); element_clear(t); + /* aid */ + element_init_Zr(t, param->pairing); + overhead += shares * element_length_in_bytes(t); + element_clear(t); + return overhead; } @@ -557,6 +570,7 @@ void dipe_free_ctxt(dipe_ctxt_t ctxt) { element_clear(ctxt->shares[i].cx[j]); } element_clear(ctxt->shares[i].c); + element_clear(ctxt->shares[i].aid); free(ctxt->shares[i].cx); } free(ctxt->shares); diff --git a/tests/testDIPE.cpp b/tests/testDIPE.cpp index 0c8e155..a436c24 100644 --- a/tests/testDIPE.cpp +++ b/tests/testDIPE.cpp @@ -206,7 +206,7 @@ TEST(DipeTest, DipeDecryptSuccessSmall) { memcpy(ptxt, "test", 4); dipe_encrypt(param, 1, &pk, 1, x, 4, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 4) { EXPECT_EQ(ptxt_len, 4); @@ -262,7 +262,7 @@ TEST(DipeTest, DipeDecryptSuccessTightSmall) { memcpy(ptxt, "test", 4); dipe_encrypt(param, 1, &pk, 1, x, 4, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 4) { EXPECT_EQ(ptxt_len, 4); @@ -318,7 +318,7 @@ TEST(DipeTest, DipeDecryptSuccessLargeBlocksize) { memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28); dipe_encrypt(param, 1, &pk, 1, x, 28, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 28) { EXPECT_EQ(ptxt_len, 28); @@ -375,7 +375,7 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeBlocksize) { memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28); dipe_encrypt(param, 1, &pk, 1, x, 28, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 28) { EXPECT_EQ(ptxt_len, 28); @@ -431,7 +431,7 @@ TEST(DipeTest, DipeDecryptSuccessLargeNonBlocksize) { memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35); dipe_encrypt(param, 1, &pk, 1, x, 35, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 35) { EXPECT_EQ(ptxt_len, 35); @@ -488,7 +488,7 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeNonBlocksize) { memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35); dipe_encrypt(param, 1, &pk, 1, x, 35, ptxt, clen, ctxt); - ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt); + ptxt_len = dipe_decrypt(param, 1, &sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); if (clen >= overhead + 35) { EXPECT_EQ(ptxt_len, 35); @@ -509,6 +509,130 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeNonBlocksize) { dipe_free_secretkey(sk); } +TEST(DipeTest, DipeDecryptSuccessMultiKey) { + size_t ptxt_len; + size_t overhead; + dipe_master_publickey_t pk[3]; + dipe_master_secretkey_t msk[3]; + dipe_secretkey_t sk[3]; + + element_t y[6]; + element_t x[6]; + + for (size_t i = 0; i < 6; i+=2) { + element_init_Zr(y[i], *dipe_get_pairing(param)); + element_init_Zr(x[i], *dipe_get_pairing(param)); + element_init_Zr(y[i+1], *dipe_get_pairing(param)); + element_init_Zr(x[i+1], *dipe_get_pairing(param)); + + element_set1(y[i]); + element_set1(x[i+1]); + element_random(y[i+1]); + element_neg(x[i], y[i+1]); + } + + for (size_t i = 0; i < 3; ++i) { + dipe_master_keygen(param, 6, &pk[i], &msk[i]); + dipe_keygen(param, msk[i], "1234567890abcdef", y, &sk[i]); + } + overhead = dipe_ciphertext_overhead(param, 6, 0); + + char ctxt[overhead + 35]; + char ptxt[overhead + 35]; + + + for (size_t clen = overhead; clen <= overhead + 35; ++clen) { + memset(ctxt, 0, overhead + 35); + memset(ptxt, 0, overhead + 35); + memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35); + + dipe_encrypt(param, 3, pk, 3, x, 35, ptxt, clen, ctxt); + ptxt_len = dipe_decrypt(param, 3, sk, 0, "1234567890abcdef", y, clen, ctxt, ptxt); + + if (clen >= overhead + 35) { + EXPECT_EQ(ptxt_len, 35); + EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc"); + } + else { + EXPECT_EQ(ptxt_len, 0); + } + } + + for (size_t i = 0; i < 6; ++i) { + element_clear(y[i]); + element_clear(x[i]); + } + + for (size_t i = 0; i < 3; ++i) { + dipe_free_master_secretkey(msk[i]); + dipe_free_master_publickey(pk[i]); + dipe_free_secretkey(sk[i]); + } +} + +TEST(DipeTest, DipeDecryptSuccessThreshold) { + size_t ptxt_len; + size_t overhead; + dipe_master_publickey_t pk[3]; + dipe_master_secretkey_t msk[3]; + dipe_secretkey_t sk[3]; + + element_t y[6]; + element_t x[6]; + + for (size_t i = 0; i < 6; i+=2) { + element_init_Zr(y[i], *dipe_get_pairing(param)); + element_init_Zr(x[i], *dipe_get_pairing(param)); + element_init_Zr(y[i+1], *dipe_get_pairing(param)); + element_init_Zr(x[i+1], *dipe_get_pairing(param)); + + element_set1(y[i]); + element_set1(x[i+1]); + element_random(y[i+1]); + element_neg(x[i], y[i+1]); + } + + for (size_t i = 0; i < 3; ++i) { + dipe_master_keygen(param, 6, &pk[i], &msk[i]); + dipe_keygen(param, msk[i], "1234567890abcdef", y, &sk[i]); + } + overhead = dipe_ciphertext_overhead(param, 6, 2); + + char ctxt[overhead + 35]; + char ptxt[overhead + 35]; + + + for (size_t clen = overhead+20; clen <= overhead + 35; ++clen) { + for (size_t kid = 0; kid < 3; ++kid) { + memset(ctxt, 0, overhead + 35); + memset(ptxt, 0, overhead + 35); + memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35); + + dipe_encrypt(param, 3, pk, 1, x, 35, ptxt, clen, ctxt); + ptxt_len = dipe_decrypt(param, 1, &sk[kid], 2, "1234567890abcdef", y, clen, ctxt, ptxt); + + if (clen >= overhead + 35) { + EXPECT_EQ(ptxt_len, 35); + EXPECT_STREQ(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc"); + } + else { + EXPECT_EQ(ptxt_len, 0); + } + } + } + + for (size_t i = 0; i < 6; ++i) { + element_clear(y[i]); + element_clear(x[i]); + } + + for (size_t i = 0; i < 3; ++i) { + dipe_free_master_secretkey(msk[i]); + dipe_free_master_publickey(pk[i]); + dipe_free_secretkey(sk[i]); + } +} +