`num_tokens` denotes the number of tokens to request and each token can be used to create one proof of knowledge.
(
rng: &mut R,
num_tokens: usize,
mac: &MAC<G>,
messages: &[G::ScalarField],
user_public_key: &UserPublicKey<G>,
params: &MACParams<G>,
)
| 131 | impl<G: AffineRepr> HOLUserProtocol<G> { |
| 132 | /// `num_tokens` denotes the number of tokens to request and each token can be used to create one proof of knowledge. |
| 133 | pub fn init<R: RngCore>( |
| 134 | rng: &mut R, |
| 135 | num_tokens: usize, |
| 136 | mac: &MAC<G>, |
| 137 | messages: &[G::ScalarField], |
| 138 | user_public_key: &UserPublicKey<G>, |
| 139 | params: &MACParams<G>, |
| 140 | ) -> Result<Self, KVACError> { |
| 141 | assert_eq!(params.supported_message_count(), messages.len()); |
| 142 | let mut u = vec![]; |
| 143 | for _ in 0..num_tokens { |
| 144 | // u needs to be invertible |
| 145 | let mut u_i = G::ScalarField::rand(rng); |
| 146 | while u_i.is_zero() { |
| 147 | u_i = G::ScalarField::rand(rng); |
| 148 | } |
| 149 | u.push(u_i); |
| 150 | } |
| 151 | let v = (0..num_tokens) |
| 152 | .map(|_| G::ScalarField::rand(rng)) |
| 153 | .collect::<Vec<_>>(); |
| 154 | let minus_e = -mac.e; |
| 155 | // B = (e+x) * A = g_0 + user_pk + \sum(g_vec_i*m_i) for all i in I |
| 156 | let B = params.b(messages.iter().enumerate(), &user_public_key)?; |
| 157 | let A_table = WindowTable::new(num_tokens, mac.A.into_group()); |
| 158 | let B_table = WindowTable::new(num_tokens, B); |
| 159 | let mut A_hat = vec![]; |
| 160 | let mut B_bar = vec![]; |
| 161 | let mut D = vec![]; |
| 162 | let mut r1_vec = vec![]; |
| 163 | let mut r3_vec = vec![]; |
| 164 | let mut l = vec![]; |
| 165 | for _ in 0..num_tokens { |
| 166 | let r1 = G::ScalarField::rand(rng); |
| 167 | let mut r2 = G::ScalarField::rand(rng); |
| 168 | while r2.is_zero() { |
| 169 | r2 = G::ScalarField::rand(rng); |
| 170 | } |
| 171 | let r3 = r2.inverse().unwrap(); |
| 172 | |
| 173 | let l_i = r1 * r2; |
| 174 | // A_hat = A * r1 * r2 |
| 175 | let A_hat_i = (A_table.multiply(&l_i)).into_affine(); |
| 176 | // D = B * r2 |
| 177 | let D_i = B_table.multiply(&r2).into_affine(); |
| 178 | // D * r1 = B * r2 * r1 |
| 179 | // A_hat = A * r1 * r2 |
| 180 | // B_bar = D * r1 - A_hat * e = B * r2 * r1 - A * r1 * r2 * e |
| 181 | let B_bar_i = |
| 182 | (B_table.multiply(&l_i) + A_table.multiply(&(l_i * minus_e))).into_affine(); |
| 183 | A_hat.push(A_hat_i); |
| 184 | B_bar.push(B_bar_i); |
| 185 | D.push(D_i); |
| 186 | r1_vec.push(r1); |
| 187 | r3_vec.push(r3); |
| 188 | l.push(l_i); |
| 189 | } |
| 190 | Ok(Self { |