mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Add namespacing and gadget name collection to Layouter
This commit is contained in:
parent
60061f64fd
commit
bf771a7446
7 changed files with 178 additions and 1 deletions
|
|
@ -34,6 +34,7 @@ name = "plonk"
|
|||
harness = false
|
||||
|
||||
[dependencies]
|
||||
backtrace = { version = "0.3", optional = true }
|
||||
bitvec = "0.18"
|
||||
subtle = "2.3"
|
||||
crossbeam-utils = "0.7"
|
||||
|
|
@ -47,4 +48,5 @@ lazy_static = "1.4.0"
|
|||
static_assertions = "1.1.0"
|
||||
|
||||
[features]
|
||||
gadget-traces = ["backtrace"]
|
||||
sanity-checks = []
|
||||
|
|
|
|||
106
src/circuit.rs
106
src/circuit.rs
|
|
@ -1,6 +1,6 @@
|
|||
//! Traits and structs for implementing circuit components.
|
||||
|
||||
use std::fmt;
|
||||
use std::{fmt, marker::PhantomData};
|
||||
|
||||
use crate::{
|
||||
arithmetic::FieldExt,
|
||||
|
|
@ -136,6 +136,10 @@ impl<'r, C: Chip> Region<'r, C> {
|
|||
/// A particular concrete layout strategy will implement this trait for each chip it
|
||||
/// supports.
|
||||
pub trait Layouter<C: Chip> {
|
||||
/// Represents the type of the "root" of this layouter, so that nested namespaces
|
||||
/// can minimize indirection.
|
||||
type Root: Layouter<C>;
|
||||
|
||||
/// Provides access to the chip configuration.
|
||||
fn config(&self) -> &C::Config;
|
||||
|
||||
|
|
@ -155,4 +159,104 @@ pub trait Layouter<C: Chip> {
|
|||
A: FnMut(Region<'_, C>) -> Result<(), Error>,
|
||||
N: Fn() -> NR,
|
||||
NR: Into<String>;
|
||||
|
||||
/// Gets the "root" of this assignment, bypassing the namespacing.
|
||||
///
|
||||
/// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
|
||||
fn get_root(&mut self) -> &mut Self::Root;
|
||||
|
||||
/// Creates a new (sub)namespace and enters into it.
|
||||
///
|
||||
/// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
|
||||
fn push_namespace<NR, N>(&mut self, name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR;
|
||||
|
||||
/// Exits out of the existing namespace.
|
||||
///
|
||||
/// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
|
||||
fn pop_namespace(&mut self, gadget_name: Option<String>);
|
||||
|
||||
/// Enters into a namespace.
|
||||
fn namespace<NR, N>(&mut self, name_fn: N) -> NamespacedLayouter<'_, C, Self::Root>
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
self.get_root().push_namespace(name_fn);
|
||||
|
||||
NamespacedLayouter(self.get_root(), PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
/// This is a "namespaced" layouter which borrows a `Layouter` (pushing a namespace
|
||||
/// context) and, when dropped, pops out of the namespace context.
|
||||
#[derive(Debug)]
|
||||
pub struct NamespacedLayouter<'a, C: Chip, L: Layouter<C> + 'a>(&'a mut L, PhantomData<C>);
|
||||
|
||||
impl<'a, C: Chip, L: Layouter<C> + 'a> Layouter<C> for NamespacedLayouter<'a, C, L> {
|
||||
type Root = L::Root;
|
||||
|
||||
fn config(&self) -> &C::Config {
|
||||
self.0.config()
|
||||
}
|
||||
|
||||
fn assign_region<A, N, NR>(&mut self, name: N, assignment: A) -> Result<(), Error>
|
||||
where
|
||||
A: FnMut(Region<'_, C>) -> Result<(), Error>,
|
||||
N: Fn() -> NR,
|
||||
NR: Into<String>,
|
||||
{
|
||||
self.0.assign_region(name, assignment)
|
||||
}
|
||||
|
||||
fn get_root(&mut self) -> &mut Self::Root {
|
||||
self.0.get_root()
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
panic!("Only the root's push_namespace should be called");
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, _gadget_name: Option<String>) {
|
||||
panic!("Only the root's pop_namespace should be called");
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, C: Chip, L: Layouter<C> + 'a> Drop for NamespacedLayouter<'a, C, L> {
|
||||
fn drop(&mut self) {
|
||||
let gadget_name = {
|
||||
#[cfg(feature = "gadget-traces")]
|
||||
{
|
||||
let mut gadget_name = None;
|
||||
let mut is_second_frame = false;
|
||||
backtrace::trace(|frame| {
|
||||
if is_second_frame {
|
||||
// Resolve this instruction pointer to a symbol name.
|
||||
backtrace::resolve_frame(frame, |symbol| {
|
||||
gadget_name = symbol.name().map(|name| format!("{:#}", name));
|
||||
});
|
||||
|
||||
// We are done!
|
||||
false
|
||||
} else {
|
||||
// We want the next frame.
|
||||
is_second_frame = true;
|
||||
true
|
||||
}
|
||||
});
|
||||
gadget_name
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "gadget-traces"))]
|
||||
None
|
||||
};
|
||||
|
||||
self.get_root().pop_namespace(gadget_name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ impl<'a, C: Chip, CS: Assignment<C::Field>> SingleChip<'a, C, CS> {
|
|||
}
|
||||
|
||||
impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a, C, CS> {
|
||||
type Root = Self;
|
||||
|
||||
fn config(&self) -> &C::Config {
|
||||
&self.config
|
||||
}
|
||||
|
|
@ -142,6 +144,22 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_root(&mut self) -> &mut Self::Root {
|
||||
self
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
self.cs.push_namespace(name_fn)
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, gadget_name: Option<String>) {
|
||||
self.cs.pop_namespace(gadget_name)
|
||||
}
|
||||
}
|
||||
|
||||
/// The shape of a region. For a region at a certain index, we track
|
||||
|
|
|
|||
12
src/dev.rs
12
src/dev.rs
|
|
@ -213,6 +213,18 @@ impl<F: Field + Group> Assignment<F> for MockProver<F> {
|
|||
|
||||
self.permutations[permutation].copy(left_column, left_row, right_column, right_row)
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// TODO: Do something with namespaces :)
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, _: Option<String>) {
|
||||
// TODO: Do something with namespaces :)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: FieldExt> MockProver<F> {
|
||||
|
|
|
|||
|
|
@ -182,6 +182,23 @@ pub trait Assignment<F: Field> {
|
|||
right_column: usize,
|
||||
right_row: usize,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
/// Creates a new (sub)namespace and enters into it.
|
||||
///
|
||||
/// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
|
||||
///
|
||||
/// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
|
||||
fn push_namespace<NR, N>(&mut self, name_fn: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR;
|
||||
|
||||
/// Exits out of the existing namespace.
|
||||
///
|
||||
/// Not intended for downstream consumption; use [`Layouter::namespace`] instead.
|
||||
///
|
||||
/// [`Layouter::namespace`]: crate::circuit::Layouter#method.namespace
|
||||
fn pop_namespace(&mut self, gadget_name: Option<String>);
|
||||
}
|
||||
|
||||
/// This is a trait that circuits provide implementations for so that the
|
||||
|
|
|
|||
|
|
@ -128,6 +128,18 @@ impl<F: Field> Assignment<F> for Assembly<F> {
|
|||
|
||||
self.permutations[permutation].copy(left_column, left_row, right_column, right_row)
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, _: Option<String>) {
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a `VerifyingKey` from an instance of `Circuit`.
|
||||
|
|
|
|||
|
|
@ -162,6 +162,18 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn push_namespace<NR, N>(&mut self, _: N)
|
||||
where
|
||||
NR: Into<String>,
|
||||
N: FnOnce() -> NR,
|
||||
{
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
|
||||
fn pop_namespace(&mut self, _: Option<String>) {
|
||||
// Do nothing; we don't care about namespaces in this context.
|
||||
}
|
||||
}
|
||||
|
||||
let mut witness = WitnessCollection {
|
||||
|
|
|
|||
Loading…
Reference in a new issue