Skip to content

Commit 64818a7

Browse files
committed
Merge branch 'main' into robknight/custom-predicate-frontend
2 parents 675fde5 + ce26a31 commit 64818a7

31 files changed

+1935
-459
lines changed

.github/workflows/typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ BA = "BA"
44
Ded = "Ded" # "ANDed", it thought "Ded" should be "Dead"
55
OT = "OT"
66
aks = "aks" # anchored keys
7+
nin = "nin" # not in

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ serde_json = "1.0.140"
2424
base64 = "0.22.1"
2525
schemars = "1.0.0-alpha.17"
2626

27+
# Uncomment for debugging with https://github.com/ed255/plonky2/ at branch `feat/debug`. The repo directory needs to be checked out next to the pod2 repo directory.
28+
# [patch."https://github.com/0xPolygonZero/plonky2"]
29+
# plonky2 = { path = "../plonky2/plonky2" }
30+
2731
[features]
2832
default = ["backend_plonky2"]
2933
backend_plonky2 = ["plonky2"]

src/backends/plonky2/circuits/common.rs

Lines changed: 65 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@ use crate::backends::plonky2::basetypes::D;
44
use crate::backends::plonky2::mock::mainpod::Statement;
55
use crate::backends::plonky2::mock::mainpod::{Operation, OperationArg};
66
use crate::middleware::{
7-
NativeOperation, NativePredicate, Params, Predicate, StatementArg, ToFields, Value, F,
8-
HASH_SIZE, VALUE_SIZE,
7+
NativeOperation, NativePredicate, Params, Predicate, StatementArg, ToFields, Value,
8+
EMPTY_VALUE, F, HASH_SIZE, OPERATION_ARG_F_LEN, STATEMENT_ARG_F_LEN, VALUE_SIZE,
99
};
10-
use crate::middleware::{OPERATION_ARG_F_LEN, STATEMENT_ARG_F_LEN};
1110
use anyhow::Result;
1211
use plonky2::field::extension::Extendable;
1312
use plonky2::field::types::{Field, PrimeField64};
@@ -51,29 +50,72 @@ impl ValueTarget {
5150
}
5251
}
5352

53+
#[derive(Clone)]
54+
pub struct StatementArgTarget {
55+
pub elements: [Target; STATEMENT_ARG_F_LEN],
56+
}
57+
58+
impl StatementArgTarget {
59+
pub fn set_targets(
60+
&self,
61+
pw: &mut PartialWitness<F>,
62+
params: &Params,
63+
arg: &StatementArg,
64+
) -> Result<()> {
65+
pw.set_target_arr(&self.elements, &arg.to_fields(params))
66+
}
67+
68+
fn new(first: ValueTarget, second: ValueTarget) -> Self {
69+
let elements: Vec<_> = first
70+
.elements
71+
.into_iter()
72+
.chain(second.elements.into_iter())
73+
.collect();
74+
StatementArgTarget {
75+
elements: elements.try_into().expect("size STATEMENT_ARG_F_LEN"),
76+
}
77+
}
78+
79+
pub fn none(builder: &mut CircuitBuilder<F, D>) -> Self {
80+
let empty = builder.constant_value(EMPTY_VALUE);
81+
Self::new(empty.clone(), empty)
82+
}
83+
84+
pub fn literal(builder: &mut CircuitBuilder<F, D>, value: &ValueTarget) -> Self {
85+
let empty = builder.constant_value(EMPTY_VALUE);
86+
Self::new(value.clone(), empty)
87+
}
88+
89+
pub fn anchored_key(
90+
_builder: &mut CircuitBuilder<F, D>,
91+
pod_id: &ValueTarget,
92+
key: &ValueTarget,
93+
) -> Self {
94+
Self::new(pod_id.clone(), key.clone())
95+
}
96+
}
97+
5498
#[derive(Clone)]
5599
pub struct StatementTarget {
56100
pub predicate: [Target; Params::predicate_size()],
57-
pub args: Vec<[Target; STATEMENT_ARG_F_LEN]>,
101+
pub args: Vec<StatementArgTarget>,
58102
}
59103

