]> git.siccegge.de Git - software/DIPE.git/commitdiff
integrate secret sharing
authorChristoph Egger <christoph@christoph-egger.org>
Thu, 16 Jan 2020 21:45:08 +0000 (22:45 +0100)
committerChristoph Egger <christoph@christoph-egger.org>
Thu, 16 Jan 2020 21:45:08 +0000 (22:45 +0100)
include/DIPE.h
src/DIPE.cxx
src/DIPE_Internal.h
src/SS.cxx
tests/testDIPE.cpp
tests/testSS.cpp

index b9889afe33b94dce902315935e2f2c62761eae07..a983fc2f7cde4ce9d1ac064bcf4c480dc606dde8 100644 (file)
@@ -12,21 +12,23 @@ extern "C" {
        pairing_t* dipe_get_pairing(dipe_param_t param);
 
        void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_publickey_t* pk, dipe_master_secretkey_t* sk);
        pairing_t* dipe_get_pairing(dipe_param_t param);
 
        void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_publickey_t* pk, dipe_master_secretkey_t* sk);
-       void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, element_t* y, dipe_secretkey_t* sk);
+       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, dipe_master_publickey_t mpk, element_t* x, size_t ptxt_len, char* ptxt, size_t ctxt_len, char* ctxt);
-       size_t dipe_decrypt(dipe_param_t param, dipe_secretkey_t sk, 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);
+       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_ciphertext_overhead(dipe_param_t param, size_t dimension, size_t shares);
 
 
-       void dipe_encap(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt);
-       void dipe_decap(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y, dipe_ctxt_t ctxt, element_t ptxt);
+       void dipe_encap(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* mpk, size_t threshold, element_t* x,
+                       element_t ptxt, dipe_ctxt_t* ctxt);
+       void dipe_decap(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, const char* cid, element_t* y,
+                       dipe_ctxt_t ctxt, element_t ptxt);
 
 
-       void dipe_ss_share(dipe_param_t param, size_t id_size, element_t* ids, size_t fid_size, element_t* fake_ids, size_t share_size, element_t** shares,
-                          element_t* secret, element_t** dummy_shares);
+       void dipe_ss_share(dipe_param_t param, size_t id_size, element_t* ids, size_t fid_size, element_t* fake_ids,
+                          size_t share_size, element_t** shares, element_t* secret, element_t** dummy_shares);
        void dipe_ss_recover(dipe_param_t param, size_t id_size, element_t* ids, size_t share_size, element_t** shares, element_t* secret);
 
        size_t dipe_serialize_ctxt(dipe_param_t param, dipe_ctxt_t ctxt, uint8_t* buffer);
        void dipe_ss_recover(dipe_param_t param, size_t id_size, element_t* ids, size_t share_size, element_t** shares, element_t* secret);
 
        size_t dipe_serialize_ctxt(dipe_param_t param, dipe_ctxt_t ctxt, uint8_t* buffer);
-       size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, dipe_ctxt_t* ctxt, uint8_t* buffer);
+       size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, size_t shares, dipe_ctxt_t* ctxt, uint8_t* buffer);
        
        void dipe_free_param(dipe_param_t param);
        void dipe_free_master_secretkey(dipe_master_secretkey_t sk);
        
        void dipe_free_param(dipe_param_t param);
        void dipe_free_master_secretkey(dipe_master_secretkey_t sk);
index 9b8c91ec52c9f8495aa8f178072fd672674e9ec0..7b13147966a7df39b24919bd023fe018f3ed5380 100644 (file)
@@ -21,7 +21,7 @@ namespace {
                return 16 /*cid*/ + dimension * element_length_in_bytes(elem);
        }
 
                return 16 /*cid*/ + dimension * element_length_in_bytes(elem);
        }
 
