mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-08 20:40:31 +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
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
backtrace = { version = "0.3", optional = true }
|
||||||
bitvec = "0.18"
|
bitvec = "0.18"
|
||||||
subtle = "2.3"
|
subtle = "2.3"
|
||||||
crossbeam-utils = "0.7"
|
crossbeam-utils = "0.7"
|
||||||
|
|
@ -47,4 +48,5 @@ lazy_static = "1.4.0"
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
gadget-traces = ["backtrace"]
|
||||||
sanity-checks = []
|
sanity-checks = []
|
||||||
|
|
|
||||||
106
src/circuit.rs
106
src/circuit.rs
|
|
@ -1,6 +1,6 @@
|
||||||
//! Traits and structs for implementing circuit components.
|
//! Traits and structs for implementing circuit components.
|
||||||
|
|
||||||
use std::fmt;
|
use std::{fmt, marker::PhantomData};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arithmetic::FieldExt,
|
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
|
/// A particular concrete layout strategy will implement this trait for each chip it
|
||||||
/// supports.
|
/// supports.
|
||||||
pub trait Layouter<C: Chip> {
|
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.
|
/// Provides access to the chip configuration.
|
||||||
fn config(&self) -> &C::Config;
|
fn config(&self) -> &C::Config;
|
||||||
|
|
||||||
|
|
@ -155,4 +159,104 @@ pub trait Layouter<C: Chip> {
|
||||||
A: FnMut(Region<'_, C>) -> Result<(), Error>,
|
A: FnMut(Region<'_, C>) -> Result<(), Error>,
|
||||||
N: Fn() -> NR,
|
N: Fn() -> NR,
|
||||||
NR: Into<String>;
|
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> {
|
impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a, C, CS> {
|
||||||
|
type Root = Self;
|
||||||
|
|
||||||
fn config(&self) -> &C::Config {
|
fn config(&self) -> &C::Config {
|
||||||
&self.config
|
&self.config
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +144,22 @@ impl<'a, C: Chip, CS: Assignment<C::Field> + 'a> Layouter<C> for SingleChip<'a,
|
||||||
|
|
||||||
Ok(())
|
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
|
/// 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)
|
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> {
|
impl<F: FieldExt> MockProver<F> {
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,23 @@ pub trait Assignment<F: Field> {
|
||||||
right_column: usize,
|
right_column: usize,
|
||||||
right_row: usize,
|
right_row: usize,
|
||||||
) -> Result<(), Error>;
|
) -> 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
|
/// 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)
|
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`.
|
/// Generate a `VerifyingKey` from an instance of `Circuit`.
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,18 @@ pub fn create_proof<C: CurveAffine, T: TranscriptWrite<C>, ConcreteCircuit: Circ
|
||||||
|
|
||||||
Ok(())
|
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 {
|
let mut witness = WitnessCollection {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue