mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 09:43:09 +00:00
Merge branch 'main' into optimize_arithmetic_ops
This commit is contained in:
commit
4433fd8048
@ -12,12 +12,12 @@ edition = "2018"
|
||||
default-run = "bench_recursion"
|
||||
|
||||
[dependencies]
|
||||
env_logger = "0.8.3"
|
||||
env_logger = "0.9.0"
|
||||
log = "0.4.14"
|
||||
itertools = "0.10.0"
|
||||
num = "0.3"
|
||||
rand = "0.7.3"
|
||||
rand_chacha = "0.2.2"
|
||||
num = "0.4"
|
||||
rand = "0.8.4"
|
||||
rand_chacha = "0.3.1"
|
||||
rayon = "1.5.1"
|
||||
unroll = "0.1.5"
|
||||
anyhow = "1.0.40"
|
||||
|
||||
@ -34,6 +34,7 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
},
|
||||
};
|
||||
|
||||
let inputs = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let zero = builder.zero();
|
||||
@ -49,7 +50,6 @@ fn bench_prove<F: Field + Extendable<D>, const D: usize>() -> Result<()> {
|
||||
builder.add_extension(zero_ext, zero_ext);
|
||||
|
||||
let circuit = builder.build();
|
||||
let inputs = PartialWitness::new();
|
||||
let proof_with_pis = circuit.prove(inputs)?;
|
||||
let proof_bytes = serde_cbor::to_vec(&proof_with_pis).unwrap();
|
||||
info!("Proof length: {} bytes", proof_bytes.len());
|
||||
|
||||
@ -343,7 +343,7 @@ impl Field for CrandallField {
|
||||
}
|
||||
|
||||
fn rand_from_rng<R: Rng>(rng: &mut R) -> Self {
|
||||
Self::from_canonical_u64(rng.gen_range(0, FIELD_ORDER))
|
||||
Self::from_canonical_u64(rng.gen_range(0..FIELD_ORDER))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ enum FftStrategy {
|
||||
|
||||
const FFT_STRATEGY: FftStrategy = FftStrategy::Classic;
|
||||
|
||||
type FftRootTable<F> = Vec<Vec<F>>;
|
||||
pub(crate) type FftRootTable<F> = Vec<Vec<F>>;
|
||||
|
||||
fn fft_classic_root_table<F: Field>(n: usize) -> FftRootTable<F> {
|
||||
let lg_n = log2_strict(n);
|
||||
|
||||
@ -23,7 +23,6 @@ pub const SALT_SIZE: usize = 2;
|
||||
pub struct PolynomialBatchCommitment<F: Field> {
|
||||
pub polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
pub merkle_tree: MerkleTree<F>,
|
||||
pub degree: usize,
|
||||
pub degree_log: usize,
|
||||
pub rate_bits: usize,
|
||||
pub blinding: bool,
|
||||
@ -31,25 +30,23 @@ pub struct PolynomialBatchCommitment<F: Field> {
|
||||
|
||||
impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
/// Creates a list polynomial commitment for the polynomials interpolating the values in `values`.
|
||||
pub(crate) fn new(
|
||||
pub(crate) fn from_values(
|
||||
values: Vec<PolynomialValues<F>>,
|
||||
rate_bits: usize,
|
||||
blinding: bool,
|
||||
timing: &mut TimingTree,
|
||||
) -> Self {
|
||||
let degree = values[0].len();
|
||||
let polynomials = values.par_iter().map(|v| v.ifft()).collect::<Vec<_>>();
|
||||
let lde_values = timed!(
|
||||
let coeffs = timed!(
|
||||
timing,
|
||||
"compute LDE",
|
||||
Self::lde_values(&polynomials, rate_bits, blinding)
|
||||
"IFFT",
|
||||
values.par_iter().map(|v| v.ifft()).collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing)
|
||||
Self::from_coeffs(coeffs, rate_bits, blinding, timing)
|
||||
}
|
||||
|
||||
/// Creates a list polynomial commitment for the polynomials `polynomials`.
|
||||
pub(crate) fn new_from_polys(
|
||||
pub(crate) fn from_coeffs(
|
||||
polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
rate_bits: usize,
|
||||
blinding: bool,
|
||||
@ -58,21 +55,10 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
let degree = polynomials[0].len();
|
||||
let lde_values = timed!(
|
||||
timing,
|
||||
"compute LDE",
|
||||
"FFT + blinding",
|
||||
Self::lde_values(&polynomials, rate_bits, blinding)
|
||||
);
|
||||
|
||||
Self::new_from_data(polynomials, lde_values, degree, rate_bits, blinding, timing)
|
||||
}
|
||||
|
||||
fn new_from_data(
|
||||
polynomials: Vec<PolynomialCoeffs<F>>,
|
||||
lde_values: Vec<Vec<F>>,
|
||||
degree: usize,
|
||||
rate_bits: usize,
|
||||
blinding: bool,
|
||||
timing: &mut TimingTree,
|
||||
) -> Self {
|
||||
let mut leaves = timed!(timing, "transpose LDEs", transpose(&lde_values));
|
||||
reverse_index_bits_in_place(&mut leaves);
|
||||
let merkle_tree = timed!(timing, "build Merkle tree", MerkleTree::new(leaves, false));
|
||||
@ -80,7 +66,6 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
Self {
|
||||
polynomials,
|
||||
merkle_tree,
|
||||
degree,
|
||||
degree_log: log2_strict(degree),
|
||||
rate_bits,
|
||||
blinding,
|
||||
@ -93,20 +78,23 @@ impl<F: Field> PolynomialBatchCommitment<F> {
|
||||
blinding: bool,
|
||||
) -> Vec<Vec<F>> {
|
||||
let degree = polynomials[0].len();
|
||||
|
||||
// If blinding, salt with two random elements to each leaf vector.
|
||||
let salt_size = if blinding { SALT_SIZE } else { 0 };
|
||||
|
||||
polynomials
|
||||
.par_iter()
|
||||
.map(|p| {
|
||||
assert_eq!(p.len(), degree, "Polynomial degree invalid.");
|
||||
p.lde(rate_bits).coset_fft(F::coset_shift()).values
|
||||
})
|
||||
.chain(if blinding {
|
||||
// If blinding, salt with two random elements to each leaf vector.
|
||||
(0..SALT_SIZE)
|
||||
.map(|_| F::rand_vec(degree << rate_bits))
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
assert_eq!(p.len(), degree, "Polynomial degrees inconsistent");
|
||||
p.lde(rate_bits)
|
||||
.coset_fft_with_options(F::coset_shift(), Some(rate_bits), None)
|
||||
.values
|
||||
})
|
||||
.chain(
|
||||
(0..salt_size)
|
||||
.into_par_iter()
|
||||
.map(|_| F::rand_vec(degree << rate_bits)),
|
||||
)
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -306,7 +294,7 @@ mod tests {
|
||||
|
||||
let lpcs = (0..4)
|
||||
.map(|i| {
|
||||
PolynomialBatchCommitment::<F>::new(
|
||||
PolynomialBatchCommitment::<F>::from_values(
|
||||
gen_random_test_case(ks[i], degree_bits),
|
||||
common_data.config.rate_bits,
|
||||
PlonkPolynomials::polynomials(i).blinding,
|
||||
|
||||
@ -712,8 +712,8 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let vs = FF::rand_vec(3);
|
||||
let ts = builder.add_virtual_extension_targets(3);
|
||||
@ -749,6 +749,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let x = FF::rand();
|
||||
@ -763,7 +764,7 @@ mod tests {
|
||||
builder.assert_equal_extension(zt, comp_zt_unsafe);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
@ -64,6 +64,7 @@ mod tests {
|
||||
type FF = QuarticCrandallField;
|
||||
let len = 1 << len_log;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let v = (0..len - 1)
|
||||
.map(|_| builder.constant_extension(FF::rand()))
|
||||
@ -83,7 +84,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
@ -74,6 +74,7 @@ mod tests {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let len = 4;
|
||||
@ -103,7 +104,7 @@ mod tests {
|
||||
builder.assert_equal_extension(eval, true_eval_target);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
@ -113,6 +114,7 @@ mod tests {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let len = 2;
|
||||
@ -137,7 +139,7 @@ mod tests {
|
||||
builder.assert_equal_extension(eval, true_eval_target);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ mod tests {
|
||||
type FF = QuarticCrandallField;
|
||||
let len = 1 << len_log;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let vec = FF::rand_vec(len);
|
||||
let v: Vec<_> = vec.iter().map(|x| builder.constant_extension(*x)).collect();
|
||||
@ -61,7 +62,7 @@ mod tests {
|
||||
}
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
@ -48,8 +48,8 @@ mod tests {
|
||||
type F = CrandallField;
|
||||
type FF = QuarticCrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let (x, y) = (FF::rand(), FF::rand());
|
||||
let xt = builder.add_virtual_extension_target();
|
||||
|
||||
@ -99,6 +99,7 @@ mod tests {
|
||||
fn test_split_base() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let x = F::from_canonical_usize(0b110100000); // 416 = 1532 in base 6.
|
||||
let xt = builder.constant(x);
|
||||
@ -115,7 +116,7 @@ mod tests {
|
||||
builder.assert_leading_zeros(xt, 64 - 9);
|
||||
let data = builder.build();
|
||||
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
@ -124,9 +125,10 @@ mod tests {
|
||||
fn test_base_sum() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
|
||||
let n = thread_rng().gen_range(0, 1 << 10);
|
||||
let n = thread_rng().gen_range(0..(1 << 10));
|
||||
let x = builder.constant(F::from_canonical_usize(n));
|
||||
|
||||
let zero = builder.zero();
|
||||
@ -147,7 +149,7 @@ mod tests {
|
||||
|
||||
let data = builder.build();
|
||||
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
@ -124,8 +124,8 @@ pub(crate) fn test_eval_fns<F: Extendable<D>, G: Gate<F, D>, const D: usize>(
|
||||
let constants = F::Extension::rand_vec(gate.num_constants());
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let wires_t = builder.add_virtual_extension_targets(wires.len());
|
||||
let constants_t = builder.add_virtual_extension_targets(constants.len());
|
||||
|
||||
@ -64,9 +64,9 @@ impl<F: Extendable<D>, const D: usize> Tree<GateRef<F, D>> {
|
||||
gates.sort_unstable_by_key(|g| (-(g.0.degree() as isize), -(g.0.num_constants() as isize)));
|
||||
|
||||
for max_degree_bits in 1..10 {
|
||||
// The constraint polynomials are padded to the next power in `compute_vanishig_polys`.
|
||||
// So we can restrict our search space by setting `max_degree` to a power of 2.
|
||||
let max_degree = 1 << max_degree_bits;
|
||||
// The quotient polynomials are padded to the next power of 2 in `compute_quotient_polys`.
|
||||
// So we can restrict our search space by setting `max_degree` to 1 + a power of 2.
|
||||
let max_degree = (1 << max_degree_bits) + 1;
|
||||
for max_constants in 1..100 {
|
||||
if let Some(mut best_tree) = Self::find_tree(&gates, max_degree, max_constants) {
|
||||
let mut best_num_constants = best_tree.num_constants();
|
||||
|
||||
@ -357,7 +357,7 @@ mod tests {
|
||||
|
||||
let permutation_inputs = (0..W).map(F::from_canonical_usize).collect::<Vec<_>>();
|
||||
|
||||
let mut witness = PartialWitness::new();
|
||||
let mut witness = PartialWitness::new(gate.num_wires());
|
||||
witness.set_wire(
|
||||
Wire {
|
||||
gate: 0,
|
||||
|
||||
@ -154,14 +154,14 @@ mod tests {
|
||||
fn test_recursive_merkle_proof() -> Result<()> {
|
||||
type F = CrandallField;
|
||||
let config = CircuitConfig::large_config();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config);
|
||||
let mut pw = PartialWitness::new();
|
||||
|
||||
let log_n = 8;
|
||||
let n = 1 << log_n;
|
||||
let leaves = random_data::<F>(n, 7);
|
||||
let tree = MerkleTree::new(leaves, false);
|
||||
let i: usize = thread_rng().gen_range(0, n);
|
||||
let i: usize = thread_rng().gen_range(0..n);
|
||||
let proof = tree.prove(i);
|
||||
|
||||
let proof_t = MerkleProofTarget {
|
||||
|
||||
@ -399,6 +399,7 @@ mod tests {
|
||||
num_routed_wires: 27,
|
||||
..CircuitConfig::default()
|
||||
};
|
||||
let mut witness = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, 4>::new(config.clone());
|
||||
let mut recursive_challenger = RecursiveChallenger::new(&mut builder);
|
||||
let mut recursive_outputs_per_round: Vec<Vec<Target>> = Vec::new();
|
||||
@ -409,7 +410,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
let circuit = builder.build();
|
||||
let mut witness = PartialWitness::new();
|
||||
generate_partial_witness(
|
||||
&mut witness,
|
||||
&circuit.prover_only.generators,
|
||||
|
||||
@ -26,22 +26,23 @@ impl<F: Field> Witness<F> {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PartialWitness<F: Field> {
|
||||
pub(crate) target_values: HashMap<Target, F>,
|
||||
pub(crate) wire_values: Vec<Vec<Option<F>>>,
|
||||
pub(crate) virtual_target_values: Vec<Option<F>>,
|
||||
}
|
||||
|
||||
impl<F: Field> PartialWitness<F> {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(num_wires: usize) -> Self {
|
||||
PartialWitness {
|
||||
target_values: HashMap::new(),
|
||||
wire_values: vec![vec![None; num_wires]],
|
||||
virtual_target_values: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.target_values.is_empty()
|
||||
}
|
||||
|
||||
pub fn get_target(&self, target: Target) -> F {
|
||||
self.target_values[&target]
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => self.wire_values[gate][input].unwrap(),
|
||||
Target::VirtualTarget { index } => self.virtual_target_values[index].unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_targets(&self, targets: &[Target]) -> Vec<F> {
|
||||
@ -76,7 +77,10 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
|
||||
pub fn try_get_target(&self, target: Target) -> Option<F> {
|
||||
self.target_values.get(&target).cloned()
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => self.wire_values[gate][input],
|
||||
Target::VirtualTarget { index } => self.virtual_target_values[index],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_wire(&self, wire: Wire) -> F {
|
||||
@ -88,7 +92,15 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
|
||||
pub fn contains(&self, target: Target) -> bool {
|
||||
self.target_values.contains_key(&target)
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => {
|
||||
self.wire_values.len() > gate && self.wire_values[gate][input].is_some()
|
||||
}
|
||||
Target::VirtualTarget { index } => {
|
||||
self.virtual_target_values.len() > index
|
||||
&& self.virtual_target_values[index].is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_all(&self, targets: &[Target]) -> bool {
|
||||
@ -96,13 +108,36 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
|
||||
pub fn set_target(&mut self, target: Target, value: F) {
|
||||
let opt_old_value = self.target_values.insert(target, value);
|
||||
if let Some(old_value) = opt_old_value {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target was set twice with different values: {:?}",
|
||||
target
|
||||
);
|
||||
match target {
|
||||
Target::Wire(Wire { gate, input }) => {
|
||||
if gate >= self.wire_values.len() {
|
||||
self.wire_values
|
||||
.resize(gate + 1, vec![None; self.wire_values[0].len()]);
|
||||
}
|
||||
if let Some(old_value) = self.wire_values[gate][input] {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target was set twice with different values: {:?}",
|
||||
target
|
||||
);
|
||||
} else {
|
||||
self.wire_values[gate][input] = Some(value);
|
||||
}
|
||||
}
|
||||
Target::VirtualTarget { index } => {
|
||||
if index >= self.virtual_target_values.len() {
|
||||
self.virtual_target_values.resize(index + 1, None);
|
||||
}
|
||||
if let Some(old_value) = self.virtual_target_values[index] {
|
||||
assert_eq!(
|
||||
old_value, value,
|
||||
"Target was set twice with different values: {:?}",
|
||||
target
|
||||
);
|
||||
} else {
|
||||
self.virtual_target_values[index] = Some(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,16 +197,19 @@ impl<F: Field> PartialWitness<F> {
|
||||
}
|
||||
|
||||
pub fn extend<I: Iterator<Item = (Target, F)>>(&mut self, pairs: I) {
|
||||
self.target_values.extend(pairs);
|
||||
for (t, v) in pairs {
|
||||
self.set_target(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn full_witness(self, degree: usize, num_wires: usize) -> Witness<F> {
|
||||
let mut wire_values = vec![vec![F::ZERO; degree]; num_wires];
|
||||
self.target_values.into_iter().for_each(|(t, v)| {
|
||||
if let Target::Wire(Wire { gate, input }) = t {
|
||||
wire_values[input][gate] = v;
|
||||
assert!(self.wire_values.len() <= degree);
|
||||
for i in 0..self.wire_values.len() {
|
||||
for j in 0..num_wires {
|
||||
wire_values[j][i] = self.wire_values[i][j].unwrap_or(F::ZERO);
|
||||
}
|
||||
});
|
||||
}
|
||||
Witness { wire_values }
|
||||
}
|
||||
|
||||
@ -212,9 +250,3 @@ impl<F: Field> PartialWitness<F> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field> Default for PartialWitness<F> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
@ -506,7 +506,6 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
/// Builds a "full circuit", with both prover and verifier data.
|
||||
pub fn build(mut self) -> CircuitData<F, D> {
|
||||
let mut timing = TimingTree::new("preprocess", Level::Trace);
|
||||
let quotient_degree_factor = 7; // TODO: add this as a parameter.
|
||||
let start = Instant::now();
|
||||
|
||||
// Hash the public inputs, and route them to a `PublicInputGate` which will enforce that
|
||||
@ -541,10 +540,13 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
|
||||
let gates = self.gates.iter().cloned().collect();
|
||||
let (gate_tree, max_filtered_constraint_degree, num_constants) = Tree::from_gates(gates);
|
||||
assert!(
|
||||
max_filtered_constraint_degree <= quotient_degree_factor + 1,
|
||||
"Constraints are too high degree."
|
||||
);
|
||||
// `quotient_degree_factor` has to be between `max_filtered_constraint_degree-1` and `1<<rate_bits`.
|
||||
// We find the value that minimizes `num_partial_product + quotient_degree_factor`.
|
||||
let quotient_degree_factor = (max_filtered_constraint_degree - 1
|
||||
..=1 << self.config.rate_bits)
|
||||
.min_by_key(|&q| num_partial_products(self.config.num_routed_wires, q).0 + q)
|
||||
.unwrap();
|
||||
info!("Quotient degree factor set to: {}.", quotient_degree_factor);
|
||||
let prefixed_gates = PrefixedGate::from_tree(gate_tree);
|
||||
|
||||
let subgroup = F::two_adic_subgroup(degree_bits);
|
||||
@ -555,7 +557,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let sigma_vecs = self.sigma_vecs(&k_is, &subgroup);
|
||||
|
||||
let constants_sigmas_vecs = [constant_vecs, sigma_vecs.clone()].concat();
|
||||
let constants_sigmas_commitment = PolynomialBatchCommitment::new(
|
||||
let constants_sigmas_commitment = PolynomialBatchCommitment::from_values(
|
||||
constants_sigmas_vecs,
|
||||
self.config.rate_bits,
|
||||
self.config.zero_knowledge & PlonkPolynomials::CONSTANTS_SIGMAS.blinding,
|
||||
|
||||
@ -81,7 +81,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let wires_commitment = timed!(
|
||||
timing,
|
||||
"compute wires commitment",
|
||||
PolynomialBatchCommitment::new(
|
||||
PolynomialBatchCommitment::from_values(
|
||||
wires_values,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::WIRES.blinding,
|
||||
@ -125,7 +125,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let zs_partial_products_commitment = timed!(
|
||||
timing,
|
||||
"commit to Z's",
|
||||
PolynomialBatchCommitment::new(
|
||||
PolynomialBatchCommitment::from_values(
|
||||
zs_partial_products,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::ZS_PARTIAL_PRODUCTS.blinding,
|
||||
@ -173,7 +173,7 @@ pub(crate) fn prove<F: Extendable<D>, const D: usize>(
|
||||
let quotient_polys_commitment = timed!(
|
||||
timing,
|
||||
"commit to quotient polys",
|
||||
PolynomialBatchCommitment::new_from_polys(
|
||||
PolynomialBatchCommitment::from_coeffs(
|
||||
all_quotient_poly_chunks,
|
||||
config.rate_bits,
|
||||
config.zero_knowledge & PlonkPolynomials::QUOTIENT.blinding,
|
||||
@ -332,7 +332,7 @@ fn compute_quotient_polys<'a, F: Extendable<D>, const D: usize>(
|
||||
alphas: &[F],
|
||||
) -> Vec<PolynomialCoeffs<F>> {
|
||||
let num_challenges = common_data.config.num_challenges;
|
||||
let max_degree_bits = log2_ceil(common_data.quotient_degree_factor + 1);
|
||||
let max_degree_bits = log2_ceil(common_data.quotient_degree_factor);
|
||||
assert!(
|
||||
max_degree_bits <= common_data.config.rate_bits,
|
||||
"Having constraints of degree higher than the rate is not supported yet. \
|
||||
|
||||
@ -383,7 +383,7 @@ mod tests {
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new())?,
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
@ -391,7 +391,7 @@ mod tests {
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
@ -438,7 +438,7 @@ mod tests {
|
||||
}
|
||||
let data = builder.build();
|
||||
(
|
||||
data.prove(PartialWitness::new())?,
|
||||
data.prove(PartialWitness::new(config.num_wires))?,
|
||||
data.verifier_only,
|
||||
data.common,
|
||||
)
|
||||
@ -446,7 +446,7 @@ mod tests {
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
@ -464,7 +464,7 @@ mod tests {
|
||||
|
||||
verify(proof_with_pis.clone(), &vd, &cd)?;
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
|
||||
let mut pw = PartialWitness::new();
|
||||
let mut pw = PartialWitness::new(config.num_wires);
|
||||
let pt = proof_to_proof_target(&proof_with_pis, &mut builder);
|
||||
set_proof_target(&proof_with_pis, &pt, &mut pw);
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ use anyhow::{ensure, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::fft::FftRootTable;
|
||||
use crate::field::fft::{fft, fft_with_options, ifft};
|
||||
use crate::field::field_types::Field;
|
||||
use crate::util::log2_strict;
|
||||
@ -198,15 +199,33 @@ impl<F: Field> PolynomialCoeffs<F> {
|
||||
fft(self)
|
||||
}
|
||||
|
||||
pub fn fft_with_options(
|
||||
&self,
|
||||
zero_factor: Option<usize>,
|
||||
root_table: Option<FftRootTable<F>>,
|
||||
) -> PolynomialValues<F> {
|
||||
fft_with_options(self, zero_factor, root_table)
|
||||
}
|
||||
|
||||
/// Returns the evaluation of the polynomial on the coset `shift*H`.
|
||||
pub fn coset_fft(&self, shift: F) -> PolynomialValues<F> {
|
||||
self.coset_fft_with_options(shift, None, None)
|
||||
}
|
||||
|
||||
/// Returns the evaluation of the polynomial on the coset `shift*H`.
|
||||
pub fn coset_fft_with_options(
|
||||
&self,
|
||||
shift: F,
|
||||
zero_factor: Option<usize>,
|
||||
root_table: Option<FftRootTable<F>>,
|
||||
) -> PolynomialValues<F> {
|
||||
let modified_poly: Self = shift
|
||||
.powers()
|
||||
.zip(&self.coeffs)
|
||||
.map(|(r, &c)| r * c)
|
||||
.collect::<Vec<_>>()
|
||||
.into();
|
||||
modified_poly.fft()
|
||||
modified_poly.fft_with_options(zero_factor, root_table)
|
||||
}
|
||||
|
||||
pub fn to_extension<const D: usize>(&self) -> PolynomialCoeffs<F::Extension>
|
||||
@ -434,7 +453,7 @@ mod tests {
|
||||
fn test_polynomial_multiplication() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000));
|
||||
let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000));
|
||||
let a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
let b = PolynomialCoeffs::new(F::rand_vec(b_deg));
|
||||
let m1 = &a * &b;
|
||||
@ -450,8 +469,8 @@ mod tests {
|
||||
fn test_inv_mod_xn() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let a_deg = rng.gen_range(1, 1_000);
|
||||
let n = rng.gen_range(1, 1_000);
|
||||
let a_deg = rng.gen_range(1..1_000);
|
||||
let n = rng.gen_range(1..1_000);
|
||||
let a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
let b = a.inv_mod_xn(n);
|
||||
let mut m = &a * &b;
|
||||
@ -472,7 +491,7 @@ mod tests {
|
||||
fn test_polynomial_long_division() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000));
|
||||
let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000));
|
||||
let a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
let b = PolynomialCoeffs::new(F::rand_vec(b_deg));
|
||||
let (q, r) = a.div_rem_long_division(&b);
|
||||
@ -486,7 +505,7 @@ mod tests {
|
||||
fn test_polynomial_division() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let (a_deg, b_deg) = (rng.gen_range(1, 10_000), rng.gen_range(1, 10_000));
|
||||
let (a_deg, b_deg) = (rng.gen_range(1..10_000), rng.gen_range(1..10_000));
|
||||
let a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
let b = PolynomialCoeffs::new(F::rand_vec(b_deg));
|
||||
let (q, r) = a.div_rem(&b);
|
||||
@ -500,7 +519,7 @@ mod tests {
|
||||
fn test_polynomial_division_by_constant() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let a_deg = rng.gen_range(1, 10_000);
|
||||
let a_deg = rng.gen_range(1..10_000);
|
||||
let a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
let b = PolynomialCoeffs::from(vec![F::rand()]);
|
||||
let (q, r) = a.div_rem(&b);
|
||||
@ -514,8 +533,8 @@ mod tests {
|
||||
fn test_division_by_z_h() {
|
||||
type F = CrandallField;
|
||||
let mut rng = thread_rng();
|
||||
let a_deg = rng.gen_range(1, 10_000);
|
||||
let n = rng.gen_range(1, a_deg);
|
||||
let a_deg = rng.gen_range(1..10_000);
|
||||
let n = rng.gen_range(1..a_deg);
|
||||
let mut a = PolynomialCoeffs::new(F::rand_vec(a_deg));
|
||||
a.trim();
|
||||
let z_h = {
|
||||
@ -554,7 +573,7 @@ mod tests {
|
||||
PolynomialCoeffs::new(xn_min_one_vec)
|
||||
};
|
||||
|
||||
let a = g.exp(rng.gen_range(0, n as u64));
|
||||
let a = g.exp(rng.gen_range(0..(n as u64)));
|
||||
let denom = PolynomialCoeffs::new(vec![-a, F::ONE]);
|
||||
let now = Instant::now();
|
||||
xn_minus_one.div_rem(&denom);
|
||||
|
||||
@ -249,6 +249,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let alpha = FF::rand();
|
||||
@ -264,7 +265,7 @@ mod tests {
|
||||
builder.assert_equal_extension(manual_reduce, circuit_reduce);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
@ -276,6 +277,7 @@ mod tests {
|
||||
|
||||
let config = CircuitConfig::large_config();
|
||||
|
||||
let pw = PartialWitness::new(config.num_wires);
|
||||
let mut builder = CircuitBuilder::<F, D>::new(config);
|
||||
|
||||
let alpha = FF::rand();
|
||||
@ -294,7 +296,7 @@ mod tests {
|
||||
builder.assert_equal_extension(manual_reduce, circuit_reduce);
|
||||
|
||||
let data = builder.build();
|
||||
let proof = data.prove(PartialWitness::new())?;
|
||||
let proof = data.prove(pw)?;
|
||||
|
||||
verify(proof, &data.verifier_only, &data.common)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user