60104
impl StatementTarget {
61105
pub fn new_native(
62106
builder: &mut CircuitBuilder<F, D>,
63107
params: &Params,
64108
predicate: NativePredicate,
65-
args: &[[Target; STATEMENT_ARG_F_LEN]],
109+
args: &[StatementArgTarget],
66110
) -> Self {
67111
let predicate_vec = builder.constants(&Predicate::Native(predicate).to_fields(params));
68112
Self {
69113
predicate: array::from_fn(|i| predicate_vec[i]),
70114
args: args
71115
.iter()
72-
.map(|arg| *arg)
73-
.chain(
74-
iter::repeat([builder.zero(); STATEMENT_ARG_F_LEN])
75-
.take(params.max_statement_args - args.len()),
76-
)
116+
.cloned()
117+
.chain(iter::repeat_with(|| StatementArgTarget::none(builder)))
118+
.take(params.max_statement_args)
77119
.collect(),
78120
}
79121
}
@@ -92,7 +134,7 @@ impl StatementTarget {
92134
.take(params.max_statement_args)
93135
.enumerate()
94136
{
95-
pw.set_target_arr(&self.args[i], &arg.to_fields(params))?;
137+
self.args[i].set_targets(pw, params, arg)?;
96138
}
97139
Ok(())
98140
}
@@ -159,7 +201,7 @@ impl Flattenable for StatementTarget {
159201
fn flatten(&self) -> Vec<Target> {
160202
self.predicate
161203
.iter()
162-
.chain(self.args.iter().flatten())
204+
.chain(self.args.iter().flat_map(|a| &a.elements))
163205
.cloned()
164206
.collect()
165207
}
@@ -172,7 +214,11 @@ impl Flattenable for StatementTarget {
172214
);
173215
let predicate: [Target; Params::predicate_size()] = array::from_fn(|i| v[i]);
174216
let args = (0..num_args)
175-
.map(|i| array::from_fn(|j| v[Params::predicate_size() + i * STATEMENT_ARG_F_LEN + j]))
217+
.map(|i| StatementArgTarget {
218+
elements: array::from_fn(|j| {
219+
v[Params::predicate_size() + i * STATEMENT_ARG_F_LEN + j]
220+
}),
221+
})
176222
.collect();
177223

178224
Self { predicate, args }
@@ -192,7 +238,7 @@ pub trait CircuitBuilderPod<F: RichField + Extendable<D>, const D: usize> {
192238

193239
// Convenience methods for checking values.
194240
/// Checks whether `xs` is right-padded with 0s so as to represent a `Value`.
195-
fn statement_arg_is_value(&mut self, xs: &[Target]) -> BoolTarget;
241+
fn statement_arg_is_value(&mut self, arg: &StatementArgTarget) -> BoolTarget;
196242
/// Checks whether `x < y` if `b` is true. This involves checking
197243
/// that `x` and `y` each consist of two `u32` limbs.
198244
fn assert_less_if(&mut self, b: BoolTarget, x: ValueTarget, y: ValueTarget);
@@ -231,7 +277,9 @@ impl CircuitBuilderPod<F, D> for CircuitBuilder<F, D> {
231277
StatementTarget {
232278
predicate: self.add_virtual_target_arr(),
233279
args: (0..params.max_statement_args)
234-
.map(|_| self.add_virtual_target_arr())
280+
.map(|_| StatementArgTarget {
281+
elements: self.add_virtual_target_arr(),
282+
})
235283
.collect(),
236284
}
237285
}
@@ -272,11 +320,11 @@ impl CircuitBuilderPod<F, D> for CircuitBuilder<F, D> {
272320
})
273321
}
274322

275-
fn statement_arg_is_value(&mut self, xs: &[Target]) -> BoolTarget {
323+
fn statement_arg_is_value(&mut self, arg: &StatementArgTarget) -> BoolTarget {
276324
let zeros = iter::repeat(self.zero())
277325
.take(STATEMENT_ARG_F_LEN - VALUE_SIZE)
278326
.collect::<Vec<_>>();
279-
self.is_equal_slice(&xs[VALUE_SIZE..], &zeros)
327+
self.is_equal_slice(&arg.elements[VALUE_SIZE..], &zeros)
280328
}
281329

282330
fn assert_less_if(&mut self, b: BoolTarget, x: ValueTarget, y: ValueTarget) {

0 commit comments

Comments
 (0)