-       void dipe_generate_h(char* cid, element_t* y, size_t dimension, unsigned char* result) {
+       void dipe_generate_h(const char* cid, element_t* y, size_t dimension, unsigned char* result) {
                memcpy(result, cid, 16);
                unsigned char* next_element = result+16;
                for (size_t i = 0; i < dimension; ++i) {
                memcpy(result, cid, 16);
                unsigned char* next_element = result+16;
                for (size_t i = 0; i < dimension; ++i) {
@@ -56,7 +56,7 @@ namespace {
 
                ctxt_len -= 16; /* Tag */
                if (ctxt_len < ptxt_len + 4) return 0;
 
                ctxt_len -= 16; /* Tag */
                if (ctxt_len < ptxt_len + 4) return 0;
-               
+
                memset(block, 0, 16);
                gcm_aes128_set_key(&ctx, key);
                gcm_aes128_set_iv(&ctx, 12, iv);
                memset(block, 0, 16);
                gcm_aes128_set_key(&ctx, key);
                gcm_aes128_set_iv(&ctx, 12, iv);
@@ -67,7 +67,7 @@ namespace {
                memcpy(block+4, ptxt, min((size_t)12, ptxt_len));
                ptxt_len -= min((size_t)12, ptxt_len);
                ptxt += 12;
                memcpy(block+4, ptxt, min((size_t)12, ptxt_len));
                ptxt_len -= min((size_t)12, ptxt_len);
                ptxt += 12;
-               
+
                while (ctxt_len >= 16) {
                        gcm_aes128_encrypt(&ctx, 16, ctxt, block);
                        memset(block, 0, 16);
                while (ctxt_len >= 16) {
                        gcm_aes128_encrypt(&ctx, 16, ctxt, block);
                        memset(block, 0, 16);
@@ -80,7 +80,7 @@ namespace {
                                ptxt_len -= min((size_t)16, ptxt_len);
                        }
                }
                                ptxt_len -= min((size_t)16, ptxt_len);
                        }
                }
-               
+
                if (ctxt_len > 0) {
                        gcm_aes128_encrypt(&ctx, ctxt_len, ctxt, block);
                        ctxt += ctxt_len;
                if (ctxt_len > 0) {
                        gcm_aes128_encrypt(&ctx, ctxt_len, ctxt, block);
                        ctxt += ctxt_len;
@@ -98,7 +98,7 @@ namespace {
                gcm_aes128_set_iv(&ctx, 12, iv);
                len -= 16; /* GCM tag */
 
                gcm_aes128_set_iv(&ctx, 12, iv);
                len -= 16; /* GCM tag */
 
-               
+
                gcm_aes128_decrypt(&ctx, min((size_t)16, len), block, ctxt);
                uint32_t ptxtlen = 0;
                memcpy(&ptxtlen, block, 4);
                gcm_aes128_decrypt(&ctx, min((size_t)16, len), block, ctxt);
                uint32_t ptxtlen = 0;
                memcpy(&ptxtlen, block, 4);
@@ -113,11 +113,11 @@ namespace {
                }
                gcm_aes128_digest(&ctx, 16, block);
 
                }
                gcm_aes128_digest(&ctx, 16, block);
 
-               /* error case is with return code 0, see manual 
+               /* error case is with return code 0, see manual
                 * https://www.lysator.liu.se/~nisse/nettle/nettle.html#Miscellaneous-functions
                 */
                if (memeql_sec(ctxt, block, 16) == 0)
                 * https://www.lysator.liu.se/~nisse/nettle/nettle.html#Miscellaneous-functions
                 */
                if (memeql_sec(ctxt, block, 16) == 0)
-                       return 0; 
+                       return 0;
                else
                        return ptxtlen;
        }
                else
                        return ptxtlen;
        }
@@ -151,6 +151,10 @@ void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_public
        *sk = (dipe_master_secretkey_t)malloc(sizeof(dipe_master_secretkey));
 
        (*sk)->dimension = (*pk)->dimension = dimension;
        *sk = (dipe_master_secretkey_t)malloc(sizeof(dipe_master_secretkey));
 
        (*sk)->dimension = (*pk)->dimension = dimension;
+       element_init_Zr((*pk)->aid, param->pairing);
+       element_init_Zr((*sk)->aid, param->pairing);
+       element_random((*pk)->aid);
+       element_set((*sk)->aid, (*pk)->aid);
 
        element_init_Zr((*sk)->a, param->pairing);
        element_init_GT((*pk)->a, param->pairing);
 
        element_init_Zr((*sk)->a, param->pairing);
        element_init_GT((*pk)->a, param->pairing);
@@ -167,10 +171,12 @@ void dipe_master_keygen(dipe_param_t param, size_t dimension, dipe_master_public
        }
 }
 
        }
 }
 
-void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, element_t* y, dipe_secretkey_t* sk) {
+void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, const char* cid, element_t* y, dipe_secretkey_t* sk) {
        *sk = (dipe_secretkey_t)malloc(sizeof(dipe_secretkey));
        (*sk)->dimension = msk->dimension;
        element_init_G2((*sk)->d, param->pairing);
        *sk = (dipe_secretkey_t)malloc(sizeof(dipe_secretkey));
        (*sk)->dimension = msk->dimension;
        element_init_G2((*sk)->d, param->pairing);
+       element_init_Zr((*sk)->aid, param->pairing);
+       element_set((*sk)->aid, msk->aid);
 
        size_t hash_input_length = dipe_h_length(y[0], msk->dimension);
        unsigned char hash_input[hash_input_length];
 
        size_t hash_input_length = dipe_h_length(y[0], msk->dimension);
        unsigned char hash_input[hash_input_length];
@@ -206,58 +212,108 @@ void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, ele
        element_clear(a2);
 }
 
        element_clear(a2);
 }
 
