use crate::*;
use ark_ec::pairing::Pairing;
use ark_ec::AffineRepr;
use ark_ec::Group;
use ark_ff::{PrimeField, ToConstraintField};
use ark_serialize::{
CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate,
};
use ark_std::{
borrow::Cow,
io::{Read, Write},
marker::PhantomData,
ops::{Add, AddAssign},
};
#[derive(Derivative)]
#[derivative(
Clone(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct UniversalParams<E: Pairing> {
pub powers_of_g: Vec<E::G1Affine>,
pub powers_of_gamma_g: BTreeMap<usize, E::G1Affine>,
pub h: E::G2Affine,
pub beta_h: E::G2Affine,
pub neg_powers_of_h: BTreeMap<usize, E::G2Affine>,
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub prepared_h: E::G2Prepared,
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub prepared_beta_h: E::G2Prepared,
}
impl<E: Pairing> Valid for UniversalParams<E> {
fn check(&self) -> Result<(), SerializationError> {
self.powers_of_g.check()?;
self.powers_of_gamma_g.check()?;
self.h.check()?;
self.beta_h.check()?;
self.neg_powers_of_h.check()?;
Ok(())
}
}
impl<E: Pairing> PCUniversalParams for UniversalParams<E> {
fn max_degree(&self) -> usize {
self.powers_of_g.len() - 1
}
}
impl<E: Pairing> CanonicalSerialize for UniversalParams<E> {
fn serialize_with_mode<W: Write>(
&self,
mut writer: W,
compress: Compress,
) -> Result<(), SerializationError> {
self.powers_of_g
.serialize_with_mode(&mut writer, compress)?;
self.powers_of_gamma_g
.serialize_with_mode(&mut writer, compress)?;
self.h.serialize_with_mode(&mut writer, compress)?;
self.beta_h.serialize_with_mode(&mut writer, compress)?;
self.neg_powers_of_h
.serialize_with_mode(&mut writer, compress)
}
fn serialized_size(&self, compress: Compress) -> usize {
self.powers_of_g.serialized_size(compress)
+ self.powers_of_gamma_g.serialized_size(compress)
+ self.h.serialized_size(compress)
+ self.beta_h.serialized_size(compress)
+ self.neg_powers_of_h.serialized_size(compress)
}
}
impl<E: Pairing> CanonicalDeserialize for UniversalParams<E> {
fn deserialize_with_mode<R: Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, SerializationError> {
let powers_of_g = Vec::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let powers_of_gamma_g =
BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let beta_h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let neg_powers_of_h = BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let prepared_h = E::G2Prepared::from(h.clone());
let prepared_beta_h = E::G2Prepared::from(beta_h.clone());
let result = Self {
powers_of_g,
powers_of_gamma_g,
h,
beta_h,
neg_powers_of_h,
prepared_h,
prepared_beta_h,
};
if let Validate::Yes = validate {
result.check()?;
}
Ok(result)
}
}
#[derive(Derivative)]
#[derivative(
Default(bound = ""),
Hash(bound = ""),
Clone(bound = ""),
Debug(bound = ""),
PartialEq
)]
pub struct Powers<'a, E: Pairing> {
pub powers_of_g: Cow<'a, [E::G1Affine]>,
pub powers_of_gamma_g: Cow<'a, [E::G1Affine]>,
}
impl<E: Pairing> Powers<'_, E> {
pub fn size(&self) -> usize {
self.powers_of_g.len()
}
}
impl<'a, E: Pairing> Valid for Powers<'a, E> {
fn check(&self) -> Result<(), SerializationError> {
Ok(())
}
}
impl<'a, E: Pairing> CanonicalSerialize for Powers<'a, E> {
fn serialize_with_mode<W: Write>(
&self,
mut writer: W,
compress: Compress,
) -> Result<(), SerializationError> {
self.powers_of_g
.serialize_with_mode(&mut writer, compress)?;
self.powers_of_gamma_g
.serialize_with_mode(&mut writer, compress)
}
fn serialized_size(&self, compress: Compress) -> usize {
self.powers_of_g.serialized_size(compress)
+ self.powers_of_gamma_g.serialized_size(compress)
}
}
impl<'a, E: Pairing> CanonicalDeserialize for Powers<'a, E> {
fn deserialize_with_mode<R: Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, SerializationError> {
let powers_of_g = Vec::deserialize_with_mode(&mut reader, compress, validate)?;
let powers_of_gamma_g = Vec::deserialize_with_mode(&mut reader, compress, validate)?;
let result = Self {
powers_of_g: Cow::Owned(powers_of_g),
powers_of_gamma_g: Cow::Owned(powers_of_gamma_g),
};
if let Validate::Yes = validate {
result.check()?;
}
Ok(result)
}
}
#[derive(Derivative)]
#[derivative(
Default(bound = ""),
Clone(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct VerifierKey<E: Pairing> {
pub g: E::G1Affine,
pub gamma_g: E::G1Affine,
pub h: E::G2Affine,
pub beta_h: E::G2Affine,
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub prepared_h: E::G2Prepared,
#[derivative(Debug = "ignore", PartialEq = "ignore")]
pub prepared_beta_h: E::G2Prepared,
}
impl<E: Pairing> Valid for VerifierKey<E> {
fn check(&self) -> Result<(), SerializationError> {
self.g.check()?;
self.gamma_g.check()?;
self.h.check()?;
self.beta_h.check()?;
Ok(())
}
}
impl<E: Pairing> CanonicalSerialize for VerifierKey<E> {
fn serialize_with_mode<W: Write>(
&self,
mut writer: W,
compress: Compress,
) -> Result<(), SerializationError> {
self.g.serialize_with_mode(&mut writer, compress)?;
self.gamma_g.serialize_with_mode(&mut writer, compress)?;
self.h.serialize_with_mode(&mut writer, compress)?;
self.beta_h.serialize_with_mode(&mut writer, compress)
}
fn serialized_size(&self, compress: Compress) -> usize {
self.g.serialized_size(compress)
+ self.gamma_g.serialized_size(compress)
+ self.h.serialized_size(compress)
+ self.beta_h.serialized_size(compress)
}
}
impl<E: Pairing> CanonicalDeserialize for VerifierKey<E> {
fn deserialize_with_mode<R: Read>(
mut reader: R,
compress: Compress,
validate: Validate,
) -> Result<Self, SerializationError> {
let g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let gamma_g = E::G1Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let beta_h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
let prepared_h = E::G2Prepared::from(h.clone());
let prepared_beta_h = E::G2Prepared::from(beta_h.clone());
let result = Self {
g,
gamma_g,
h,
beta_h,
prepared_h,
prepared_beta_h,
};
if let Validate::Yes = validate {
result.check()?;
}
Ok(result)
}
}
impl<E: Pairing> ToConstraintField<<E::TargetField as Field>::BasePrimeField> for VerifierKey<E>
where
E::G1Affine: ToConstraintField<<E::TargetField as Field>::BasePrimeField>,
E::G2Affine: ToConstraintField<<E::TargetField as Field>::BasePrimeField>,
{
fn to_field_elements(&self) -> Option<Vec<<E::TargetField as Field>::BasePrimeField>> {
let mut res = Vec::new();
res.extend_from_slice(&self.g.to_field_elements().unwrap());
res.extend_from_slice(&self.gamma_g.to_field_elements().unwrap());
res.extend_from_slice(&self.h.to_field_elements().unwrap());
res.extend_from_slice(&self.beta_h.to_field_elements().unwrap());
Some(res)
}
}
#[derive(Derivative)]
#[derivative(Default(bound = ""), Clone(bound = ""), Debug(bound = ""))]
pub struct PreparedVerifierKey<E: Pairing> {
pub prepared_g: Vec<E::G1Affine>,
pub prepared_h: E::G2Prepared,
pub prepared_beta_h: E::G2Prepared,
}
impl<E: Pairing> PreparedVerifierKey<E> {
pub fn prepare(vk: &VerifierKey<E>) -> Self {
let supported_bits = E::ScalarField::MODULUS_BIT_SIZE as usize;
let mut prepared_g = Vec::<E::G1Affine>::new();
let mut g = E::G1::from(vk.g.clone());
for _ in 0..supported_bits {
prepared_g.push(g.clone().into());
g.double_in_place();
}
Self {
prepared_g,
prepared_h: vk.prepared_h.clone(),
prepared_beta_h: vk.prepared_beta_h.clone(),
}
}
}
#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
#[derivative(
Default(bound = ""),
Hash(bound = ""),
Clone(bound = ""),
Copy(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct Commitment<E: Pairing>(
pub E::G1Affine,
);
impl<E: Pairing> PCCommitment for Commitment<E> {
#[inline]
fn empty() -> Self {
Commitment(E::G1Affine::zero())
}
fn has_degree_bound(&self) -> bool {
false
}
}
impl<E: Pairing> ToConstraintField<<E::TargetField as Field>::BasePrimeField> for Commitment<E>
where
E::G1Affine: ToConstraintField<<E::TargetField as Field>::BasePrimeField>,
{
fn to_field_elements(&self) -> Option<Vec<<E::TargetField as Field>::BasePrimeField>> {
self.0.to_field_elements()
}
}
impl<'a, E: Pairing> AddAssign<(E::ScalarField, &'a Commitment<E>)> for Commitment<E> {
#[inline]
fn add_assign(&mut self, (f, other): (E::ScalarField, &'a Commitment<E>)) {
let mut other = other.0 * f;
other.add_assign(&self.0);
self.0 = other.into();
}
}
#[derive(Derivative)]
#[derivative(
Default(bound = ""),
Hash(bound = ""),
Clone(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct PreparedCommitment<E: Pairing>(
pub Vec<E::G1Affine>,
);
impl<E: Pairing> PreparedCommitment<E> {
pub fn prepare(comm: &Commitment<E>) -> Self {
let mut prepared_comm = Vec::<E::G1Affine>::new();
let mut cur = E::G1::from(comm.0.clone());
let supported_bits = E::ScalarField::MODULUS_BIT_SIZE as usize;
for _ in 0..supported_bits {
prepared_comm.push(cur.clone().into());
cur.double_in_place();
}
Self { 0: prepared_comm }
}
}
#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
#[derivative(
Hash(bound = ""),
Clone(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct Randomness<F: PrimeField, P: DenseUVPolynomial<F>> {
pub blinding_polynomial: P,
_field: PhantomData<F>,
}
impl<F: PrimeField, P: DenseUVPolynomial<F>> Randomness<F, P> {
#[inline]
pub fn is_hiding(&self) -> bool {
!self.blinding_polynomial.is_zero()
}
#[inline]
pub fn calculate_hiding_polynomial_degree(hiding_bound: usize) -> usize {
hiding_bound + 1
}
}
impl<F: PrimeField, P: DenseUVPolynomial<F>> PCRandomness for Randomness<F, P> {
fn empty() -> Self {
Self {
blinding_polynomial: P::zero(),
_field: PhantomData,
}
}
fn rand<R: RngCore>(hiding_bound: usize, _: bool, _: Option<usize>, rng: &mut R) -> Self {
let mut randomness = Randomness::empty();
let hiding_poly_degree = Self::calculate_hiding_polynomial_degree(hiding_bound);
randomness.blinding_polynomial = P::rand(hiding_poly_degree, rng);
randomness
}
}
impl<'a, F: PrimeField, P: DenseUVPolynomial<F>> Add<&'a Randomness<F, P>> for Randomness<F, P> {
type Output = Self;
#[inline]
fn add(mut self, other: &'a Self) -> Self {
self.blinding_polynomial += &other.blinding_polynomial;
self
}
}
impl<'a, F: PrimeField, P: DenseUVPolynomial<F>> Add<(F, &'a Randomness<F, P>)>
for Randomness<F, P>
{
type Output = Self;
#[inline]
fn add(mut self, other: (F, &'a Randomness<F, P>)) -> Self {
self += other;
self
}
}
impl<'a, F: PrimeField, P: DenseUVPolynomial<F>> AddAssign<&'a Randomness<F, P>>
for Randomness<F, P>
{
#[inline]
fn add_assign(&mut self, other: &'a Self) {
self.blinding_polynomial += &other.blinding_polynomial;
}
}
impl<'a, F: PrimeField, P: DenseUVPolynomial<F>> AddAssign<(F, &'a Randomness<F, P>)>
for Randomness<F, P>
{
#[inline]
fn add_assign(&mut self, (f, other): (F, &'a Randomness<F, P>)) {
self.blinding_polynomial += (f, &other.blinding_polynomial);
}
}
#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)]
#[derivative(
Default(bound = ""),
Hash(bound = ""),
Clone(bound = ""),
Copy(bound = ""),
Debug(bound = ""),
PartialEq(bound = ""),
Eq(bound = "")
)]
pub struct Proof<E: Pairing> {
pub w: E::G1Affine,
pub random_v: Option<E::ScalarField>,
}