]> git.siccegge.de Git - software/DIPE.git/blobdiff - src/DIPE.cxx
integrate secret sharing
[software/DIPE.git] / src / DIPE.cxx
index 9b8c91ec52c9f8495aa8f178072fd672674e9ec0..7b13147966a7df39b24919bd023fe018f3ed5380 100644 (file)
@@ -21,7 +21,7 @@ namespace {
                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) {
@@ -56,7 +56,7 @@ namespace {
 
                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);
@@ -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;
-               
+
                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);
                        }
                }
-               
+
                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_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);
 
-               /* 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)
-                       return 0; 
+                       return 0;
                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;
+       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);
@@ -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);
+       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];
@@ -206,58 +212,108 @@ void dipe_keygen(dipe_param_t param, dipe_master_secretkey_t msk, char* cid, ele
        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)->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_init_Zr(r, param->pairing);
-       element_init_Zr(s, param->pairing);
 
-       element_random(r);
+       element_init_Zr(s, param->pairing);
        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_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_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(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);
 
-       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;
@@ -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_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);
-       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);
        }
 
-       pairing_apply(ptxt, ctxt->s, sk->d, param->pairing);
        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);
@@ -285,7 +376,7 @@ void dipe_decap(dipe_param_t param, dipe_secretkey_t sk, char* cid, element_t* y
        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;
@@ -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);
-       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;
-       
+
        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;
-       
+
        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;
-       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);
@@ -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);
-       
+
        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);
-       
+
+       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;
 }
 
-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;
+       (*ctxt)->sharecount = shares;
 
        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);
-       
+
+
+       (*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;
 }
 
-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;
 
+       /* s */
        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);
+
+       /* c */
        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;
@@ -402,6 +525,7 @@ void dipe_free_master_secretkey(dipe_master_secretkey_t sk) {
        }
        element_clear(sk->a);
        free(sk->k);
+       element_clear(sk->aid);
        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->aid);
        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) {
-       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->s);
        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);
 }