-void dipe_encap(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt) {
+void dipe_encap(dipe_param_t param, size_t mpkcount, dipe_master_publickey_t* mpk, size_t threshold, element_t* x, element_t ptxt, dipe_ctxt_t* ctxt) {
        *ctxt = (dipe_ctxt_t)malloc(sizeof(dipe_ctxt));
        *ctxt = (dipe_ctxt_t)malloc(sizeof(dipe_ctxt));
-       (*ctxt)->dimension = mpk->dimension;
+       (*ctxt)->dimension = mpk[0]->dimension;
+       (*ctxt)->sharecount = mpkcount - threshold /*  TODO */;
 
 
-       element_t r;
+       element_t r[(*ctxt)->sharecount];
+       element_t r0;
+       element_t faid[(*ctxt)->sharecount];
+       element_t aid[mpkcount];
        element_t s;
        element_t s;
-       element_init_Zr(r, param->pairing);
-       element_init_Zr(s, param->pairing);
 
 
-       element_random(r);
+       element_init_Zr(s, param->pairing);
        element_random(s);
        element_random(s);
+       element_init_Zr(r0, param->pairing);
+       element_random(r0);
 
        element_init_G1((*ctxt)->s, param->pairing);
        element_pow_zn((*ctxt)->s, param->g1, s);
 
 
        element_init_G1((*ctxt)->s, param->pairing);
        element_pow_zn((*ctxt)->s, param->g1, s);
 
-       element_t k1;
-       element_t x1;
-       element_init_G1(k1, param->pairing);
-       element_init_G1(x1, param->pairing);
+       (*ctxt)->cx = (element_t*)calloc((*ctxt)->dimension, sizeof(element_t));
+       (*ctxt)->shares = (struct dipe_ctxt_share*)calloc((*ctxt)->sharecount, sizeof(struct dipe_ctxt_share));
+       for (size_t i = 0; i < (*ctxt)->sharecount; ++i) {
+               element_init_Zr((*ctxt)->shares[i].aid, param->pairing);
+               element_init_Zr(faid[i], param->pairing);
+               element_random((*ctxt)->shares[i].aid);
+               element_set(faid[i], (*ctxt)->shares[i].aid);
+
+               element_init_Zr(r[i], param->pairing);
+               element_random(r[i]);
+       }
 
 
-       (*ctxt)->cx = (element_t*)calloc(mpk->dimension, sizeof(element_t));
-       for (size_t i = 0; i < mpk->dimension; ++i){
-               element_pow_zn(x1, param->g1, x[i]);
-               element_pow_zn(x1, x1, r);
+       element_t* ashares[mpkcount];
+       for (size_t i = 0; i < mpkcount; ++i) {
+               ashares[i] = &(mpk[i]->a);
+               element_init_Zr(aid[i], param->pairing);
+               element_set(aid[i], mpk[i]->aid);
+       }
+       element_t* adummyshares[(*ctxt)->sharecount];
+       for (size_t i  = 0; i < (*ctxt)->sharecount; ++i) {
+               adummyshares[i] = &((*ctxt)->shares[i].c);
+       }
+       dipe_ss_share(param, mpkcount, aid, (*ctxt)->sharecount, faid, 1, ashares, &((*ctxt)->c), adummyshares);
 
 
-               element_pow_zn(k1, mpk->k[i], s);
+       for (size_t i  = 0; i < (*ctxt)->sharecount; ++i) {
+               element_pow_zn((*ctxt)->shares[i].c, (*ctxt)->shares[i].c, s);
+       }
+       element_pow_zn((*ctxt)->c, (*ctxt)->c, s);
+       element_mul((*ctxt)->c, (*ctxt)->c, ptxt);
 
 
+
+       element_t* kshares[mpkcount];
+       for (size_t i = 0; i < mpkcount; ++i) {
+               kshares[i] = mpk[i]->k;
+       }
+       element_t* kdummyshares[(*ctxt)->sharecount];
+       for (size_t i  = 0; i < (*ctxt)->sharecount; ++i) {
+               kdummyshares[i] = (*ctxt)->shares[i].cx = (element_t*)calloc((*ctxt)->dimension, sizeof(element_t));
+       }
+
+       element_t tmp;
+       for (size_t i = 0; i < (*ctxt)->sharecount; ++i) {
                element_init_G1((*ctxt)->cx[i], param->pairing);
                element_init_G1((*ctxt)->cx[i], param->pairing);
-               element_mul((*ctxt)->cx[i], k1, x1);
+       }
+       element_init_G1(tmp, param->pairing);
+       dipe_ss_share(param, mpkcount, aid, (*ctxt)->sharecount, faid, (*ctxt)->dimension, kshares, (*ctxt)->cx, kdummyshares);
+
+       for (size_t i = 0; i < (*ctxt)->sharecount; ++i) {
+               for (size_t j = 0; j < (*ctxt)->dimension; ++j) {
+                       element_pow_zn((*ctxt)->shares[i].cx[j], (*ctxt)->shares[i].cx[j], s);
+                       element_pow_zn(tmp, param->g1, x[j]);
+                       element_pow_zn(tmp, tmp, r[i]);
+                       element_mul((*ctxt)->shares[i].cx[j], (*ctxt)->shares[i].cx[j], tmp);
+               }
+       }
+       for (size_t j = 0; j < (*ctxt)->dimension; ++j) {
+               element_pow_zn((*ctxt)->cx[j], (*ctxt)->cx[j], s);
+               element_pow_zn(tmp, param->g1, x[j]);
+               element_pow_zn(tmp, tmp, r0);
+               element_mul((*ctxt)->cx[j], (*ctxt)->cx[j], tmp);
        }
 
        }
 
-       element_t at;
-       element_init_GT(at, param->pairing);
-       element_pow_zn(at, mpk->a, s);
-       element_init_GT((*ctxt)->c, param->pairing);
-       element_mul((*ctxt)->c, at, ptxt);
 
 
-       element_clear(r);
+       for (size_t i = 0; i < (*ctxt)->sharecount; ++i) {
+               element_clear(r[i]);
+               element_clear(faid[i]);
+       }
+       for (size_t i = 0; i < mpkcount; ++i) {
+               element_clear(aid[i]);
+       }
+       element_clear(r0);
        element_clear(s);
        element_clear(s);
-       element_clear(k1);
-       element_clear(x1);
-       element_clear(at);
+       element_clear(tmp);
 }
 
 
 }
 
 
