X-Git-Url: https://git.siccegge.de//index.cgi?p=software%2FDIPE.git;a=blobdiff_plain;f=src%2FDIPE.cxx;fp=src%2FDIPE.cxx;h=7b13147966a7df39b24919bd023fe018f3ed5380;hp=9b8c91ec52c9f8495aa8f178072fd672674e9ec0;hb=5611c662936ee7c02b5b4d6e7ede3cbde8dfde92;hpb=f20d9414f3017939d6aec74c70c0d5c0380edfae diff --git a/src/DIPE.cxx b/src/DIPE.cxx index 9b8c91e..7b13147 100644 --- a/src/DIPE.cxx +++ b/src/DIPE.cxx @@ -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); }