From 6f635c10f82a11479eceb019ff26934709186dfa Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Fri, 4 Oct 2024 17:49:43 +0200 Subject: [PATCH 01/10] Implement PartialEq, Eq, Hash for Cell and AssignedCell --- halo2_frontend/src/circuit.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/halo2_frontend/src/circuit.rs b/halo2_frontend/src/circuit.rs index 4f6737854..8bdefe3a2 100644 --- a/halo2_frontend/src/circuit.rs +++ b/halo2_frontend/src/circuit.rs @@ -435,7 +435,7 @@ pub trait Chip: Sized { } /// Index of a region in a layouter -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct RegionIndex(usize); impl From for RegionIndex { @@ -471,7 +471,7 @@ impl std::ops::Deref for RegionStart { } /// A pointer to a cell within a circuit. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Cell { /// Identifies the region in which this cell resides. pub region_index: RegionIndex, @@ -489,6 +489,21 @@ pub struct AssignedCell { _marker: PhantomData, } +impl PartialEq for AssignedCell { + fn eq(&self, other: &Self) -> bool { + self.cell == other.cell + } +} + +impl Eq for AssignedCell {} + +use std::hash::{Hash, Hasher}; +impl Hash for AssignedCell { + fn hash(&self, state: &mut H) { + self.cell.hash(state) + } +} + impl AssignedCell { /// Returns the value of the [`AssignedCell`]. pub fn value(&self) -> Value<&V> { From a486667c091c099f29f28099702841ff0fb199e3 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Tue, 8 Oct 2024 10:21:36 +0200 Subject: [PATCH 02/10] Add table, compressed and normal rows count. --- halo2_frontend/src/dev/cost_model.rs | 56 +++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/halo2_frontend/src/dev/cost_model.rs b/halo2_frontend/src/dev/cost_model.rs index 86ce03800..d1ac7076b 100644 --- a/halo2_frontend/src/dev/cost_model.rs +++ b/halo2_frontend/src/dev/cost_model.rs @@ -51,6 +51,19 @@ pub struct CostOptions { /// 2^K bound on the number of rows. pub k: usize, + + /// Rows count, not including table rows and not accounting for compression + /// (where multiple regions can use the same rows). + pub rows_count: usize, + + /// Table rows count, not accounting for compression (where multiple regions + /// can use the same rows), but not much if any compression can happen with + /// table rows anyway. + pub table_rows_count: usize, + + /// Compressed rows count, accounting for compression (where multiple + /// regions can use the same rows). + pub compressed_rows_count: usize, } /// Structure holding polynomial related data for benchmarks @@ -76,7 +89,7 @@ impl FromStr for Poly { pub struct Lookup; impl Lookup { - fn queries(&self) -> impl Iterator { + pub fn queries(&self) -> impl Iterator { // - product commitments at x and \omega x // - input commitments at x and x_inv // - table commitments at x @@ -98,7 +111,7 @@ pub struct Permutation { } impl Permutation { - fn queries(&self) -> impl Iterator { + pub fn queries(&self) -> impl Iterator { // - product commitments at x and x_inv // - polynomial commitments at x let product = "0,-1".parse().unwrap(); @@ -108,6 +121,10 @@ impl Permutation { .chain(Some(product)) .chain(iter::repeat(poly).take(self.columns)) } + + pub fn nr_columns(&self) -> usize { + self.columns + } } /// Structure holding the [Shuffle] related data for circuit benchmarks. @@ -307,6 +324,38 @@ pub fn from_circuit_to_cost_model_options, .max() .unwrap_or(0); + // Note that this computation does't assume that `regions` is already in + // order of increasing row indices. + let (rows_count, table_rows_count, compressed_rows_count) = { + let mut rows_count = 0; + let mut table_rows_count = 0; + let mut compressed_rows_count = 0; + for region in prover.regions { + // If `region.rows == None`, then that region has no rows. + if let Some((start, end)) = region.rows { + // Note that `end` is the index of the last column, so when + // counting rows this last column needs to be counted via `end + + // 1`. + + // A region is a _table region_ if all of its columns are `Fixed` + // columns (see that [`plonk::circuit::TableColumn` is a wrapper + // around `Column`]). All of a table region's rows are + // counted towards `table_rows_count.` + if region + .columns + .iter() + .all(|c| *c.column_type() == halo2_middleware::circuit::Any::Fixed) + { + table_rows_count += (end + 1) - start; + } else { + rows_count += (end + 1) - start; + } + compressed_rows_count = std::cmp::max(compressed_rows_count, end + 1); + } + } + (rows_count, table_rows_count, compressed_rows_count) + }; + let k = prover.k.try_into().unwrap(); CostOptions { @@ -319,5 +368,8 @@ pub fn from_circuit_to_cost_model_options, permutation, shuffle, k, + rows_count, + table_rows_count, + compressed_rows_count, } } From f88b5e324530f7f4a09e75c1f7dce3952113fd0f Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Wed, 9 Oct 2024 17:59:50 +0200 Subject: [PATCH 03/10] Add rows and table rows to cost model. --- halo2_frontend/src/dev/cost_model.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/halo2_frontend/src/dev/cost_model.rs b/halo2_frontend/src/dev/cost_model.rs index d1ac7076b..b64e19416 100644 --- a/halo2_frontend/src/dev/cost_model.rs +++ b/halo2_frontend/src/dev/cost_model.rs @@ -145,6 +145,10 @@ impl Shuffle { pub struct ModelCircuit { /// Power-of-2 bound on the number of rows in the circuit. pub k: usize, + /// Number of rows in the circuit (not including table rows). + pub rows: usize, + /// Number of table rows in the circuit. + pub table_rows: usize, /// Maximum degree of the circuit. pub max_deg: usize, /// Number of advice columns. @@ -245,6 +249,8 @@ impl CostOptions { ModelCircuit { k: self.k, + rows: self.rows_count, + table_rows: self.table_rows_count, max_deg: self.max_degree, advice_columns: self.advice.len(), lookups: self.lookup.len(), From e2d1fa8dbac9637d98dd28e3c12fecb008169487 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Wed, 9 Oct 2024 18:00:10 +0200 Subject: [PATCH 04/10] Ignore unassigned cells if they are multiplied by zero --- halo2_frontend/src/dev.rs | 76 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/halo2_frontend/src/dev.rs b/halo2_frontend/src/dev.rs index 2958a3202..5756a8b4d 100644 --- a/halo2_frontend/src/dev.rs +++ b/halo2_frontend/src/dev.rs @@ -44,9 +44,11 @@ pub use tfp::TracingFloorPlanner; #[cfg(feature = "dev-graph")] mod graph; +use crate::plonk::circuit::constraint_system::VirtualCell; #[cfg(feature = "dev-graph")] #[cfg_attr(docsrs, doc(cfg(feature = "dev-graph")))] pub use graph::{circuit_dot_graph, layout::CircuitLayout}; +use halo2_middleware::poly::Rotation; /// Region of assignments that are done during synthesis. #[derive(Debug)] @@ -830,7 +832,17 @@ impl + Ord> MockProver { } _ => { // Check that it was assigned! - if r.cells.contains_key(&(cell.column, cell_row)) { + if r.cells.contains_key(&(cell.column, cell_row)) + || gate.polynomials().par_iter().all( + |expr| { + self.cell_is_irrelevant( + cell, + expr, + gate_row as usize, + ) + }, + ) + { None } else { Some(VerifyFailure::CellNotAssigned { @@ -1177,6 +1189,68 @@ impl + Ord> MockProver { } } + // Checks if the given expression is guaranteed to be constantly zero at the given offset. + fn expr_is_constantly_zero(&self, expr: &Expression, offset: usize) -> bool { + match expr { + Expression::Constant(constant) => constant.is_zero().into(), + Expression::Selector(selector) => !self.selectors[selector.0][offset], + Expression::Fixed(query) => match self.fixed[query.column_index][offset] { + CellValue::Assigned(value) => value.is_zero().into(), + _ => false, + }, + Expression::Scaled(e, factor) => { + factor.is_zero().into() || self.expr_is_constantly_zero(e, offset) + } + Expression::Sum(e1, e2) => { + self.expr_is_constantly_zero(e1, offset) && self.expr_is_constantly_zero(e2, offset) + } + Expression::Product(e1, e2) => { + self.expr_is_constantly_zero(e1, offset) || self.expr_is_constantly_zero(e2, offset) + } + _ => false, + } + } + // Verify that the value of the given cell within the given expression is + // irrelevant to the evaluation of the expression. This may be because + // the cell is always multiplied by an expression that evaluates to 0, or + // because the cell is not being queried in the expression at all. + fn cell_is_irrelevant(&self, cell: &VirtualCell, expr: &Expression, offset: usize) -> bool { + // Check if a given query (defined by its columnd and rotation, since we + // want this function to support different query types) is equal to `cell`. + let eq_query = |query_column: usize, query_rotation: Rotation, col_type: Any| { + cell.column.index == query_column + && cell.column.column_type == col_type + && query_rotation == cell.rotation + }; + match expr { + Expression::Constant(_) | Expression::Selector(_) => true, + Expression::Fixed(query) => !eq_query(query.column_index, query.rotation(), Any::Fixed), + Expression::Advice(query) => !eq_query( + query.column_index, + query.rotation(), + Any::Advice, + ), + Expression::Instance(query) => { + !eq_query(query.column_index, query.rotation(), Any::Instance) + } + Expression::Challenge(_) => true, + Expression::Negated(e) => self.cell_is_irrelevant(cell, e, offset), + Expression::Sum(e1, e2) => { + self.cell_is_irrelevant(cell, e1, offset) + && self.cell_is_irrelevant(cell, e2, offset) + } + Expression::Product(e1, e2) => { + (self.expr_is_constantly_zero(e1, offset) + || self.expr_is_constantly_zero(e2, offset)) + || (self.cell_is_irrelevant(cell, e1, offset) + && self.cell_is_irrelevant(cell, e2, offset)) + } + Expression::Scaled(e, factor) => { + factor.is_zero().into() || self.cell_is_irrelevant(cell, e, offset) + } + } + } + /// Panics if the circuit being checked by this `MockProver` is not satisfied. /// /// Any verification failures will be pretty-printed to stderr before the function From dded7aebd64b5616cf53aaa52de9d1e331deec36 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Wed, 9 Oct 2024 18:01:02 +0200 Subject: [PATCH 05/10] Some format values are written as "Scalar(0x..)" The hotfix was to change the stripping rules, but this is probably an incorrect implementation of certain traits for one of the curves. --- halo2_frontend/src/dev/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/halo2_frontend/src/dev/util.rs b/halo2_frontend/src/dev/util.rs index c83a9b849..c91656511 100644 --- a/halo2_frontend/src/dev/util.rs +++ b/halo2_frontend/src/dev/util.rs @@ -63,7 +63,7 @@ pub(super) fn format_value(v: F) -> String { // Format value as hex. let s = format!("{v:?}"); // Remove leading zeroes. - let s = s.strip_prefix("0x").unwrap(); + let s = s.splitn(2, "0x").nth(1).unwrap().splitn(2, ")").nth(0).unwrap(); let s = s.trim_start_matches('0'); format!("0x{s}") } From 68047033a9eb2e1e6055e2998898c6ec1e27d4a0 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Wed, 9 Oct 2024 18:02:03 +0200 Subject: [PATCH 06/10] Update MWV - this is the smalles version with which I could compile. --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 54227249d..aaceec04e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.78.0 +1.80.0 From b0a9549642a517235819069349cc2bcce3b0cf65 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Thu, 10 Oct 2024 10:34:06 +0200 Subject: [PATCH 07/10] Nits --- halo2_backend/src/helpers.rs | 12 +++---- halo2_backend/src/plonk.rs | 34 +++++++++---------- halo2_backend/src/plonk/lookup/prover.rs | 2 ++ halo2_backend/src/plonk/prover.rs | 6 ++-- halo2_debug/src/display.rs | 2 +- .../src/circuit/floor_planner/v1/strategy.rs | 14 -------- halo2_frontend/src/dev.rs | 6 ++-- halo2_frontend/src/dev/util.rs | 2 +- halo2_proofs/src/plonk.rs | 16 ++++----- 9 files changed, 40 insertions(+), 54 deletions(-) diff --git a/halo2_backend/src/helpers.rs b/halo2_backend/src/helpers.rs index 3cd00b84a..ce69fd051 100644 --- a/halo2_backend/src/helpers.rs +++ b/halo2_backend/src/helpers.rs @@ -37,9 +37,9 @@ pub trait SerdeCurveAffine: CurveAffine + SerdeObject { /// Reads an element from the buffer and parses it according to the `format`: /// - `Processed`: Reads a compressed curve element and decompress it /// - `RawBytes`: Reads an uncompressed curve element with coordinates in Montgomery form. - /// Checks that field elements are less than modulus, and then checks that the point is on the curve. + /// Checks that field elements are less than modulus, and then checks that the point is on the curve. /// - `RawBytesUnchecked`: Reads an uncompressed curve element with coordinates in Montgomery form; - /// does not perform any checks + /// does not perform any checks fn read(reader: &mut R, format: SerdeFormat) -> io::Result { match format { SerdeFormat::Processed => ::read(reader), @@ -70,9 +70,9 @@ impl SerdeCurveAffine for C {} pub trait SerdePrimeField: PrimeField + SerdeObject { /// Reads a field element as bytes from the buffer according to the `format`: /// - `Processed`: Reads a field element in standard form, with endianness specified by the - /// `PrimeField` implementation, and checks that the element is less than the modulus. + /// `PrimeField` implementation, and checks that the element is less than the modulus. /// - `RawBytes`: Reads a field element from raw bytes in its internal Montgomery representations, - /// and checks that the element is less than the modulus. + /// and checks that the element is less than the modulus. /// - `RawBytesUnchecked`: Reads a field element in Montgomery form and performs no checks. fn read(reader: &mut R, format: SerdeFormat) -> io::Result { match format { @@ -90,9 +90,9 @@ pub trait SerdePrimeField: PrimeField + SerdeObject { /// Writes a field element as bytes to the buffer according to the `format`: /// - `Processed`: Writes a field element in standard form, with endianness specified by the - /// `PrimeField` implementation. + /// `PrimeField` implementation. /// - Otherwise: Writes a field element into raw bytes in its internal Montgomery representation, - /// WITHOUT performing the expensive Montgomery reduction. + /// WITHOUT performing the expensive Montgomery reduction. fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> { match format { SerdeFormat::Processed => writer.write_all(self.to_repr().as_ref()), diff --git a/halo2_backend/src/plonk.rs b/halo2_backend/src/plonk.rs index ee34d50e3..915cf2d71 100644 --- a/halo2_backend/src/plonk.rs +++ b/halo2_backend/src/plonk.rs @@ -65,11 +65,11 @@ where /// /// Writes a curve element according to `format`: /// - `Processed`: Writes a compressed curve element with coordinates in standard form. - /// Writes a field element in standard form, with endianness specified by the - /// `PrimeField` implementation. + /// Writes a field element in standard form, with endianness specified by the + /// `PrimeField` implementation. /// - Otherwise: Writes an uncompressed curve element with coordinates in Montgomery form - /// Writes a field element into raw bytes in its internal Montgomery representation, - /// WITHOUT performing the expensive Montgomery reduction. + /// Writes a field element into raw bytes in its internal Montgomery representation, + /// WITHOUT performing the expensive Montgomery reduction. pub fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> { // Version byte that will be checked on read. writer.write_all(&[VERSION])?; @@ -90,12 +90,12 @@ where /// /// Reads a curve element from the buffer and parses it according to the `format`: /// - `Processed`: Reads a compressed curve element and decompresses it. - /// Reads a field element in standard form, with endianness specified by the - /// `PrimeField` implementation, and checks that the element is less than the modulus. + /// Reads a field element in standard form, with endianness specified by the + /// `PrimeField` implementation, and checks that the element is less than the modulus. /// - `RawBytes`: Reads an uncompressed curve element with coordinates in Montgomery form. - /// Checks that field elements are less than modulus, and then checks that the point is on the curve. + /// Checks that field elements are less than modulus, and then checks that the point is on the curve. /// - `RawBytesUnchecked`: Reads an uncompressed curve element with coordinates in Montgomery form; - /// does not perform any checks + /// does not perform any checks pub fn read( reader: &mut R, format: SerdeFormat, @@ -302,12 +302,12 @@ where /// /// Writes a curve element according to `format`: /// - `Processed`: Writes a compressed curve element with coordinates in standard form. - /// Writes a field element in standard form, with endianness specified by the - /// `PrimeField` implementation. + /// Writes a field element in standard form, with endianness specified by the + /// `PrimeField` implementation. /// - Otherwise: Writes an uncompressed curve element with coordinates in Montgomery form - /// Writes a field element into raw bytes in its internal Montgomery representation, - /// WITHOUT performing the expensive Montgomery reduction. - /// Does so by first writing the verifying key and then serializing the rest of the data (in the form of field polynomials) + /// Writes a field element into raw bytes in its internal Montgomery representation, + /// WITHOUT performing the expensive Montgomery reduction. + /// Does so by first writing the verifying key and then serializing the rest of the data (in the form of field polynomials) pub fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> { self.vk.write(writer, format)?; self.l0.write(writer, format)?; @@ -325,12 +325,12 @@ where /// /// Reads a curve element from the buffer and parses it according to the `format`: /// - `Processed`: Reads a compressed curve element and decompresses it. - /// Reads a field element in standard form, with endianness specified by the - /// `PrimeField` implementation, and checks that the element is less than the modulus. + /// Reads a field element in standard form, with endianness specified by the + /// `PrimeField` implementation, and checks that the element is less than the modulus. /// - `RawBytes`: Reads an uncompressed curve element with coordinates in Montgomery form. - /// Checks that field elements are less than modulus, and then checks that the point is on the curve. + /// Checks that field elements are less than modulus, and then checks that the point is on the curve. /// - `RawBytesUnchecked`: Reads an uncompressed curve element with coordinates in Montgomery form; - /// does not perform any checks + /// does not perform any checks pub fn read( reader: &mut R, format: SerdeFormat, diff --git a/halo2_backend/src/plonk/lookup/prover.rs b/halo2_backend/src/plonk/lookup/prover.rs index 9f25fe9f1..8d34723fe 100644 --- a/halo2_backend/src/plonk/lookup/prover.rs +++ b/halo2_backend/src/plonk/lookup/prover.rs @@ -59,6 +59,7 @@ pub(in crate::plonk) struct Evaluated { /// obtaining A' and S', and /// - constructs [`Permuted`] struct using permuted_input_value = A', and /// permuted_table_expression = S'. +/// /// The [`Permuted`] struct is used to update the Lookup, and is then returned. #[allow(clippy::too_many_arguments)] pub(in crate::plonk) fn lookup_commit_permuted< @@ -404,6 +405,7 @@ type ExpressionPair = (Polynomial, Polynomial, R: RngCore>( pk: &ProvingKey, diff --git a/halo2_backend/src/plonk/prover.rs b/halo2_backend/src/plonk/prover.rs index af72d863d..ffdb0413c 100644 --- a/halo2_backend/src/plonk/prover.rs +++ b/halo2_backend/src/plonk/prover.rs @@ -325,8 +325,6 @@ impl< let params = self.params; let meta = &self.pk.vk.cs; - let mut rng = &mut self.rng; - let advices = &mut self.advices; let challenges = &mut self.challenges; @@ -406,7 +404,7 @@ impl< for (column_index, advice_values) in column_indices.iter().zip(&mut advice_values) { if !unblinded_advice.contains(column_index) { for cell in &mut advice_values[unusable_rows_start..] { - *cell = Scheme::Scalar::random(&mut rng); + *cell = Scheme::Scalar::random(&mut self.rng); } } else { #[cfg(feature = "sanity-checks")] @@ -423,7 +421,7 @@ impl< if unblinded_advice.contains(i) { Blind::default() } else { - Blind(Scheme::Scalar::random(&mut rng)) + Blind(Scheme::Scalar::random(&mut self.rng)) } }) .collect(); diff --git a/halo2_debug/src/display.rs b/halo2_debug/src/display.rs index f4feba48f..c2e2faed4 100644 --- a/halo2_debug/src/display.rs +++ b/halo2_debug/src/display.rs @@ -10,7 +10,7 @@ use std::fmt; /// - If the value is a power of two, format it as `2^k` /// - If the value is smaller than 2^16, format it in decimal /// - If the value is bigger than congruent -2^16, format it in decimal as the negative congruent -/// (between -2^16 and 0). +/// (between -2^16 and 0). /// - Else format it in hex without leading zeros. pub struct FDisp<'a, F: PrimeField>(pub &'a F); diff --git a/halo2_frontend/src/circuit/floor_planner/v1/strategy.rs b/halo2_frontend/src/circuit/floor_planner/v1/strategy.rs index a5dd0f2ba..8e32d2c33 100644 --- a/halo2_frontend/src/circuit/floor_planner/v1/strategy.rs +++ b/halo2_frontend/src/circuit/floor_planner/v1/strategy.rs @@ -214,22 +214,8 @@ pub(crate) fn slot_in_biggest_advice_first( advice_cols * shape.row_count() }; - // This used to incorrectly use `sort_unstable_by_key` with non-unique keys, which gave - // output that differed between 32-bit and 64-bit platforms, and potentially between Rust - // versions. - // We now use `sort_by_cached_key` with non-unique keys, and rely on `region_shapes` - // being sorted by region index (which we also rely on below to return `RegionStart`s - // in the correct order). - #[cfg(not(feature = "floor-planner-v1-legacy-pdqsort"))] sorted_regions.sort_by_cached_key(sort_key); - // To preserve compatibility, when the "floor-planner-v1-legacy-pdqsort" feature is enabled, - // we use a copy of the pdqsort implementation from the Rust 1.56.1 standard library, fixed - // to its behaviour on 64-bit platforms. - // https://github.com/rust-lang/rust/blob/1.56.1/library/core/src/slice/mod.rs#L2365-L2402 - #[cfg(feature = "floor-planner-v1-legacy-pdqsort")] - halo2_legacy_pdqsort::sort::quicksort(&mut sorted_regions, |a, b| sort_key(a).lt(&sort_key(b))); - sorted_regions.reverse(); // Lay out the sorted regions. diff --git a/halo2_frontend/src/dev.rs b/halo2_frontend/src/dev.rs index 5756a8b4d..14b5894a9 100644 --- a/halo2_frontend/src/dev.rs +++ b/halo2_frontend/src/dev.rs @@ -923,9 +923,9 @@ impl + Ord> MockProver { cell_values: util::cell_values( gate, poly, - &util::load(n, row, &self.cs.fixed_queries, &self.fixed), - &util::load(n, row, &self.cs.advice_queries, &self.advice), - &util::load_instance( + util::load(n, row, &self.cs.fixed_queries, &self.fixed), + util::load(n, row, &self.cs.advice_queries, &self.advice), + util::load_instance( n, row, &self.cs.instance_queries, diff --git a/halo2_frontend/src/dev/util.rs b/halo2_frontend/src/dev/util.rs index c91656511..5445ffb62 100644 --- a/halo2_frontend/src/dev/util.rs +++ b/halo2_frontend/src/dev/util.rs @@ -63,7 +63,7 @@ pub(super) fn format_value(v: F) -> String { // Format value as hex. let s = format!("{v:?}"); // Remove leading zeroes. - let s = s.splitn(2, "0x").nth(1).unwrap().splitn(2, ")").nth(0).unwrap(); + let s = s.split_once("0x").unwrap().1.split(")").next().unwrap(); let s = s.trim_start_matches('0'); format!("0x{s}") } diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 41a2feb2d..8bfbb9270 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -35,12 +35,12 @@ use std::io; /// /// Reads a curve element from the buffer and parses it according to the `format`: /// - `Processed`: Reads a compressed curve element and decompresses it. -/// Reads a field element in standard form, with endianness specified by the -/// `PrimeField` implementation, and checks that the element is less than the modulus. +/// Reads a field element in standard form, with endianness specified by the +/// `PrimeField` implementation, and checks that the element is less than the modulus. /// - `RawBytes`: Reads an uncompressed curve element with coordinates in Montgomery form. -/// Checks that field elements are less than modulus, and then checks that the point is on the curve. +/// Checks that field elements are less than modulus, and then checks that the point is on the curve. /// - `RawBytesUnchecked`: Reads an uncompressed curve element with coordinates in Montgomery form; -/// does not perform any checks +/// does not perform any checks pub fn vk_read>( reader: &mut R, format: SerdeFormat, @@ -63,12 +63,12 @@ where /// /// Reads a curve element from the buffer and parses it according to the `format`: /// - `Processed`: Reads a compressed curve element and decompresses it. -/// Reads a field element in standard form, with endianness specified by the -/// `PrimeField` implementation, and checks that the element is less than the modulus. +/// Reads a field element in standard form, with endianness specified by the +/// `PrimeField` implementation, and checks that the element is less than the modulus. /// - `RawBytes`: Reads an uncompressed curve element with coordinates in Montgomery form. -/// Checks that field elements are less than modulus, and then checks that the point is on the curve. +/// Checks that field elements are less than modulus, and then checks that the point is on the curve. /// - `RawBytesUnchecked`: Reads an uncompressed curve element with coordinates in Montgomery form; -/// does not perform any checks +/// does not perform any checks pub fn pk_read>( reader: &mut R, format: SerdeFormat, From 5bb4fdb74444a9ae97d038f77d7ef091c84b283c Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Thu, 10 Oct 2024 11:06:53 +0200 Subject: [PATCH 08/10] Expose constraint (needed to define the types of `Constraints`) --- halo2_proofs/src/plonk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 8bfbb9270..51a179fdb 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -22,7 +22,7 @@ pub use error::Error; pub use halo2_backend::plonk::{Error as ErrorBack, ProvingKey, VerifyingKey}; pub use halo2_frontend::plonk::{ Advice, Assigned, Assignment, Challenge, Circuit, Column, ColumnType, ConstraintSystem, - Constraints, Error as ErrorFront, Expression, FirstPhase, Fixed, FixedQuery, FloorPlanner, + Constraint, Constraints, Error as ErrorFront, Expression, FirstPhase, Fixed, FixedQuery, FloorPlanner, Instance, Phase, SecondPhase, Selector, TableColumn, ThirdPhase, VirtualCells, }; pub use halo2_middleware::circuit::{Any, ConstraintSystemMid}; From 41eba59cee023905e917482757a36e6b1d07c304 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Mon, 21 Oct 2024 13:32:23 +0200 Subject: [PATCH 09/10] Remove code coverage token --- .github/workflows/coverage.yml | 23 ----------------------- README.md | 2 +- 2 files changed, 1 insertion(+), 24 deletions(-) delete mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index 5b1973892..000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: coverage - -on: [pull_request, push] - -jobs: - coverage: - runs-on: ubuntu-latest - env: - CARGO_TERM_COLOR: always - steps: - - uses: actions/checkout@v4 - - name: Install Rust - run: rustup update stable - - name: Install cargo-llvm-cov - uses: taiki-e/install-action@cargo-llvm-cov - - name: Generate code coverage - run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v4 - with: - token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos - files: lcov.info - fail_ci_if_error: true \ No newline at end of file diff --git a/README.md b/README.md index 432b98607..da1d24b17 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# halo2 [![codecov](https://codecov.io/github/privacy-scaling-explorations/halo2/graph/badge.svg?token=6WX7KBHFIP)](https://codecov.io/github/privacy-scaling-explorations/halo2) +# halo2 ## [Documentation](https://privacy-scaling-explorations.github.io/halo2/halo2_proofs) From 9f0cbf55ed00aa3cabf78f4c8f9594c259acd6b5 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Mon, 21 Oct 2024 13:32:55 +0200 Subject: [PATCH 10/10] Nits --- halo2_frontend/src/dev.rs | 24 ++++++++++-------------- halo2_proofs/src/plonk.rs | 6 +++--- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/halo2_frontend/src/dev.rs b/halo2_frontend/src/dev.rs index 14b5894a9..e017e664b 100644 --- a/halo2_frontend/src/dev.rs +++ b/halo2_frontend/src/dev.rs @@ -833,15 +833,13 @@ impl + Ord> MockProver { _ => { // Check that it was assigned! if r.cells.contains_key(&(cell.column, cell_row)) - || gate.polynomials().par_iter().all( - |expr| { - self.cell_is_irrelevant( - cell, - expr, - gate_row as usize, - ) - }, - ) + || gate.polynomials().par_iter().all(|expr| { + self.cell_is_irrelevant( + cell, + expr, + gate_row as usize, + ) + }) { None } else { @@ -1225,11 +1223,9 @@ impl + Ord> MockProver { match expr { Expression::Constant(_) | Expression::Selector(_) => true, Expression::Fixed(query) => !eq_query(query.column_index, query.rotation(), Any::Fixed), - Expression::Advice(query) => !eq_query( - query.column_index, - query.rotation(), - Any::Advice, - ), + Expression::Advice(query) => { + !eq_query(query.column_index, query.rotation(), Any::Advice) + } Expression::Instance(query) => { !eq_query(query.column_index, query.rotation(), Any::Instance) } diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 51a179fdb..4541d9fdc 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -21,9 +21,9 @@ pub use verifier::verify_proof; pub use error::Error; pub use halo2_backend::plonk::{Error as ErrorBack, ProvingKey, VerifyingKey}; pub use halo2_frontend::plonk::{ - Advice, Assigned, Assignment, Challenge, Circuit, Column, ColumnType, ConstraintSystem, - Constraint, Constraints, Error as ErrorFront, Expression, FirstPhase, Fixed, FixedQuery, FloorPlanner, - Instance, Phase, SecondPhase, Selector, TableColumn, ThirdPhase, VirtualCells, + Advice, Assigned, Assignment, Challenge, Circuit, Column, ColumnType, Constraint, + ConstraintSystem, Constraints, Error as ErrorFront, Expression, FirstPhase, Fixed, FixedQuery, + FloorPlanner, Instance, Phase, SecondPhase, Selector, TableColumn, ThirdPhase, VirtualCells, }; pub use halo2_middleware::circuit::{Any, ConstraintSystemMid};