-void dipe_decap(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y, dipe_ctxt_t ctxt, element_t ptxt) {
-       size_t hash_input_length = dipe_h_length(y[0], sk->dimension);
+void dipe_decap(dipe_param_t param, size_t skcount, dipe_secretkey_t* sk, const char* cid, element_t* y, dipe_ctxt_t ctxt, element_t ptxt) {
+       size_t hash_input_length = dipe_h_length(y[0], sk[0]->dimension);
        unsigned char hash_input[hash_input_length];
        element_t h;
        element_init_G2(h, param->pairing);
 
        unsigned char hash_input[hash_input_length];
        element_t h;
        element_init_G2(h, param->pairing);
 
-       dipe_generate_h(cid, y, sk->dimension, hash_input);
+       dipe_generate_h(cid, y, sk[0]->dimension, hash_input);
        element_from_hash(h, hash_input, hash_input_length);
 
        element_t tmp;
        element_from_hash(h, hash_input, hash_input_length);
 
        element_t tmp;
@@ -267,17 +323,52 @@ void dipe_decap(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y
        element_init_GT(innerp, param->pairing);
        element_init_G2(hy, param->pairing);
 
        element_init_GT(innerp, param->pairing);
        element_init_G2(hy, param->pairing);
 
+       element_t aid[skcount + ctxt->sharecount];
+       element_t* beta[skcount + ctxt->sharecount];
+       for (size_t i = 0; i < skcount; ++i) {
+               beta[i] = (element_t*)calloc(1, sizeof(element_t));
+               element_init_GT(*(beta[i]), param->pairing);
+               element_init_Zr(aid[i], param->pairing);
+               element_set(aid[i], sk[i]->aid);
+               pairing_apply(*(beta[i]), ctxt->s, sk[i]->d, param->pairing);
+       }
+       for (size_t i = 0; i < ctxt->sharecount; ++i) {
+               beta[skcount+i] = (element_t*)calloc(1, sizeof(element_t));
+               element_init_GT(*(beta[skcount+i]), param->pairing);
+               element_init_Zr(aid[skcount+i], param->pairing);
+               element_set(aid[skcount+i], ctxt->shares[i].aid);
+
+               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);
+               }
+               element_mul(*(beta[skcount+i]), ctxt->shares[i].c, innerp);
+       }
+
+       element_t recover[1];
+       dipe_ss_recover(param, skcount + ctxt->sharecount, aid, 1, beta, recover);
+       element_set(ptxt, recover[0]);
+       element_clear(recover[0]);
+
        element_set1(innerp);
        element_set1(innerp);
-       for (size_t i = 0; i < sk->dimension; ++i) {
+       for (size_t i = 0; i < sk[0]->dimension; ++i) {
                element_pow_zn(hy, h, y[i]);
                pairing_apply(tmp, ctxt->cx[i], hy, param->pairing);
                element_mul(innerp, innerp, tmp);
        }
 
                element_pow_zn(hy, h, y[i]);
                pairing_apply(tmp, ctxt->cx[i], hy, param->pairing);
                element_mul(innerp, innerp, tmp);
        }
 
-       pairing_apply(ptxt, ctxt->s, sk->d, param->pairing);
        element_invert(ptxt, ptxt);
        element_mul(ptxt, ptxt, ctxt->c);
        element_invert(ptxt, ptxt);
        element_mul(ptxt, ptxt, ctxt->c);
-       element_mul(ptxt, ptxt, innerp);
+       element_mul(ptxt, ptxt, innerp); /* innerp */
+
+       for (size_t i = 0; i < skcount + ctxt->sharecount; ++i) {
+               element_clear(aid[i]);
+               element_clear(*(beta[i]));
+               free(beta[i]);
+       }
 
        element_clear(h);
        element_clear(tmp);
 
        element_clear(h);
        element_clear(tmp);
@@ -285,7 +376,7 @@ void dipe_decap(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y
        element_clear(hy);
 }
 
        element_clear(hy);
 }
 
-void dipe_encrypt(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x, size_t ptxt_len, char* ptxt, size_t ctxt_len, char* ctxt) {
+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) {
        element_t key;
        uint8_t aes[32];
        dipe_ctxt_t cap;
        element_t key;
        uint8_t aes[32];
        dipe_ctxt_t cap;
@@ -294,27 +385,27 @@ void dipe_encrypt(dipe_param_t param, dipe_master_publickey_t mpk, element_t* x,
        element_init_GT(key, param->pairing);
        element_random(key);
        dipe_generate_aeskey(key, aes);
        element_init_GT(key, param->pairing);
        element_random(key);
        dipe_generate_aeskey(key, aes);
-       dipe_encap(param, mpk, x, key, &cap);
+       dipe_encap(param, mpkcount, mpk, threshold, x, key, &cap);
        cap_len = dipe_serialize_ctxt(param, cap, (uint8_t*)ctxt);
        ctxt += cap_len; ctxt_len -= cap_len;
        cap_len = dipe_serialize_ctxt(param, cap, (uint8_t*)ctxt);
        ctxt += cap_len; ctxt_len -= cap_len;
-       
+
        dipe_aes_encrypt(aes, aes+16, ptxt_len, (uint8_t*)ptxt, ctxt_len, (uint8_t*)ctxt);
 
        dipe_free_ctxt(cap);
        element_clear(key);
 }
 
        dipe_aes_encrypt(aes, aes+16, ptxt_len, (uint8_t*)ptxt, ctxt_len, (uint8_t*)ctxt);
 
        dipe_free_ctxt(cap);
        element_clear(key);
 }
 
