| 391 | |
| 392 | impl<E: Pairing> SubsetWitness<E> { |
| 393 | pub fn verify<'a>( |
| 394 | &self, |
| 395 | subset: BTreeSet<E::ScalarField>, |
| 396 | set_commitment: &SetCommitment<E>, |
| 397 | srs: impl Into<&'a PreparedSetCommitmentSRS<E>>, |
| 398 | ) -> Result<(), DelegationError> { |
| 399 | if subset.is_empty() { |
| 400 | return if self.0 == set_commitment.0 { |
| 401 | Ok(()) |
| 402 | } else { |
| 403 | Err(DelegationError::InvalidWitness) |
| 404 | }; |
| 405 | } |
| 406 | let srs = srs.into(); |
| 407 | let P1_table = WindowTable::new(subset.len(), srs.get_P1().into_group()); |
| 408 | let s_P1 = srs.get_s_P1().into_group(); |
| 409 | // Check if subset contains the trapdoor |
| 410 | for s in subset.iter() { |
| 411 | if P1_table.multiply(s) == s_P1 { |
| 412 | return Err(DelegationError::ShouldNotContainTrapdoor); |
| 413 | } |
| 414 | } |
| 415 | // Check if e(witness, Ch(subset)) == e(set_commitment, P2) => e(witness, Ch(subset))*e(-set_commitment, P2) == 1 |
| 416 | if E::multi_pairing( |
| 417 | [self.0, (-set_commitment.0.into_group()).into_affine()], |
| 418 | [ |
| 419 | E::G2Prepared::from(srs.eval_P2(subset)), |
| 420 | srs.prepared_P2.clone(), |
| 421 | ], |
| 422 | ) |
| 423 | .is_zero() |
| 424 | { |
| 425 | Ok(()) |
| 426 | } else { |
| 427 | Err(DelegationError::InvalidWitness) |
| 428 | } |
| 429 | } |
| 430 | } |
| 431 | |
| 432 | impl<E: Pairing> AggregateSubsetWitness<E> { |