|
|
@ -60,92 +60,6 @@ impl CommitmentGensTrait for CommitmentGens { |
|
|
|
comm: G::vartime_multiscalar_mul(v, &self.gens[..v.len()]),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn split_at(&self, n: usize) -> (CommitmentGens<G>, CommitmentGens<G>) {
|
|
|
|
(
|
|
|
|
CommitmentGens {
|
|
|
|
gens: self.gens[0..n].to_vec(),
|
|
|
|
_p: Default::default(),
|
|
|
|
},
|
|
|
|
CommitmentGens {
|
|
|
|
gens: self.gens[n..].to_vec(),
|
|
|
|
_p: Default::default(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn combine(&self, other: &CommitmentGens<G>) -> CommitmentGens<G> {
|
|
|
|
let gens = {
|
|
|
|
let mut c = self.gens.clone();
|
|
|
|
c.extend(other.gens.clone());
|
|
|
|
c
|
|
|
|
};
|
|
|
|
CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// combines the left and right halves of `self` using `w1` and `w2` as the weights
|
|
|
|
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> CommitmentGens<G> {
|
|
|
|
let w = vec![*w1, *w2];
|
|
|
|
let (L, R) = self.split_at(self.len() / 2);
|
|
|
|
|
|
|
|
let gens = (0..self.len() / 2)
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| {
|
|
|
|
let gens = CommitmentGens::<G> {
|
|
|
|
gens: [L.gens[i].clone(), R.gens[i].clone()].to_vec(),
|
|
|
|
_p: Default::default(),
|
|
|
|
};
|
|
|
|
gens.commit(&w).comm.preprocessed()
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Scales each element in `self` by `r`
|
|
|
|
fn scale(&self, r: &G::Scalar) -> Self {
|
|
|
|
let gens_scaled = self
|
|
|
|
.gens
|
|
|
|
.clone()
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|g| {
|
|
|
|
let gens = CommitmentGens::<G> {
|
|
|
|
gens: vec![g],
|
|
|
|
_p: Default::default(),
|
|
|
|
};
|
|
|
|
gens.commit(&[*r]).comm.preprocessed()
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
CommitmentGens {
|
|
|
|
gens: gens_scaled,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// reinterprets a vector of commitments as a set of generators
|
|
|
|
fn reinterpret_commitments_as_gens(
|
|
|
|
c: &[CompressedCommitment<G::CompressedGroupElement>],
|
|
|
|
) -> Result<Self, NovaError> {
|
|
|
|
let d = (0..c.len())
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| c[i].decompress())
|
|
|
|
.collect::<Result<Vec<Commitment<G>>, NovaError>>()?;
|
|
|
|
let gens = (0..d.len())
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| d[i].comm.preprocessed())
|
|
|
|
.collect();
|
|
|
|
Ok(CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<G: Group> CommitmentTrait<G> for Commitment<G> {
|
|
|
@ -302,3 +216,109 @@ impl CommitmentEngineTrait for CommitmentEngine { |
|
|
|
gens.commit(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub(crate) trait CommitmentGensExtTrait<G: Group>: CommitmentGensTrait<G> {
|
|
|
|
type CE: CommitmentEngineTrait<G>;
|
|
|
|
|
|
|
|
/// Splits the commitment key into two pieces at a specified point
|
|
|
|
fn split_at(&self, n: usize) -> (Self, Self)
|
|
|
|
where
|
|
|
|
Self: Sized;
|
|
|
|
|
|
|
|
/// Combines two commitment keys into one
|
|
|
|
fn combine(&self, other: &Self) -> Self;
|
|
|
|
|
|
|
|
/// Folds the two commitment keys into one using the provided weights
|
|
|
|
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> Self;
|
|
|
|
|
|
|
|
/// Scales the commitment key using the provided scalar
|
|
|
|
fn scale(&self, r: &G::Scalar) -> Self;
|
|
|
|
|
|
|
|
/// Reinterprets commitments as commitment keys
|
|
|
|
fn reinterpret_commitments_as_gens(
|
|
|
|
c: &[<<Self as CommitmentGensExtTrait<G>>::CE as CommitmentEngineTrait<G>>::CompressedCommitment],
|
|
|
|
) -> Result<Self, NovaError>
|
|
|
|
where
|
|
|
|
Self: Sized;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<G: Group> CommitmentGensExtTrait<G> for CommitmentGens<G> {
|
|
|
|
type CE = CommitmentEngine<G>;
|
|
|
|
|
|
|
|
fn split_at(&self, n: usize) -> (CommitmentGens<G>, CommitmentGens<G>) {
|
|
|
|
(
|
|
|
|
CommitmentGens {
|
|
|
|
gens: self.gens[0..n].to_vec(),
|
|
|
|
_p: Default::default(),
|
|
|
|
},
|
|
|
|
CommitmentGens {
|
|
|
|
gens: self.gens[n..].to_vec(),
|
|
|
|
_p: Default::default(),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn combine(&self, other: &CommitmentGens<G>) -> CommitmentGens<G> {
|
|
|
|
let gens = {
|
|
|
|
let mut c = self.gens.clone();
|
|
|
|
c.extend(other.gens.clone());
|
|
|
|
c
|
|
|
|
};
|
|
|
|
CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// combines the left and right halves of `self` using `w1` and `w2` as the weights
|
|
|
|
fn fold(&self, w1: &G::Scalar, w2: &G::Scalar) -> CommitmentGens<G> {
|
|
|
|
let w = vec![*w1, *w2];
|
|
|
|
let (L, R) = self.split_at(self.len() / 2);
|
|
|
|
|
|
|
|
let gens = (0..self.len() / 2)
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| {
|
|
|
|
let bases = [L.gens[i].clone(), R.gens[i].clone()].to_vec();
|
|
|
|
G::vartime_multiscalar_mul(&w, &bases).preprocessed()
|
|
|
|
})
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Scales each element in `self` by `r`
|
|
|
|
fn scale(&self, r: &G::Scalar) -> Self {
|
|
|
|
let gens_scaled = self
|
|
|
|
.gens
|
|
|
|
.clone()
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|g| G::vartime_multiscalar_mul(&[*r], &[g]).preprocessed())
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
CommitmentGens {
|
|
|
|
gens: gens_scaled,
|
|
|
|
_p: Default::default(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// reinterprets a vector of commitments as a set of generators
|
|
|
|
fn reinterpret_commitments_as_gens(
|
|
|
|
c: &[CompressedCommitment<G::CompressedGroupElement>],
|
|
|
|
) -> Result<Self, NovaError> {
|
|
|
|
let d = (0..c.len())
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| c[i].decompress())
|
|
|
|
.collect::<Result<Vec<Commitment<G>>, NovaError>>()?;
|
|
|
|
let gens = (0..d.len())
|
|
|
|
.into_par_iter()
|
|
|
|
.map(|i| d[i].comm.preprocessed())
|
|
|
|
.collect();
|
|
|
|
Ok(CommitmentGens {
|
|
|
|
gens,
|
|
|
|
_p: Default::default(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|