-size_t dipe_decrypt(dipe_param_t param, dipe_secretkey_t sk, 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, 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;
        dipe_ctxt_t cap;
        uint8_t aes[32];
        element_t key;
        size_t cap_len;
-       
+
        element_init_GT(key, param->pairing);
        element_init_GT(key, param->pairing);
-       cap_len = dipe_deserialize_ctxt(param, sk->dimension, &cap, (uint8_t*)ctxt);
+       cap_len = dipe_deserialize_ctxt(param, sk[0]->dimension, 0, &cap, (uint8_t*)ctxt);
        ctxt += cap_len;
        ctxt_len -= cap_len;
        ctxt += cap_len;
        ctxt_len -= cap_len;
-       dipe_decap(param, sk, cid, y, cap, key);
+       dipe_decap(param, skcount, sk, cid, y, cap, key);
        dipe_generate_aeskey(key, aes);
 
        dipe_free_ctxt(cap);
        dipe_generate_aeskey(key, aes);
 
        dipe_free_ctxt(cap);
@@ -333,7 +424,7 @@ size_t dipe_serialize_ctxt(__attribute__((unused)) dipe_param_t param, dipe_ctxt
        element_to_bytes_compressed(buffer, ctxt->s);
        buffer += element_length_in_bytes_compressed(ctxt->s);
        bytes_written += element_length_in_bytes_compressed(ctxt->s);
        element_to_bytes_compressed(buffer, ctxt->s);
        buffer += element_length_in_bytes_compressed(ctxt->s);
        bytes_written += element_length_in_bytes_compressed(ctxt->s);
-       
+
        for (size_t i = 0; i < ctxt->dimension; ++i) {
                element_to_bytes_compressed(buffer, ctxt->cx[i]);
                buffer += element_length_in_bytes_compressed(ctxt->cx[i]);
        for (size_t i = 0; i < ctxt->dimension; ++i) {
                element_to_bytes_compressed(buffer, ctxt->cx[i]);
                buffer += element_length_in_bytes_compressed(ctxt->cx[i]);
@@ -343,14 +434,31 @@ size_t dipe_serialize_ctxt(__attribute__((unused)) dipe_param_t param, dipe_ctxt
        element_to_bytes(buffer, ctxt->c);
        buffer += element_length_in_bytes(ctxt->c);
        bytes_written += element_length_in_bytes(ctxt->c);
        element_to_bytes(buffer, ctxt->c);
        buffer += element_length_in_bytes(ctxt->c);
        bytes_written += element_length_in_bytes(ctxt->c);
-       
+
+       for (size_t j = 0; j < ctxt->sharecount; ++j) {
+               element_to_bytes(buffer, ctxt->shares[j].aid);
+               buffer += element_length_in_bytes(ctxt->shares[j].aid);
+               bytes_written += element_length_in_bytes(ctxt->shares[j].aid);
+
+               for (size_t i = 0; i < ctxt->dimension; ++i) {
+                       element_to_bytes_compressed(buffer, ctxt->shares[j].cx[i]);
+                       buffer += element_length_in_bytes_compressed(ctxt->shares[j].cx[i]);
+                       bytes_written += element_length_in_bytes_compressed(ctxt->shares[j].cx[i]);
+               }
+
+               element_to_bytes(buffer, ctxt->shares[j].c);
+               buffer += element_length_in_bytes(ctxt->shares[j].c);
+               bytes_written += element_length_in_bytes(ctxt->shares[j].c);
+       }
+
        return bytes_written;
 }
 
        return bytes_written;
 }
 
-size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, dipe_ctxt_t* ctxt, uint8_t* buffer) {
+size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, size_t shares, dipe_ctxt_t* ctxt, uint8_t* buffer) {
        size_t bytes_read = 0;
        *ctxt = (dipe_ctxt_t)malloc(sizeof(dipe_ctxt));
        (*ctxt)->dimension = dimension;
        size_t bytes_read = 0;
        *ctxt = (dipe_ctxt_t)malloc(sizeof(dipe_ctxt));
        (*ctxt)->dimension = dimension;
+       (*ctxt)->sharecount = shares;
 
        element_init_G1((*ctxt)->s, param->pairing);
        element_from_bytes_compressed((*ctxt)->s, buffer);
 
        element_init_G1((*ctxt)->s, param->pairing);
        element_from_bytes_compressed((*ctxt)->s, buffer);
@@ -369,20 +477,35 @@ size_t dipe_deserialize_ctxt(dipe_param_t param, size_t dimension, dipe_ctxt_t*
        element_from_bytes((*ctxt)->c, buffer);
        buffer += element_length_in_bytes((*ctxt)->c);
        bytes_read += element_length_in_bytes((*ctxt)->c);
        element_from_bytes((*ctxt)->c, buffer);
        buffer += element_length_in_bytes((*ctxt)->c);
        bytes_read += element_length_in_bytes((*ctxt)->c);
-       
+
+
+       (*ctxt)->shares = (struct dipe_ctxt_share*)calloc(shares, sizeof(struct dipe_ctxt_share));
+       for (size_t j = 0; j < shares; ++j) {
+               element_init_Zr((*ctxt)->shares[j].aid, param->pairing);
+               element_from_bytes((*ctxt)->shares[j].aid, buffer);
+               buffer += element_length_in_bytes((*ctxt)->shares[j].aid);
+               bytes_read += element_length_in_bytes((*ctxt)->shares[j].aid);
+
+       }
+
        return bytes_read;
 }
 
        return bytes_read;
 }
 
-size_t dipe_ciphertext_overhead(dipe_param_t param, size_t dimension) {
+size_t dipe_ciphertext_overhead(dipe_param_t param, size_t dimension, size_t shares) {
        size_t overhead = 16 + 4 /* IV + Tag + Size */;
        element_t t;
 
        size_t overhead = 16 + 4 /* IV + Tag + Size */;
        element_t t;
 
+       /* s */
        element_init_G1(t, param->pairing);
        overhead += element_length_in_bytes_compressed(t);
        element_init_G1(t, param->pairing);
        overhead += element_length_in_bytes_compressed(t);
-       overhead += dimension * element_length_in_bytes_compressed(t);
+
+       /* cx */
+       overhead += (1+shares) * dimension * element_length_in_bytes_compressed(t);
        element_clear(t);
        element_clear(t);
+
+       /* c */
        element_init_GT(t, param->pairing);
        element_init_GT(t, param->pairing);
-       overhead += element_length_in_bytes(t);
+       overhead += (1+shares) * element_length_in_bytes(t);
        element_clear(t);
 
        return overhead;
        element_clear(t);
 
        return overhead;
@@ -402,6 +525,7 @@ void dipe_free_master_secretkey(dipe_master_secretkey_t sk) {
        }
        element_clear(sk->a);
        free(sk->k);
        }
        element_clear(sk->a);
        free(sk->k);
+       element_clear(sk->aid);
        free(sk);
 }
 
        free(sk);
 }
 
@@ -411,20 +535,32 @@ void dipe_free_master_publickey(dipe_master_publickey_t pk) {
        }
        element_clear(pk->a);
        free(pk->k);
        }
        element_clear(pk->a);
        free(pk->k);
