-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflexdb_et.cpp
More file actions
176 lines (152 loc) · 5.99 KB
/
Copy pathflexdb_et.cpp
File metadata and controls
176 lines (152 loc) · 5.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "flexdb_et.hpp"
FlexDbEtPp FlexDbEt::pp_gen(const int length, const bool pre){
// Create the pp instance.
FlexDbEtPp pp{};
// Update the input length according to input.
pp.l = length;
// Save the created pairing group.
pp.pairing_group = std::make_unique<BP>(pre);
return pp;
}
FlexDbEtMsk FlexDbEt::msk_gen(const FlexDbEtPp& pp, const CharVec& key, const bool& compress){
// Create the msk instance.
FlexDbEtMsk msk{};
// Save whether the values need to be compressed.
msk.compress = compress;
if (compress){
// Sample the starting point.
msk.d_int = Helper::rand_int();
msk.r_int = Helper::rand_int();
msk.b_int = Helper::rand_int();
// Get the unique point for HMAC.
msk.hmac = std::make_unique<HMAC>(key);
}
else{
// Sample a random point and find its inverse.
msk.d = pp.pairing_group->Zp->rand();
msk.di = pp.pairing_group->Zp->inv(msk.d);
// Sample two random vectors and find one of the inverse.
msk.r = pp.pairing_group->Zp->rand_vec(pp.l);
msk.b = pp.pairing_group->Zp->rand_vec(pp.l);
msk.bi = pp.pairing_group->Zp->vec_inv(msk.b);
}
return msk;
}
G1Vec FlexDbEt::enc(const FlexDbEtPp& pp, const FlexDbEtMsk& msk, const IntVec& x){
// First convert x to field elements.
const auto x_vec = pp.pairing_group->Zp->from_int(x);
// Sample the random point alpha.
const Fp alpha = pp.pairing_group->Zp->rand();
// Create pointers for values that needs to be used.
const Fp* d;
const FpVec *r, *b;
Fp temp_d;
FpVec temp_r, temp_b;
// In this case, first figure out whether the msk values needs to be sampled.
if (msk.compress){
// Only one value is generated.
temp_d = msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.d_int, 1)[0];
// Sample r and b.
temp_r = msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.r_int, pp.l);
temp_b = msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.b_int, pp.l);
// Assign the pointers with generated values.
d = &temp_d;
r = &temp_r;
b = &temp_b;
}
else{
// Assign the pointers with values from msk.
d = &msk.d;
r = &msk.r;
b = &msk.b;
}
// Compute x + r.
const auto xr = pp.pairing_group->Zp->vec_add(x_vec, *r);
// Compute b * (x + r).
const auto bxr = pp.pairing_group->Zp->vec_mul(xr, *b);
// Compute alpha * b * (x + r).
auto abxr = pp.pairing_group->Zp->vec_mul(bxr, alpha);
// Add the last point -alpha * delta.
abxr.push_back(pp.pairing_group->Zp->neg(pp.pairing_group->Zp->mul(alpha, *d)));
// Raise the vector to g1 and return.
return pp.pairing_group->Gp->g1_raise(abxr);
}
G2Vec FlexDbEt::keygen(const FlexDbEtPp& pp, const FlexDbEtMsk& msk, const IntVec& y, int p, const IntVec& sel){
// Convert the input y integer vector to FpVec.
const FpVec y_vec = pp.pairing_group->Zp->from_int(y);
// Sample the random point beta.
const Fp beta = pp.pairing_group->Zp->rand();
// Create pointers for values that needs to be used and static variables to hold computed values.
const Fp* di;
const FpVec *r, *bi;
Fp temp_di;
FpVec temp_r, temp_bi;
// In this case, first figure out whether the msk values needs to be sampled.
if (msk.compress){
// Only one value is generated.
temp_di = pp.pairing_group->Zp->inv(
msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.d_int, 1)[0]
);
// Sample r and b.
temp_r = msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.r_int, pp.l);
// Compute the bi.
temp_bi = pp.pairing_group->Zp->vec_inv(
msk.hmac->digest_int_to_fp_vec_mod(*pp.pairing_group, msk.b_int, pp.l)
);
// Assign the pointers with generated values.
di = &temp_di;
r = &temp_r;
bi = &temp_bi;
}
else{
// Assign the pointers with values from msk.
di = &msk.di;
r = &msk.r;
bi = &msk.bi;
}
// Depends on whether sel is provided, we use the correct set of randomness.
if (sel.empty()){
// Compute b' * y.
const auto biy = pp.pairing_group->Zp->vec_mul(y_vec, *bi);
// Compute beta * b' * y.
auto bbiy = pp.pairing_group->Zp->vec_mul(biy, beta);
// Compute the last point beta * delta' * (p + <r, y>);
auto temp = pp.pairing_group->Zp->vec_ip(y_vec, *r);
temp = pp.pairing_group->Zp->add(temp, Fp(p));
temp = pp.pairing_group->Zp->mul(temp, *di);
temp = pp.pairing_group->Zp->mul(temp, beta);
// Add the last point.
bbiy.push_back(temp);
// Raise the vector to g2 and return.
return pp.pairing_group->Gp->g2_raise(bbiy);
}
// Create the selected vectors.
FpVec sel_r, sel_bi;
for (auto& i : sel){
sel_r.push_back(r->at(i));
sel_bi.push_back(bi->at(i));
}
// Compute b' * y.
const auto biy = pp.pairing_group->Zp->vec_mul(y_vec, sel_bi);
// Compute beta * b' * y.
auto bbiy = pp.pairing_group->Zp->vec_mul(biy, beta);
// Compute the last point beta * delta' * (p + <r, y>);
auto temp = pp.pairing_group->Zp->vec_ip(y_vec, sel_r);
temp = pp.pairing_group->Zp->add(temp, Fp(p));
temp = pp.pairing_group->Zp->mul(temp, *di);
temp = pp.pairing_group->Zp->mul(temp, beta);
// Add the last point.
bbiy.push_back(temp);
// Raise the vector to g2 and return.
return pp.pairing_group->Gp->g2_raise(bbiy);
}
bool FlexDbEt::dec(const G1Vec& ct, const G2Vec& sk, const IntVec& sel){
// Select ciphertext that should be used.
G1Vec sel_ct;
if (sel.empty()) sel_ct = G1Vec(ct.begin(), ct.end() - 1);
else for (const auto i : sel) sel_ct.push_back(ct[i]);
// Also add the last point int ct.
sel_ct.push_back(ct.back());
// Compute the pairing and output filter result.
return Group::check_gt_unity(Group::pair(sel_ct, sk));
}