namespace {
void dipe_ss_esf(dipe_param_t param, size_t size, size_t m, size_t excl, element_t* elements, element_t* result) {
assert(size >= m);
+
+ if (m == 0) {
+ element_set1(*result);
+ return;
+ }
/* m = n */
- if (size == m || (m + 1 == size && excl < size)) {
+ if (size == m || (m + 1 == size && excl <= size)) {
assert((size == m) ? excl > size : true);
element_set1(*result);
for (size_t i = 0; i < size; ++i) {
element_init_Zr(result[i][j], param->pairing);
/* numerator */
- dipe_ss_esf(param, size, size-i, j, elements, &numerator);
- if (((size - i) & 1) == 1) {
+ dipe_ss_esf(param, size, size-i-1, j, elements, &numerator);
+ if (((size - i-1) & 1) == 1) {
element_neg(numerator, numerator);
}
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) {
element_t tmp;
+ element_t tmpz;
element_t a_pow;
- element_init_Zr(tmp, param->pairing);
+ element_init_same_as(tmp, shares[0][0]);
+ element_init_Zr(tmpz, param->pairing);
element_init_Zr(a_pow, param->pairing);
/* Precompute V_I^{-1} needed in several steps */
/* Compute Secret */
for (size_t k = 0; k < share_size; ++k) {
- element_set0(secret[k]);
+ element_set1(secret[k]);
for (size_t j = 0; j < id_size; ++j) {
- element_mul(tmp, b[0][j], shares[j][k]);
- element_add(secret[k], secret[k], tmp);
+ element_pow_zn(tmp, shares[j][k], b[0][j]);
+ element_mul(secret[k], secret[k], tmp);
}
}
element_set1(a_pow);
for (size_t k = 0; k < id_size; ++ k) {
- element_mul(tmp, a_pow, b[k][j]);
- element_add(ab[i][j], ab[i][j], tmp);
+ element_mul(tmpz, a_pow, b[k][j]);
+ element_add(ab[i][j], ab[i][j], tmpz);
element_mul(a_pow, a_pow, fake_ids[i]);
}
}
}
- /* Matrix Product */
+ /* Matrix Product. Note this is an abuse of notation and we're doing scalar * group in additive writing */
for (size_t i = 0; i < fid_size; ++ i) {
for (size_t j = 0; j < share_size; ++j) {
- element_init_Zr(dummy_shares[i][j], param->pairing);
- element_set0(dummy_shares[i][j]);
+ element_init_same_as(dummy_shares[i][j], shares[0][0]);
+ element_set1(dummy_shares[i][j]);
for (size_t k = 0; k < id_size; ++k) {
- element_mul(tmp, ab[i][k], shares[j][k]);
- element_add(dummy_shares[i][j], dummy_shares[i][j], tmp);
+ element_pow_zn(tmp, shares[k][j], ab[i][k]);
+ element_mul(dummy_shares[i][j], dummy_shares[i][j], tmp);
}
}
}
- /* TODO: cleanup */
+ for (size_t i = 0; i < id_size; ++i) {
+ for (size_t j = 0; j < id_size; ++j) {
+ element_clear(b[i][j]);
+ }
+ free(b[i]);
+ }
+ free(b);
+
+ for (size_t i = 0; i < fid_size; ++i) {
+ for (size_t j = 0; j < id_size; ++j) {
+ element_clear(ab[i][j]);
+ }
+ free(ab[i]);
+ }
+ free(ab);
+ element_clear(tmp);
+ element_clear(tmpz);
+ element_clear(a_pow);
}
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) {
element_t tmp;
/* TODO: fix type, shares are in G_t here~ */
- element_init_Zr(tmp, param->pairing);
+ element_init_same_as(tmp, shares[0][0]);
/* Precompute V_I^{-1} needed in several steps */
/* Actually for recover we only need the values b[0][j] */
/* Compute Secret */
for (size_t k = 0; k < share_size; ++k) {
- element_set0(secret[k]);
+ element_set1(secret[k]);
+ for (size_t j = 0; j < id_size; ++j) {
+ element_pow_zn(tmp, shares[j][k], b[0][j]);
+ element_mul(secret[k], secret[k], tmp);
+ }
+ }
+
+ for (size_t i = 0; i < id_size; ++i) {
for (size_t j = 0; j < id_size; ++j) {
- element_mul(tmp, b[0][j], shares[j][k]);
- element_add(secret[k], secret[k], tmp);
+ element_clear(b[i][j]);
}
+ free(b[i]);
}
+ free(b);
+ element_clear(tmp);
}