+       element_clear(pk->aid);
        free(pk);
 }
 
 void dipe_free_secretkey(dipe_secretkey_t sk) {
        element_clear(sk->d);
        free(pk);
 }
 
 void dipe_free_secretkey(dipe_secretkey_t sk) {
        element_clear(sk->d);
+       element_clear(sk->aid);
        free(sk);
 }
 
 void dipe_free_ctxt(dipe_ctxt_t ctxt) {
        free(sk);
 }
 
 void dipe_free_ctxt(dipe_ctxt_t ctxt) {
-       for (size_t i = 0; i < ctxt->dimension; ++i) {
-               element_clear(ctxt->cx[i]);
+       for (size_t j = 0; j < ctxt->dimension; ++j) {
+               element_clear(ctxt->cx[j]);
        }
        element_clear(ctxt->c);
        }
        element_clear(ctxt->c);
-       element_clear(ctxt->s);
        free(ctxt->cx);
        free(ctxt->cx);
+
+       for (size_t i = 0; i < ctxt->sharecount; ++i) {
+               for (size_t j = 0; j < ctxt->dimension; ++j) {
+                       element_clear(ctxt->shares[i].cx[j]);
+               }
+               element_clear(ctxt->shares[i].c);
+               free(ctxt->shares[i].cx);
+       }
+       free(ctxt->shares);
+
+       element_clear(ctxt->s);
        free(ctxt);
 }
        free(ctxt);
 }
