Serialize and hash custom predicates (#90)

* Print pods from SignedPodBuilder

* Add additional print to test printing SignedPodBuilder

* Mock-prove and print MainPod

* Implement ToFields for custom predicates and dependencies

* Test: print serialization of a recursive batch

* Rearrange serialization of CustomPredicate so args_len is always in the same position

* Serialize predicates with first entry nonzero to avoid collision with padding

* Off by one error in ethdos test BatchSelf(2)

* cargo fmt

* not a typo

* Typos, trying again
This commit is contained in:
tideofwords 2025-02-26 11:28:27 -08:00 committed by GitHub
parent 05c21ebe6a
commit a37b96ab4f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 262 additions and 39 deletions

View file

@ -42,6 +42,13 @@ impl AnchoredKey {
}
}
impl fmt::Display for AnchoredKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}.{}", self.0, self.1)?;
Ok(())
}
}
/// An entry consists of a key-value pair.
pub type Entry = (String, Value);
@ -49,7 +56,7 @@ pub type Entry = (String, Value);
pub struct Value(pub [F; 4]);
impl ToFields for Value {
fn to_fields(self) -> (Vec<F>, usize) {
fn to_fields(&self, params: Params) -> (Vec<F>, usize) {
(self.0.to_vec(), 4)
}
}
@ -132,7 +139,7 @@ impl fmt::Display for Value {
pub struct Hash(pub [F; 4]);
impl ToFields for Hash {
fn to_fields(self) -> (Vec<F>, usize) {
fn to_fields(&self, params: Params) -> (Vec<F>, usize) {
(self.0.to_vec(), 4)
}
}
@ -182,8 +189,8 @@ impl FromHex for Hash {
pub struct PodId(pub Hash);
impl ToFields for PodId {
fn to_fields(self) -> (Vec<F>, usize) {
self.0.to_fields()
fn to_fields(&self, params: Params) -> (Vec<F>, usize) {
self.0.to_fields(params)
}
}
@ -234,7 +241,7 @@ pub fn hash_str(s: &str) -> Hash {
Hash(PoseidonHash::hash_no_pad(&input).elements)
}
#[derive(Clone, Debug, Copy)]
#[derive(Clone, Debug, Copy, PartialEq, Eq)]
pub struct Params {
pub max_input_signed_pods: usize,
pub max_input_main_pods: usize,
@ -243,12 +250,54 @@ pub struct Params {
pub max_public_statements: usize,
pub max_statement_args: usize,
pub max_operation_args: usize,
// max number of statements that can be ANDed or ORed together
// in a custom predicate
pub max_custom_predicate_arity: usize,
pub max_custom_batch_size: usize,
// number of field elements in a hash
pub hash_size: usize,
}
impl Params {
pub fn max_priv_statements(&self) -> usize {
self.max_statements - self.max_public_statements
}
pub fn statement_tmpl_arg_size(self) -> usize {
2 * self.hash_size + 1
}
pub fn predicate_size(self) -> usize {
self.hash_size + 2
}
pub fn statement_tmpl_size(self) -> usize {
self.predicate_size() + self.max_statement_args * self.statement_tmpl_arg_size()
}
pub fn custom_predicate_size(self) -> usize {
self.max_custom_predicate_arity * self.statement_tmpl_size() + 2
}
pub fn custom_predicate_batch_size_field_elts(self) -> usize {
self.max_custom_batch_size * self.custom_predicate_size()
}
pub fn print_serialized_sizes(self) -> () {
println!("Parameter sizes:");
println!(
" Statement template argument: {}",
self.statement_tmpl_arg_size()
);
println!(" Predicate: {}", self.predicate_size());
println!(" Statement template: {}", self.statement_tmpl_size());
println!(" Custom predicate: {}", self.custom_predicate_size());
println!(
" Custom predicate batch: {}",
self.custom_predicate_batch_size_field_elts()
);
println!("");
}
}
impl Default for Params {
@ -261,6 +310,9 @@ impl Default for Params {
max_public_statements: 10,
max_statement_args: 5,
max_operation_args: 5,
max_custom_predicate_arity: 5,
max_custom_batch_size: 5,
hash_size: 4,
}
}
}
@ -328,5 +380,5 @@ pub trait PodProver {
pub trait ToFields {
/// returns Vec<F> representation of the type, and a usize indicating how many field elements
/// does the vector contain
fn to_fields(self) -> (Vec<F>, usize);
fn to_fields(&self, params: Params) -> (Vec<F>, usize);
}