index 521c2d61681e0839416df375b6648f00d427a7cc..942427fe044e6f581b255f50b98a70a606bd4674 100644 (file)
@@ -7,24 +7,35 @@ struct dipe_param {
 
 struct dipe_master_publickey {
        size_t dimension;
 
 struct dipe_master_publickey {
        size_t dimension;
+       element_t aid;
        element_t a;
        element_t* k;
 };
 
 struct dipe_master_secretkey {
        size_t dimension;
        element_t a;
        element_t* k;
 };
 
 struct dipe_master_secretkey {
        size_t dimension;
+       element_t aid;
        element_t a;
        element_t* k;
 };
 
 struct dipe_secretkey {
        size_t dimension;
        element_t a;
        element_t* k;
 };
 
 struct dipe_secretkey {
        size_t dimension;
+       element_t aid;
        element_t d;
 };
 
        element_t d;
 };
 
+struct dipe_ctxt_share {
+       element_t aid;
+       element_t* cx;
+       element_t c;
+};
+
 struct dipe_ctxt {
        size_t dimension;
        element_t s;
        element_t* cx;
        element_t c;
 struct dipe_ctxt {
        size_t dimension;
        element_t s;
        element_t* cx;
        element_t c;
+       size_t sharecount;
+       struct dipe_ctxt_share* shares;
 };
 };
index 426072b18aa21403aaa0f7e4d5dff124b6b9fc50..7fdf8277538d2a1470d128ec752c4e9e36081f30 100644 (file)
@@ -105,6 +105,7 @@ void dipe_ss_share(dipe_param_t param, size_t id_size, element_t* ids, size_t fi
 
        /* Compute Secret */
        for (size_t k = 0; k < share_size; ++k) {
 
        /* Compute Secret */
        for (size_t k = 0; k < share_size; ++k) {
+               element_init_same_as(secret[k], shares[0][0]);
                element_set1(secret[k]);
                for (size_t j = 0; j < id_size; ++j) {
                        element_pow_zn(tmp, shares[j][k], b[0][j]);
                element_set1(secret[k]);
                for (size_t j = 0; j < id_size; ++j) {
                        element_pow_zn(tmp, shares[j][k], b[0][j]);
@@ -176,6 +177,7 @@ void dipe_ss_recover(dipe_param_t param, size_t id_size, element_t* ids, size_t
 
        /* Compute Secret */
        for (size_t k = 0; k < share_size; ++k) {
 
        /* Compute Secret */
        for (size_t k = 0; k < share_size; ++k) {
+               element_init_same_as(secret[k], shares[0][0]);
                element_set1(secret[k]);
                for (size_t j = 0; j < id_size; ++j) {
                        element_pow_zn(tmp, shares[j][k], b[0][j]);
                element_set1(secret[k]);
                for (size_t j = 0; j < id_size; ++j) {
                        element_pow_zn(tmp, shares[j][k], b[0][j]);
index 782409c0f554760afd2b6349add774d6c6e2ad71..0c8e155b00234e78e1c1fb004964e3e506f81483 100644 (file)
@@ -58,8 +58,8 @@ TEST(DipeTest, DipeDecapFail) {
 
        element_random(ptxt);
 
 
        element_random(ptxt);
 
-       dipe_encap(param, pk, y, ptxt, &ctxt);
-       dipe_decap(param, sk, "1234567890abcdef", y, ctxt, ptxtp);
+       dipe_encap(param, 1, &pk, 1, y, ptxt, &ctxt);
+       dipe_decap(param, 1, &sk, "1234567890abcdef", y, ctxt, ptxtp);
 
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
 
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
@@ -97,8 +97,8 @@ TEST(DipeTest, DipeDecapTrivialSuccess) {
 
        element_random(ptxt);
 
 
        element_random(ptxt);
 
-       dipe_encap(param, pk, y, ptxt, &ctxt);
-       dipe_decap(param, sk, "1234567890abcdef", y, ctxt, ptxtp);
+       dipe_encap(param, 1, &pk, 1, y, ptxt, &ctxt);
+       dipe_decap(param, 1, &sk, "1234567890abcdef", y, ctxt, ptxtp);
 
        EXPECT_EQ(element_cmp(ptxt, ptxtp), 0);
 
 
        EXPECT_EQ(element_cmp(ptxt, ptxtp), 0);
 
@@ -145,17 +145,17 @@ TEST(DipeTest, DipeDecapSuccess) {
 
        element_random(ptxt);
 
 
        element_random(ptxt);
 
-       dipe_encap(param, pk, x, ptxt, &ctxt);
+       dipe_encap(param, 1, &pk, 1, x, ptxt, &ctxt);
 
 
-       dipe_decap(param, sk, "1234567890abcdef", y, ctxt, ptxtp);
+       dipe_decap(param, 1, &sk, "1234567890abcdef", y, ctxt, ptxtp);
        EXPECT_EQ(element_cmp(ptxt, ptxtp), 0);
 
        /* non-matching CID */
        EXPECT_EQ(element_cmp(ptxt, ptxtp), 0);
 
        /* non-matching CID */
-       dipe_decap(param, sk, "fedcba0987654321", y, ctxt, ptxtp);
+       dipe_decap(param, 1, &sk, "fedcba0987654321", y, ctxt, ptxtp);
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
        /* inconsistent y value */
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
        /* inconsistent y value */
-       dipe_decap(param, sk, "1234567890abcdef", x, ctxt, ptxtp);
+       dipe_decap(param, 1, &sk, "1234567890abcdef", x, ctxt, ptxtp);
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
        for (size_t i = 0; i < 6; ++i) {
        EXPECT_NE(element_cmp(ptxt, ptxtp), 0);
 
        for (size_t i = 0; i < 6; ++i) {
@@ -198,15 +198,15 @@ TEST(DipeTest, DipeDecryptSuccessSmall) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        for (size_t clen = overhead; clen < 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "test", 4);
 
 
        for (size_t clen = overhead; clen < 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "test", 4);
 
-               dipe_encrypt(param, pk, x, 4, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 4, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 4) {
                        EXPECT_EQ(ptxt_len, 4);
 
                if (clen >= overhead + 4) {
                        EXPECT_EQ(ptxt_len, 4);
@@ -251,7 +251,7 @@ TEST(DipeTest, DipeDecryptSuccessTightSmall) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        char ctxt[overhead + 4];
        char ptxt[overhead + 4];
 
        char ctxt[overhead + 4];
        char ptxt[overhead + 4];
@@ -261,8 +261,8 @@ TEST(DipeTest, DipeDecryptSuccessTightSmall) {
                memset(ptxt, 0, overhead + 4);
                memcpy(ptxt, "test", 4);
 
                memset(ptxt, 0, overhead + 4);
                memcpy(ptxt, "test", 4);
 
-               dipe_encrypt(param, pk, x, 4, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 4, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 4) {
                        EXPECT_EQ(ptxt_len, 4);
 
                if (clen >= overhead + 4) {
                        EXPECT_EQ(ptxt_len, 4);
@@ -310,15 +310,15 @@ TEST(DipeTest, DipeDecryptSuccessLargeBlocksize) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        for (size_t clen = overhead; clen <= 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
 
 
        for (size_t clen = overhead; clen <= 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
 
-               dipe_encrypt(param, pk, x, 28, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 28, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 28) {
                        EXPECT_EQ(ptxt_len, 28);
 
                if (clen >= overhead + 28) {
                        EXPECT_EQ(ptxt_len, 28);
@@ -363,7 +363,7 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeBlocksize) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        char ctxt[overhead + 28];
        char ptxt[overhead + 28];
 
        char ctxt[overhead + 28];
        char ptxt[overhead + 28];
@@ -374,8 +374,8 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeBlocksize) {
                memset(ptxt, 0, overhead + 28);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
 
                memset(ptxt, 0, overhead + 28);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbb", 28);
 
-               dipe_encrypt(param, pk, x, 28, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 28, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 28) {
                        EXPECT_EQ(ptxt_len, 28);
 
                if (clen >= overhead + 28) {
                        EXPECT_EQ(ptxt_len, 28);
@@ -423,15 +423,15 @@ TEST(DipeTest, DipeDecryptSuccessLargeNonBlocksize) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        for (size_t clen = overhead; clen <= 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
 
 
        for (size_t clen = overhead; clen <= 672; ++clen) {
                memset(ctxt, 0, 672);
                memset(ptxt, 0, 672);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
 
-               dipe_encrypt(param, pk, x, 35, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 35, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 35) {
                        EXPECT_EQ(ptxt_len, 35);
 
                if (clen >= overhead + 35) {
                        EXPECT_EQ(ptxt_len, 35);
@@ -476,7 +476,7 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeNonBlocksize) {
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
 
        dipe_master_keygen(param, 6, &pk, &msk);
        dipe_keygen(param, msk, "1234567890abcdef", y, &sk);
-       overhead = dipe_ciphertext_overhead(param, 6);
+       overhead = dipe_ciphertext_overhead(param, 6, 0);
 
        char ctxt[overhead + 35];
        char ptxt[overhead + 35];
 
        char ctxt[overhead + 35];
        char ptxt[overhead + 35];
@@ -487,8 +487,8 @@ TEST(DipeTest, DipeDecryptSuccessTightLargeNonBlocksize) {
                memset(ptxt, 0, overhead + 35);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
 
                memset(ptxt, 0, overhead + 35);
                memcpy(ptxt, "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccc", 35);
 
-               dipe_encrypt(param, pk, x, 35, ptxt, clen, ctxt);
-               ptxt_len = dipe_decrypt(param, sk, "1234567890abcdef", y, clen, ctxt, ptxt);
+               dipe_encrypt(param, 1, &pk, 1, x, 35, ptxt, clen, ctxt);
+               ptxt_len = dipe_decrypt(param, 1, &sk, "1234567890abcdef", y, clen, ctxt, ptxt);
 
                if (clen >= overhead + 35) {
                        EXPECT_EQ(ptxt_len, 35);
 
                if (clen >= overhead + 35) {
                        EXPECT_EQ(ptxt_len, 35);
index d5c1244f96baba6cc4b4b45be7cfc7621622be41..7e6a7506c26081f8492a94cad0477056fcaf25ab 100644 (file)
@@ -35,8 +35,8 @@ TEST(SSText, SSBaseTest) {
 
        
        for (size_t i = 0; i < 3; ++i) {
 
        
        for (size_t i = 0; i < 3; ++i) {
-               element_init_same_as(shared_secret, types[i]);
-               element_init_same_as(recovered_secret, types[i]);
+//             element_init_same_as(shared_secret, types[i]);
+//             element_init_same_as(recovered_secret, types[i]);
                
                for (size_t j = 0; j < parties; ++j) {
                        element_init_same_as(shares[j][0], types[i]);
                
                for (size_t j = 0; j < parties; ++j) {
                        element_init_same_as(shares[j][0], types[i]);
@@ -47,9 +47,10 @@ TEST(SSText, SSBaseTest) {
                dipe_ss_share(param, parties, identities, parties, dummy_identities, 1, shares, &shared_secret, dummy_shares);
                dipe_ss_recover(param, parties, identities, 1, shares, &recovered_secret);
                EXPECT_EQ(element_cmp(shared_secret, recovered_secret), 0);
                dipe_ss_share(param, parties, identities, parties, dummy_identities, 1, shares, &shared_secret, dummy_shares);
                dipe_ss_recover(param, parties, identities, 1, shares, &recovered_secret);
                EXPECT_EQ(element_cmp(shared_secret, recovered_secret), 0);
+               element_clear(recovered_secret);
                dipe_ss_recover(param, parties, dummy_identities, 1, dummy_shares, &recovered_secret);
                EXPECT_EQ(element_cmp(shared_secret, recovered_secret), 0);
                dipe_ss_recover(param, parties, dummy_identities, 1, dummy_shares, &recovered_secret);
                EXPECT_EQ(element_cmp(shared_secret, recovered_secret), 0);
-
+               element_clear(recovered_secret);
                
                for (size_t j = 0; j < parties; ++j) {
                        element_clear(shares[j][0]);
                
                for (size_t j = 0; j < parties; ++j) {
                        element_clear(shares[j][0]);
@@ -57,7 +58,6 @@ TEST(SSText, SSBaseTest) {
                }
                
                element_clear(shared_secret);
                }
                
                element_clear(shared_secret);
-               element_clear(recovered_secret);
        }
 
        for (size_t i = 0; i < 3; ++i) {
        }
 
        for (size_t i = 0; i < 3; ++i) {