From fab18b3d5f9e59d27262d9626667f79d709f9bbd Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 11:25:49 +0100 Subject: [PATCH 1/6] feat: initial implementation --- Cargo.lock | 211 ++++++++ evm_arithmetization/Cargo.toml | 14 + evm_arithmetization/src/cpu/kernel/ast2.rs | 594 +++++++++++++++++++++ evm_arithmetization/src/cpu/kernel/mod.rs | 1 + evm_arithmetization/tests/parse.rs | 25 + 5 files changed, 845 insertions(+) create mode 100644 evm_arithmetization/src/cpu/kernel/ast2.rs create mode 100644 evm_arithmetization/tests/parse.rs diff --git a/Cargo.lock b/Cargo.lock index 03223ee5f..7ece698e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1049,6 +1049,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "base16ct" version = "0.2.0" @@ -1067,6 +1076,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bit-set" version = "0.5.3" @@ -1717,6 +1732,26 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-quote-to-tokens" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733607c1694b00bf49f2d3a0764549feffe761d0ee59a022ae591cf0617ed013" +dependencies = [ + "syn-helpers", +] + +[[package]] +name = "derive-syn-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "derive_builder" version = "0.20.1" @@ -1875,6 +1910,12 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "either_n" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c91ae510829160d5cfb19eb4ae7b6e01d44b767ca8f727c6cee936e53cc9ae5" + [[package]] name = "elliptic-curve" version = "0.13.8" @@ -2050,15 +2091,21 @@ version = "0.4.0" dependencies = [ "anyhow", "bytes", + "camino", "criterion", + "derive-quote-to-tokens", + "derive-syn-parse", "env_logger 0.11.5", "ethereum-types", + "glob", "hashbrown", "hex", "hex-literal", "itertools 0.13.0", "keccak-hash 0.10.0", + "libtest-mimic", "log", + "logos", "mpt_trie", "num", "num-bigint", @@ -2068,6 +2115,8 @@ dependencies = [ "plonky2", "plonky2_maybe_rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "plonky2_util", + "proc-macro2", + "quote", "rand", "rand_chacha", "ripemd", @@ -2080,8 +2129,11 @@ dependencies = [ "smt_trie", "starky", "static_assertions", + "syn 2.0.77", + "syn-miette", "thiserror", "tiny-keccak", + "winnow", "zk_evm_common", "zk_evm_proc_macro", ] @@ -2726,6 +2778,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -2981,6 +3039,39 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "logos" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax 0.8.4", + "syn 2.0.77", +] + +[[package]] +name = "logos-derive" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +dependencies = [ + "logos-codegen", +] + [[package]] name = "lru" version = "0.12.4" @@ -3011,6 +3102,37 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "miette" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +dependencies = [ + "backtrace", + "backtrace-ext", + "cfg-if", + "miette-derive", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "mime" version = "0.3.17" @@ -3325,6 +3447,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "owo-colors" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" + [[package]] name = "p12-keystore" version = "0.1.3" @@ -4579,6 +4707,12 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "smt_trie" version = "0.1.1" @@ -4697,6 +4831,27 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "supports-color" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "1.0.109" @@ -4719,6 +4874,29 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-helpers" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c391dcee7e7a1efd7dc921922b97b4be54129a195b6baec95bb2a223203d9d" +dependencies = [ + "either_n", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "syn-miette" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd1a2bfae2df81406f8d21baa0253d34ddd0ddafcd1e7aa12aa24279bb76a24b" +dependencies = [ + "miette", + "proc-macro2", + "syn 2.0.77", +] + [[package]] name = "syn-solidity" version = "0.8.3" @@ -4797,6 +4975,27 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.37", + "windows-sys 0.48.0", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.63" @@ -5250,6 +5449,12 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.23" @@ -5259,6 +5464,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-xid" version = "0.2.5" diff --git a/evm_arithmetization/Cargo.toml b/evm_arithmetization/Cargo.toml index ffdb8d2f5..f976d8b54 100644 --- a/evm_arithmetization/Cargo.toml +++ b/evm_arithmetization/Cargo.toml @@ -45,16 +45,27 @@ thiserror = { workspace = true } tiny-keccak = { workspace = true } serde_json = { workspace = true } serde-big-array = { workspace = true } +winnow.workspace = true # Local dependencies mpt_trie = { workspace = true } smt_trie = { workspace = true, optional = true } zk_evm_common = { workspace = true } zk_evm_proc_macro = { workspace = true } +logos = "0.14.2" +syn.workspace = true +proc-macro2.workspace = true +quote.workspace = true +derive-syn-parse = "0.2.0" +derive-quote-to-tokens = "0.1.1" +syn-miette = "0.3.0" +glob = "0.3.1" [dev-dependencies] +camino = "1.1.9" criterion = { workspace = true } hex = { workspace = true } +libtest-mimic = "0.7.3" ripemd = { workspace = true } [features] @@ -76,6 +87,9 @@ harness = false name = "fibonacci_25m_gas" harness = false +[[test]] +name = "parse" +harness = false # Display math equations properly in documentation [package.metadata.docs.rs] diff --git a/evm_arithmetization/src/cpu/kernel/ast2.rs b/evm_arithmetization/src/cpu/kernel/ast2.rs new file mode 100644 index 000000000..ec32ee082 --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/ast2.rs @@ -0,0 +1,594 @@ +//! Span-preserving AST for use by: +//! - The language server, for syntax highlighting, goto definition, etc. +//! - The rest of the compiler. +//! +//! Built on [`syn`], for simplicity. +//! +//! # Non-goals +//! - Representing trivia such as comments. This must be done in a separate step +//! in the language server, as the implementation complexity is not worth it. +//! - A Concrete Syntax Tree for formatting. + +use derive_quote_to_tokens::ToTokens; +use derive_syn_parse::Parse; +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::ext::IdentExt as _; +use syn::parse::{Parse, ParseStream, Peek}; +use syn::punctuated::Punctuated; +use syn::{braced, bracketed, parenthesized, token, Token}; + +/// Keywords +pub mod kw { + macro_rules! keywords { + ($($ident:ident),* $(,)?) => { + $( + ::syn::custom_keyword!($ident); + )* + + /// This is overly strict, but doesn't cost us much. + pub fn peek(input: ::syn::parse::ParseStream) -> bool { + false + $( + || input.peek($ident) + )* + } + }; + } + + keywords! { + all, + any, + BYTES, + cfg, + endmacro, + endrep, + feature, + GLOBAL, + JUMPTABLE, + not, + PROVER_INPUT, + PUSH, + rep, + stack, + } +} + +/// `%`-prefixed keywords. +pub mod pc { + use derive_quote_to_tokens::ToTokens; + use derive_syn_parse::Parse; + use syn::{parse::ParseStream, Token}; + + macro_rules! percent_then { + ($($ident:ident),* $(,)?) => { + $( + #[derive(::derive_syn_parse::Parse, ::derive_quote_to_tokens::ToTokens)] + #[allow(non_camel_case_types, unused)] + pub struct $ident { + pub percent: ::syn::Token![%], + pub $ident: super::kw::$ident, + } + + impl $ident { + pub fn peek(input: ::syn::parse::ParseStream) -> bool { + input.peek(::syn::Token![%]) + && input.peek2(super::kw::$ident) + } + } + )* + }; + } + + percent_then! { + endmacro, + endrep, + rep, + stack, + } + + #[derive(Parse, ToTokens)] + pub struct Macro { + pub percent: Token![%], + pub macro_: Token![macro], + } + + impl Macro { + pub fn peek(input: ParseStream) -> bool { + input.peek(Token![%]) && input.peek2(Token![macro]) + } + } +} + +pub struct File { + pub items: Vec, +} + +impl Parse for File { + fn parse(input: ParseStream) -> syn::Result { + let mut items = vec![]; + while !input.is_empty() { + items.push(input.parse()?) + } + Ok(Self { items }) + } +} + +impl ToTokens for File { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { items } = self; + for item in items { + item.to_tokens(tokens); + } + } +} + +fn peek2pc(input: ParseStream) -> bool { + input.peek(Token![%]) && input.peek2(Token![%]) +} + +fn peek2(token: T) -> impl Fn(ParseStream) -> bool { + move |it| it.peek2(token) +} + +#[derive(ToTokens)] +pub struct Ident(syn::Ident); + +impl Parse for Ident { + fn parse(input: ParseStream) -> syn::Result { + if kw::peek(input) { + return Err(input.error("keywords may not be used as identifiers")); + } + Ok(Self(input.call(syn::Ident::parse_any)?)) + } +} + +impl Ident { + pub fn peek(input: ParseStream) -> bool { + input.fork().parse::().is_ok() + } +} + +pub type Literal = syn::LitInt; + +#[derive(Parse, ToTokens)] +pub struct Variable { + pub dollar: Token![$], + pub ident: Ident, +} + +#[derive(Parse, ToTokens)] +pub struct Constant { + pub at: Token![@], + pub ident: Ident, +} + +#[derive(Parse, ToTokens)] +pub enum Item { + #[peek(Token![#], name = "#[cfg(..)]")] + Cfg(CfgItems), + #[peek_with(pc::Macro::peek, name = "%macro")] + MacroDef(MacroDef), + #[peek_with(pc::rep::peek, name = "%rep")] + Repeat(Repeat), + #[peek_with(pc::stack::peek, name = "%stack")] + Stack(Stack), + #[peek_with(peek2pc, name = "a `%%..` macro decl")] + MacroDecl(MacroDecl), + #[peek(Token![%], name = "MacroCall")] + MacroCall(MacroCall), + #[peek(kw::GLOBAL, name = "GLOBAL")] + GlobalDecl(GlobalDecl), + #[peek(kw::BYTES, name = "BYTES")] + Bytes(Bytes), + #[peek(kw::JUMPTABLE, name = "JUMPTABLE")] + Jumptable(Jumptable), + #[peek(kw::PUSH, name = "PUSH")] + Push(Push), + #[peek(kw::PROVER_INPUT, name = "PROVER_INPUT")] + ProverInput(ProverInput), + #[peek_with(peek2(Token![:]), name = "an `ident:` local decl")] + LocalDecl(LocalDecl), + #[peek_with(Ident::peek, name = "an `ident` instruction")] + Instruction(Instruction), +} + +#[derive(Parse, ToTokens)] +pub struct MacroLabel { + pub percent0: Token![%], + pub percent1: Token![%], + pub ident: Ident, +} + +#[derive(Parse, ToTokens)] +pub struct MacroDecl { + pub label: MacroLabel, + pub colon: Token![:], +} + +pub struct MacroDef { + pub macro_: pc::Macro, + pub ident: Ident, + pub param_list: Option, + pub items: Vec, + pub end_macro: pc::endmacro, +} + +impl Parse for MacroDef { + fn parse(input: ParseStream) -> syn::Result { + Ok(Self { + macro_: input.parse()?, + ident: input.parse()?, + param_list: match input.peek(token::Paren) { + true => Some(input.parse()?), + false => None, + }, + items: { + let mut items = vec![]; + while !pc::endmacro::peek(input) { + items.push(input.parse()?) + } + items + }, + end_macro: input.parse()?, + }) + } +} + +impl ToTokens for MacroDef { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + macro_, + ident, + param_list, + items, + end_macro, + } = self; + macro_.to_tokens(tokens); + ident.to_tokens(tokens); + if let Some(param_list) = param_list { + param_list.to_tokens(tokens); + } + for item in items { + item.to_tokens(tokens) + } + end_macro.to_tokens(tokens); + } +} + +#[derive(Parse)] +pub struct ParamList { + #[paren] + pub paren: token::Paren, + #[inside(paren)] + #[call(Punctuated::parse_terminated)] + pub args: Punctuated, +} + +impl ToTokens for ParamList { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { paren, args } = self; + paren.surround(tokens, |tokens| args.to_tokens(tokens)); + } +} + +#[derive(Parse, ToTokens)] +pub struct MacroCall { + pub percent: Token![%], + pub ident: Ident, + #[peek(token::Paren)] + pub macro_args: Option, +} + +#[derive(Parse)] +pub struct MacroArgs { + #[paren] + pub paren: token::Paren, + #[inside(paren)] + #[call(Punctuated::parse_terminated)] + pub args: Punctuated, +} + +impl ToTokens for MacroArgs { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { paren, args } = self; + paren.surround(tokens, |tokens| args.to_tokens(tokens)); + } +} + +#[derive(Parse, ToTokens)] +pub enum Target { + #[peek(syn::LitInt, name = "Literal")] + Literal(Literal), + #[peek_with(Ident::peek, name = "Ident")] + Ident(Ident), + #[peek_with(peek2pc, name = "a `%%..` macro label")] + MacroLabel(MacroLabel), + #[peek(Token![$], name = "a `$..` variable")] + Variable(Variable), + #[peek(Token![@], name = "a `@..` constant")] + Constant(Constant), +} + +pub struct Repeat { + pub rep: pc::rep, + pub literal: Literal, + pub items: Vec, + pub endrep: pc::endrep, +} + +impl Parse for Repeat { + fn parse(input: ParseStream) -> syn::Result { + Ok(Self { + rep: input.parse()?, + literal: input.parse()?, + items: { + let mut items = vec![]; + while !pc::endrep::peek(input) { + items.push(input.parse()?) + } + items + }, + endrep: input.parse()?, + }) + } +} + +impl ToTokens for Repeat { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + rep, + literal, + items, + endrep, + } = self; + rep.to_tokens(tokens); + literal.to_tokens(tokens); + for item in items { + item.to_tokens(tokens); + } + endrep.to_tokens(tokens); + } +} + +pub struct Stack { + pub stack: pc::stack, + pub placeholders_paren: token::Paren, + pub placeholders: Punctuated, + pub arrow: (Token![-], Token![>]), + pub replacements_paren: token::Paren, + pub replacements: Punctuated, +} + +impl Parse for Stack { + fn parse(input: ParseStream) -> syn::Result { + let placeholders; + let replacements; + Ok(Self { + stack: input.parse()?, + placeholders_paren: parenthesized!(placeholders in input), + placeholders: { Punctuated::parse_terminated(&placeholders)? }, + arrow: (input.parse()?, input.parse()?), + replacements_paren: parenthesized!(replacements in input), + replacements: Punctuated::parse_terminated(&replacements)?, + }) + } +} + +impl ToTokens for Stack { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + stack, + placeholders_paren, + placeholders, + arrow: (arrow0, arrow1), + replacements_paren, + replacements, + } = self; + stack.to_tokens(tokens); + placeholders_paren.surround(tokens, |tokens| placeholders.to_tokens(tokens)); + arrow0.to_tokens(tokens); + arrow1.to_tokens(tokens); + replacements_paren.surround(tokens, |tokens| replacements.to_tokens(tokens)); + } +} + +#[derive(Parse, ToTokens)] +pub enum Placeholder { + #[peek_with(peek2(Token![:]), name = "an `ident:` block")] + Block(Block), + #[peek_with(Ident::peek, name = "an ident")] + Ident(Ident), +} + +#[derive(Parse, ToTokens)] +pub struct Block { + pub ident: Ident, + pub colon: Token![:], + pub number: Literal, +} + +#[derive(Parse, ToTokens)] +pub struct GlobalDecl { + pub global: kw::GLOBAL, + pub ident: Ident, + pub colon: Token![:], +} + +#[derive(Parse, ToTokens)] +pub struct LocalDecl { + pub ident: Ident, + pub colon: Token![:], +} + +#[derive(Parse, ToTokens)] +pub struct Bytes { + pub bytes: kw::BYTES, + #[call(Punctuated::parse_separated_nonempty)] + pub components: Punctuated, +} + +#[derive(Parse, ToTokens)] +pub enum LiteralOrConstant { + #[peek(syn::LitInt, name = "a literal")] + Literal(Literal), + #[peek(Token![@], name = "a `@..` constant")] + Constant(Constant), +} + +#[derive(Parse, ToTokens)] +pub struct Jumptable { + pub jumptable: kw::JUMPTABLE, + #[call(Punctuated::parse_separated_nonempty)] + pub idents: Punctuated, +} + +#[derive(Parse, ToTokens)] +pub struct Push { + pub push: kw::PUSH, + pub target: Target, +} + +#[derive(Parse)] +pub struct ProverInput { + pub prover_input: kw::PROVER_INPUT, + #[paren] + pub paren: token::Paren, + #[inside(paren)] + #[call(Punctuated::parse_separated_nonempty)] + pub function: Punctuated, +} + +impl ToTokens for ProverInput { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + prover_input, + paren, + function, + } = self; + prover_input.to_tokens(tokens); + paren.surround(tokens, |tokens| function.to_tokens(tokens)); + } +} + +#[derive(Parse, ToTokens)] +pub struct Instruction { + pub ident: Ident, +} + +pub struct Cfg { + pub pound: Token![#], + pub bracket: token::Bracket, + pub cfg: kw::cfg, + pub paren: token::Paren, + pub op: Option<(CfgOp, token::Paren)>, + pub feature: kw::feature, + pub eq: Token![=], + pub features: Punctuated, +} + +impl Parse for Cfg { + fn parse(input: ParseStream) -> syn::Result { + let attr; + let mut meta; + Ok(Self { + pound: input.parse()?, + bracket: bracketed!(attr in input), + cfg: attr.parse()?, + paren: parenthesized!(meta in attr), + op: { + match CfgOp::peek(&meta) { + true => Some((meta.parse()?, parenthesized!(meta in meta))), + false => None, + } + }, + feature: meta.parse()?, + eq: meta.parse()?, + features: meta.call(Punctuated::parse_separated_nonempty)?, + }) + } +} + +impl ToTokens for Cfg { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { + pound, + bracket, + cfg, + paren, + op, + feature, + eq, + features, + } = self; + pound.to_tokens(tokens); + bracket.surround(tokens, |tokens| { + cfg.to_tokens(tokens); + paren.surround(tokens, |tokens| { + let inner = |tokens: &mut TokenStream| { + feature.to_tokens(tokens); + eq.to_tokens(tokens); + features.to_tokens(tokens); + }; + match op { + Some((op, paren)) => { + op.to_tokens(tokens); + paren.surround(tokens, inner); + } + None => inner(tokens), + } + }); + }); + } +} + +#[derive(Parse, ToTokens)] +pub enum CfgOp { + #[peek(kw::not, name = "not")] + Not(kw::not), + #[peek(kw::all, name = "all")] + All(kw::all), + #[peek(kw::any, name = "any")] + Any(kw::any), +} + +impl CfgOp { + pub fn peek(input: ParseStream) -> bool { + input.fork().parse::().is_ok() + } +} + +pub struct CfgItems { + pub cfg: Cfg, + pub brace: token::Brace, + pub items: Vec, +} + +impl Parse for CfgItems { + fn parse(input: ParseStream) -> syn::Result { + let content; + Ok(Self { + cfg: input.parse()?, + brace: braced!(content in input), + items: { + let mut items = vec![]; + while !content.is_empty() { + items.push(content.parse()?); + } + items + }, + }) + } +} + +impl ToTokens for CfgItems { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Self { cfg, brace, items } = self; + cfg.to_tokens(tokens); + brace.surround(tokens, |tokens| { + for item in items { + item.to_tokens(tokens); + } + }); + } +} diff --git a/evm_arithmetization/src/cpu/kernel/mod.rs b/evm_arithmetization/src/cpu/kernel/mod.rs index ac8147488..6bb18bc76 100644 --- a/evm_arithmetization/src/cpu/kernel/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/mod.rs @@ -1,6 +1,7 @@ pub mod aggregator; pub mod assembler; mod ast; +pub mod ast2; pub(crate) mod constants; mod cost_estimator; pub(crate) mod keccak_util; diff --git a/evm_arithmetization/tests/parse.rs b/evm_arithmetization/tests/parse.rs new file mode 100644 index 000000000..30540d8b3 --- /dev/null +++ b/evm_arithmetization/tests/parse.rs @@ -0,0 +1,25 @@ +use std::fs; + +use anyhow::Context as _; +use camino::Utf8Path; +use evm_arithmetization::cpu::kernel::ast2; +use libtest_mimic::{Arguments, Failed, Trial}; + +fn main() -> anyhow::Result<()> { + let mut trials = vec![]; + let asm_folder = Utf8Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/src/cpu/kernel/asm/",)); + for entry in glob::glob(&format!("{asm_folder}/**/*.asm"))? { + let path = entry?; + let path = Utf8Path::from_path(&path).context("invalid path")?; + let friendly = path.strip_prefix(asm_folder).unwrap_or(path); + let source = fs::read_to_string(path)?; + trials.push(Trial::test( + friendly.to_owned(), + move || match syn::parse_str::(&source) { + Ok(_) => Ok(()), + Err(e) => Err(Failed::from(syn_miette::Error::new(e, source).render())), + }, + )); + } + libtest_mimic::run(&Arguments::from_args(), trials).exit() +} From 6238d1fb1de26dfb239b4aaeb0ee7da77f4528bd Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 11:27:00 +0100 Subject: [PATCH 2/6] run: sd -F "///" "//" **/*.asm --- .../src/cpu/kernel/asm/beacon_roots.asm | 12 +- .../src/cpu/kernel/asm/bloom_filter.asm | 2 +- .../src/cpu/kernel/asm/cdk_pre_execution.asm | 10 +- .../src/cpu/kernel/asm/core/access_lists.asm | 42 ++-- .../cpu/kernel/asm/core/selfdestruct_list.asm | 10 +- .../cpu/kernel/asm/core/touched_addresses.asm | 6 +- .../bn254/curve_arithmetic/constants.asm | 30 +-- .../bn254/curve_arithmetic/final_exponent.asm | 152 +++++++------- .../bn254/curve_arithmetic/miller_loop.asm | 94 ++++----- .../curve/bn254/curve_arithmetic/pairing.asm | 66 +++--- .../curve_arithmetic/twisted_curve_checks.asm | 8 +- .../twisted_curve_endomorphism.asm | 2 +- .../bn254/field_arithmetic/degree_12_mul.asm | 102 ++++----- .../bn254/field_arithmetic/degree_6_mul.asm | 198 +++++++++--------- .../bn254/field_arithmetic/frobenius.asm | 22 +- .../asm/curve/bn254/field_arithmetic/util.asm | 68 +++--- .../asm/curve/secp256k1/inverse_scalar.asm | 2 +- .../cpu/kernel/asm/curve/secp256k1/moddiv.asm | 2 +- .../src/cpu/kernel/asm/exp.asm | 20 +- .../src/cpu/kernel/asm/hash/ripemd/box.asm | 32 +-- .../kernel/asm/hash/ripemd/compression.asm | 74 +++---- .../cpu/kernel/asm/hash/ripemd/functions.asm | 24 +-- .../src/cpu/kernel/asm/hash/ripemd/main.asm | 38 ++-- .../src/cpu/kernel/asm/hash/ripemd/update.asm | 60 +++--- .../src/cpu/kernel/asm/memory/metadata.asm | 2 +- .../kernel/asm/memory/transient_storage.asm | 24 +-- .../asm/mpt/linked_list/linked_list.asm | 122 +++++------ .../src/cpu/kernel/asm/shift.asm | 6 +- .../src/cpu/kernel/asm/signed.asm | 16 +- .../asm/transactions/common_decoding.asm | 2 +- .../src/cpu/kernel/asm/util/basic_macros.asm | 6 +- 31 files changed, 627 insertions(+), 627 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/beacon_roots.asm b/evm_arithmetization/src/cpu/kernel/asm/beacon_roots.asm index 265d61b90..b78b7154a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/beacon_roots.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/beacon_roots.asm @@ -1,10 +1,10 @@ -/// EIP-4788: Beacon block root in the EVM -/// -/// -/// *NOTE*: This will panic if one of the provided timestamps is zero. +// EIP-4788: Beacon block root in the EVM +// +// +// *NOTE*: This will panic if one of the provided timestamps is zero. -/// Pre-stack: (empty) -/// Post-stack: (empty) +// Pre-stack: (empty) +// Post-stack: (empty) global set_beacon_root: // stack: (empty) PUSH txn_loop diff --git a/evm_arithmetization/src/cpu/kernel/asm/bloom_filter.asm b/evm_arithmetization/src/cpu/kernel/asm/bloom_filter.asm index 35a4ebd76..b6388c283 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/bloom_filter.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/bloom_filter.asm @@ -1,4 +1,4 @@ -/// Implementation of Bloom filters for logs. +// Implementation of Bloom filters for logs. // Adds a Bloom entry to the transaction Bloom filter and the block Bloom filter. // diff --git a/evm_arithmetization/src/cpu/kernel/asm/cdk_pre_execution.asm b/evm_arithmetization/src/cpu/kernel/asm/cdk_pre_execution.asm index fa8828097..640a050fb 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/cdk_pre_execution.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/cdk_pre_execution.asm @@ -1,9 +1,9 @@ -/// CDK-Erigon pre-block execution logic. -/// Reference implementation: `cdk-erigon/core/state/intra_block_state_zkevm.go`. -/// This currently supports the Etrog upgrade. +// CDK-Erigon pre-block execution logic. +// Reference implementation: `cdk-erigon/core/state/intra_block_state_zkevm.go`. +// This currently supports the Etrog upgrade. -/// Pre-stack: (empty) -/// Post-stack: (empty) +// Pre-stack: (empty) +// Post-stack: (empty) global pre_block_execution: // stack: (empty) PUSH txn_loop diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index 84cc4077b..e00e79b23 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -1,10 +1,10 @@ -/// Access lists for addresses and storage keys. -/// The access list is stored in a sorted linked list in SEGMENT_ACCESSED_ADDRESSES for addresses and -/// SEGMENT_ACCESSED_STORAGE_KEYS segment for storage keys. The length of -/// the segments is stored in the global metadata. -/// Both arrays are stored in the kernel memory (context=0). -/// Searching and inserting is done by guessing the predecessor in the list. -/// If the address/storage key isn't found in the array, it is inserted at the end. +// Access lists for addresses and storage keys. +// The access list is stored in a sorted linked list in SEGMENT_ACCESSED_ADDRESSES for addresses and +// SEGMENT_ACCESSED_STORAGE_KEYS segment for storage keys. The length of +// the segments is stored in the global metadata. +// Both arrays are stored in the kernel memory (context=0). +// Searching and inserting is done by guessing the predecessor in the list. +// If the address/storage key isn't found in the array, it is inserted at the end. // Initialize the set of accessed addresses and storage keys with an empty list of the form (@U256_MAX)⮌ // which is written as [@U256_MAX, @SEGMENT_ACCESSED_ADDRESSES] in SEGMENT_ACCESSED_ADDRESSES @@ -89,8 +89,8 @@ global init_access_lists: %endmacro -/// Inserts the address into the access list if it is not already present. -/// Return 1 if the address was inserted, 0 if it was already present. +// Inserts the address into the access list if it is not already present. +// Return 1 if the address was inserted, 0 if it was already present. global insert_accessed_addresses: // stack: addr, retdest PROVER_INPUT(access_lists::address_insert) @@ -172,13 +172,13 @@ insert_new_address: SWAP1 JUMP -/// Remove the address from the access list. -/// Panics if the address is not in the access list. -/// Otherwise it guesses the node before the address (pred) -/// such that (pred)->(next)->(next_next), where the (next) node -/// stores the address. It writes the link (pred)->(next_next) -/// and (next) is marked as deleted by writing U256_MAX in its -/// next node pointer. +// Remove the address from the access list. +// Panics if the address is not in the access list. +// Otherwise it guesses the node before the address (pred) +// such that (pred)->(next)->(next_next), where the (next) node +// stores the address. It writes the link (pred)->(next_next) +// and (next) is marked as deleted by writing U256_MAX in its +// next node pointer. global remove_accessed_addresses: // stack: addr, retdest PROVER_INPUT(access_lists::address_remove) @@ -232,9 +232,9 @@ global remove_accessed_addresses: // stack: ptr %endmacro -/// Inserts the storage key into the access list if it is not already present. -/// Return `1, value_ptr` if the storage key was inserted, `0, value_ptr` if it was already present. -/// Callers to this function must ensure the original storage value is stored at `value_ptr`. +// Inserts the storage key into the access list if it is not already present. +// Return `1, value_ptr` if the storage key was inserted, `0, value_ptr` if it was already present. +// Callers to this function must ensure the original storage value is stored at `value_ptr`. global insert_accessed_storage_keys: // stack: addr, key, retdest PROVER_INPUT(access_lists::storage_insert) @@ -351,8 +351,8 @@ insert_storage_key: %journal_add_storage_loaded JUMP -/// Remove the storage key and its value from the access list. -/// Panics if the key is not in the list. +// Remove the storage key and its value from the access list. +// Panics if the key is not in the list. global remove_accessed_storage_keys: // stack: addr, key, retdest PROVER_INPUT(access_lists::storage_remove) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/selfdestruct_list.asm b/evm_arithmetization/src/cpu/kernel/asm/core/selfdestruct_list.asm index 05e158c34..210b9f92b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/selfdestruct_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/selfdestruct_list.asm @@ -1,6 +1,6 @@ -/// Self-destruct list. -/// Implemented as an array, with the length stored in the global metadata. -/// Note: This array allows duplicates. +// Self-destruct list. +// Implemented as an array, with the length stored in the global metadata. +// Note: This array allows duplicates. %macro insert_selfdestruct_list // stack: addr @@ -13,8 +13,8 @@ %mstore_global_metadata(@GLOBAL_METADATA_SELFDESTRUCT_LIST_LEN) // Store new length. %endmacro -/// Remove one occurrence of the address from the list. -/// No effect if the address is not in the list. +// Remove one occurrence of the address from the list. +// No effect if the address is not in the list. global remove_selfdestruct_list: // stack: addr, retdest %mload_global_metadata(@GLOBAL_METADATA_SELFDESTRUCT_LIST_LEN) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/touched_addresses.asm b/evm_arithmetization/src/cpu/kernel/asm/core/touched_addresses.asm index a8e926e77..94c2d68ae 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/touched_addresses.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/touched_addresses.asm @@ -10,7 +10,7 @@ POP %endmacro -/// Inserts the address into the list if it is not already present. +// Inserts the address into the list if it is not already present. global insert_touched_addresses: // stack: addr, retdest %mload_global_metadata(@GLOBAL_METADATA_TOUCHED_ADDRESSES_LEN) @@ -45,8 +45,8 @@ insert_touched_addresses_found: %stack (i, len, addr, retdest) -> (retdest) JUMP -/// Remove the address from the list. -/// Panics if the address is not in the list. +// Remove the address from the list. +// Panics if the address is not in the list. global remove_touched_addresses: // stack: addr, retdest %mload_global_metadata(@GLOBAL_METADATA_TOUCHED_ADDRESSES_LEN) diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/constants.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/constants.asm index 20882c053..0d1277408 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/constants.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/constants.asm @@ -1,11 +1,11 @@ -/// miller_data is defined by -/// (1) taking the binary expansion of N254, the order of the elliptic curve group -/// (2) popping the first and last elements, then appending a 0: -/// exp = bin(N254)[1:-1] + [0] -/// (3) counting the lengths of runs of 1s then 0s in exp, e.g. -/// if exp = 1100010011110, then EXP = [(2,3), (1,2), (4,1)] -/// (4) byte encoding each pair (n,m) as follows: -/// miller_data = [(0x20)n + m for (n,m) in EXP] +// miller_data is defined by +// (1) taking the binary expansion of N254, the order of the elliptic curve group +// (2) popping the first and last elements, then appending a 0: +// exp = bin(N254)[1:-1] + [0] +// (3) counting the lengths of runs of 1s then 0s in exp, e.g. +// if exp = 1100010011110, then EXP = [(2,3), (1,2), (4,1)] +// (4) byte encoding each pair (n,m) as follows: +// miller_data = [(0x20)n + m for (n,m) in EXP] global miller_data: BYTES 0xdc, 0x22, 0x42, 0x21 @@ -24,13 +24,13 @@ global miller_data: BYTES 0x25 -/// final_exp first computes y^a4, y^a2, y^a0 -/// representing a4, a2, a0 in *little endian* binary, define -/// EXPS4 = [(a4[i], a2[i], a0[i]) for i in 0..len(a4)] -/// EXPS2 = [ (a2[i], a0[i]) for i in len(a4)..len(a2)] -/// EXPS0 = [ a0[i] for i in len(a2)..len(a0)] -/// power_data_n is simply a reverse-order byte encoding of EXPSn -/// where (i,j,k) is sent to (100)i + (10)j + k +// final_exp first computes y^a4, y^a2, y^a0 +// representing a4, a2, a0 in *little endian* binary, define +// EXPS4 = [(a4[i], a2[i], a0[i]) for i in 0..len(a4)] +// EXPS2 = [ (a2[i], a0[i]) for i in len(a4)..len(a2)] +// EXPS0 = [ a0[i] for i in len(a2)..len(a0)] +// power_data_n is simply a reverse-order byte encoding of EXPSn +// where (i,j,k) is sent to (100)i + (10)j + k global power_data_4: BYTES 111, 010, 011, 111 diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/final_exponent.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/final_exponent.asm index 035cb4383..93163c3da 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/final_exponent.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/final_exponent.asm @@ -1,17 +1,17 @@ -/// To make the Tate pairing an invariant, the final step is to exponentiate by -/// (p^12 - 1)/N = (p^6 - 1) * (p^2 + 1) * (p^4 - p^2 + 1)/N -/// and thus we can exponentiate by each factor sequentially. -/// -/// def bn254_final_exponent(y: Fp12): -/// y = first_exp(y) -/// y = second_exp(y) -/// return final_exp(y) +// To make the Tate pairing an invariant, the final step is to exponentiate by +// (p^12 - 1)/N = (p^6 - 1) * (p^2 + 1) * (p^4 - p^2 + 1)/N +// and thus we can exponentiate by each factor sequentially. +// +// def bn254_final_exponent(y: Fp12): +// y = first_exp(y) +// y = second_exp(y) +// return final_exp(y) global bn254_final_exponent: -/// first, exponentiate by (p^6 - 1) via -/// def first_exp(y): -/// return y.frob(6) / y +// first, exponentiate by (p^6 - 1) via +// def first_exp(y): +// return y.frob(6) / y // stack: k, inp, out, retdest {out: y} %stack (k, inp, out) -> (out, 0, first_exp, out) // stack: out, 0, first_exp, out, retdest {out: y} @@ -24,9 +24,9 @@ first_exp: // stack: out, 0, out, second_exp, out, retdest {out: y_6, 0: y^-1} %jump(mul_fp254_12) -/// second, exponentiate by (p^2 + 1) via -/// def second_exp(y): -/// return y.frob(2) * y +// second, exponentiate by (p^2 + 1) via +// def second_exp(y): +// return y.frob(2) * y second_exp: // stack: out, retdest {out: y} %stack (out) -> (out, 0, out, out, final_exp, out) @@ -35,21 +35,21 @@ second_exp: // stack: 0, out, out, final_exp, out, retdest {out: y, 0: y_2} %jump(mul_fp254_12) -/// Finally, we must exponentiate by (p^4 - p^2 + 1)/N -/// To do so efficiently, we can express this power as -/// (p^4 - p^2 + 1)/N = p^3 + (a2)p^2 - (a1)p - a0 -/// and simultaneously compute y^a4, y^a2, y^a0 where -/// a1 = a4 + 2a2 - a0 -/// We first initialize these powers as 1 and then use -/// binary algorithms for exponentiation. -/// -/// def final_exp(y): -/// y4, y2, y0 = 1, 1, 1 -/// power_loop_4() -/// power_loop_2() -/// power_loop_0() -/// custom_powers() -/// final_power() +// Finally, we must exponentiate by (p^4 - p^2 + 1)/N +// To do so efficiently, we can express this power as +// (p^4 - p^2 + 1)/N = p^3 + (a2)p^2 - (a1)p - a0 +// and simultaneously compute y^a4, y^a2, y^a0 where +// a1 = a4 + 2a2 - a0 +// We first initialize these powers as 1 and then use +// binary algorithms for exponentiation. +// +// def final_exp(y): +// y4, y2, y0 = 1, 1, 1 +// power_loop_4() +// power_loop_2() +// power_loop_0() +// custom_powers() +// final_power() final_exp: // stack: val, retdest @@ -74,24 +74,24 @@ final_exp: // stack: 64, 62, 65, 0, val, retdest {0: sqr, 12: y0, 24: y2, 36: y4} %jump(power_loop_4) -/// After computing the powers -/// y^a4, y^a2, y^a0 -/// we would like to transform them to -/// y^a2, y^-a1, y^-a0 -/// -/// def custom_powers() -/// y0 = y0^{-1} -/// y1 = y4 * y2^2 * y0 -/// return y2, y1, y0 -/// -/// And finally, upon doing so, compute the final power -/// y^(p^3) * (y^a2)^(p^2) * (y^-a1)^p * (y^-a0) -/// -/// def final_power() -/// y = y.frob(3) -/// y2 = y2.frob(2) -/// y1 = y1.frob(1) -/// return y * y2 * y1 * y0 +// After computing the powers +// y^a4, y^a2, y^a0 +// we would like to transform them to +// y^a2, y^-a1, y^-a0 +// +// def custom_powers() +// y0 = y0^{-1} +// y1 = y4 * y2^2 * y0 +// return y2, y1, y0 +// +// And finally, upon doing so, compute the final power +// y^(p^3) * (y^a2)^(p^2) * (y^-a1)^p * (y^-a0) +// +// def final_power() +// y = y.frob(3) +// y2 = y2.frob(2) +// y1 = y1.frob(1) +// return y * y2 * y1 * y0 custom_powers: // stack: val, retdest {12: y0, 24: y2, 36: y4} @@ -140,35 +140,35 @@ final_mul: %jump(mul_fp254_12) -/// def power_loop_4(): -/// for i in range(64): -/// abc = load(i, power_data_4) -/// if a: -/// y4 *= acc -/// if b: -/// y2 *= acc -/// if c: -/// y0 *= acc -/// acc = square_fp254_12(acc) -/// y4 *= acc -/// -/// def power_loop_2(): -/// for i in range(62): -/// ab = load(i, power_data_2) -/// if a: -/// y2 *= acc -/// if b: -/// y0 *= acc -/// acc = square_fp254_12(acc) -/// y2 *= acc -/// -/// def power_loop_0(): -/// for i in range(65): -/// a = load(i, power_data_0) -/// if a: -/// y0 *= acc -/// acc = square_fp254_12(acc) -/// y0 *= acc +// def power_loop_4(): +// for i in range(64): +// abc = load(i, power_data_4) +// if a: +// y4 *= acc +// if b: +// y2 *= acc +// if c: +// y0 *= acc +// acc = square_fp254_12(acc) +// y4 *= acc +// +// def power_loop_2(): +// for i in range(62): +// ab = load(i, power_data_2) +// if a: +// y2 *= acc +// if b: +// y0 *= acc +// acc = square_fp254_12(acc) +// y2 *= acc +// +// def power_loop_0(): +// for i in range(65): +// a = load(i, power_data_0) +// if a: +// y0 *= acc +// acc = square_fp254_12(acc) +// y0 *= acc power_loop_4: // stack: i , j, k, sqr {0: sqr, 12: y0, 24: y2, 36: y4} diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm index 99cf24e71..dc99838e1 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/miller_loop.asm @@ -1,29 +1,29 @@ -/// def miller(P, Q): -/// miller_init() -/// miller_loop() -/// -/// def miller_init(): -/// out = 1 -/// O = P -/// times = 61 -/// -/// def miller_loop(): -/// while times: -/// 0xnm = load(miller_data) -/// while 0xnm > 0x20: -/// miller_one() -/// while 0xnm: -/// miller_zero() -/// times -= 1 -/// -/// def miller_one(): -/// 0xnm -= 0x20 -/// mul_tangent() -/// mul_cord() -/// -/// def miller_zero(): -/// 0xnm -= 1 -/// mul_tangent() +// def miller(P, Q): +// miller_init() +// miller_loop() +// +// def miller_init(): +// out = 1 +// O = P +// times = 61 +// +// def miller_loop(): +// while times: +// 0xnm = load(miller_data) +// while 0xnm > 0x20: +// miller_one() +// while 0xnm: +// miller_zero() +// times -= 1 +// +// def miller_one(): +// 0xnm -= 0x20 +// mul_tangent() +// mul_cord() +// +// def miller_zero(): +// 0xnm -= 1 +// mul_tangent() global bn254_miller: // stack: ptr, out, retdest @@ -85,11 +85,11 @@ miller_zero: %jump(mul_tangent) -/// def mul_tangent() -/// out = square_fp254_12(out) -/// line = tangent(O, Q) -/// out = mul_fp254_12_sparse(out, line) -/// O += O +// def mul_tangent() +// out = square_fp254_12(out) +// line = tangent(O, Q) +// out = mul_fp254_12_sparse(out, line) +// O += O mul_tangent: // stack: retdest, 0xnm, times, O, P, Q, out @@ -132,10 +132,10 @@ after_double: // stack: retdest, 0xnm, times, 2*O, P, Q, out {12: line} JUMP -/// def mul_cord() -/// line = cord(P, O, Q) -/// out = mul_fp254_12_sparse(out, line) -/// O += P +// def mul_cord() +// line = cord(P, O, Q) +// out = mul_fp254_12_sparse(out, line) +// O += P mul_cord: // stack: 0xnm, times, O, P, Q, out @@ -179,12 +179,12 @@ after_add: %jump(miller_one) -/// def tangent(px, py, qx, qy): -/// return sparse_store( -/// py**2 - 9, -/// (-3px**2) * qx, -/// (2py) * qy, -/// ) +// def tangent(px, py, qx, qy): +// return sparse_store( +// py**2 - 9, +// (-3px**2) * qx, +// (2py) * qy, +// ) %macro tangent // stack: px, py, qx, qx_, qy, qy_ @@ -239,12 +239,12 @@ after_add: %mstore_bn254_pairing(21) %endmacro -/// def cord(p1x, p1y, p2x, p2y, qx, qy): -/// return sparse_store( -/// p1y*p2x - p2y*p1x, -/// (p2y - p1y) * qx, -/// (p1x - p2x) * qy, -/// ) +// def cord(p1x, p1y, p2x, p2y, qx, qy): +// return sparse_store( +// p1y*p2x - p2y*p1x, +// (p2y - p1y) * qx, +// (p1x - p2x) * qy, +// ) %macro cord // stack: p1x , p1y, p2x , p2y, qx, qx_, qy, qy_ diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm index b1bd2f835..f7dc31c05 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/pairing.asm @@ -1,38 +1,38 @@ -/// The input to the pairing script is a list of points -/// P_i = n_i*G: Curve, Q_i = m_i*H: TwistedCurve -/// where G, H are the respective generators, such that -/// sum_i n_i*m_i = 0 -/// and therefore, due to bilinearity of the pairing: -/// prod_i e(P_i, Q_i) -/// = prod_i e(n_i G, m_i H) -/// = prod_i e(G,H)^{n_i * m_i} -/// = e(G,H)^{sum_i n_i * m_i} -/// = e(G,H)^0 -/// = 1: Fp12 +// The input to the pairing script is a list of points +// P_i = n_i*G: Curve, Q_i = m_i*H: TwistedCurve +// where G, H are the respective generators, such that +// sum_i n_i*m_i = 0 +// and therefore, due to bilinearity of the pairing: +// prod_i e(P_i, Q_i) +// = prod_i e(n_i G, m_i H) +// = prod_i e(G,H)^{n_i * m_i} +// = e(G,H)^{sum_i n_i * m_i} +// = e(G,H)^0 +// = 1: Fp12 -/// def bn254_pairing(pairs: List((Curve, TwistedCurve))) -> Bool: -/// -/// for P, Q in pairs: -/// if not (P.is_valid and Q.is_valid): -/// return @U256_MAX -/// -/// out = 1 -/// for P, Q in pairs: -/// if P != 0 and Q != 0: -/// out *= miller_loop(P, Q) -/// -/// result = bn254_final_exponent(out) -/// return result == unit_fp12 +// def bn254_pairing(pairs: List((Curve, TwistedCurve))) -> Bool: +// +// for P, Q in pairs: +// if not (P.is_valid and Q.is_valid): +// return @U256_MAX +// +// out = 1 +// for P, Q in pairs: +// if P != 0 and Q != 0: +// out *= miller_loop(P, Q) +// +// result = bn254_final_exponent(out) +// return result == unit_fp12 -/// The following is a key to this API -/// -/// - k is the number of inputs -/// - each input given by a pair of points, one on the curve and one on the twisted curve -/// - each input consists of 6 stack terms---2 for the curve point and 4 for the twisted curve point -/// - the inputs are presumed to be placed on the kernel contiguously -/// - the output (as defined above) is an Fp12 element -/// - out and inp are the BnPairing segment offsets for the output element and input -/// - the assembly code currently uses offsets 0-78 for scratch space +// The following is a key to this API +// +// - k is the number of inputs +// - each input given by a pair of points, one on the curve and one on the twisted curve +// - each input consists of 6 stack terms---2 for the curve point and 4 for the twisted curve point +// - the inputs are presumed to be placed on the kernel contiguously +// - the output (as defined above) is an Fp12 element +// - out and inp are the BnPairing segment offsets for the output element and input +// - the assembly code currently uses offsets 0-78 for scratch space global bn254_pairing: // stack: k, inp, out, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_checks.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_checks.asm index c9583498e..08c3cd50d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_checks.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_checks.asm @@ -93,10 +93,10 @@ MUL // Cheaper than AND %endmacro -/// The `ECPAIRING` precompile requires checking that G2 -/// inputs are on the correct prime-order subgroup. -/// This macro performs this check, based on the algorithm -/// detailed in . +// The `ECPAIRING` precompile requires checking that G2 +// inputs are on the correct prime-order subgroup. +// This macro performs this check, based on the algorithm +// detailed in . %macro bn_check_twisted_subgroup // stack: Q = (X, Y) %dup_bn_g2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_endomorphism.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_endomorphism.asm index dfe819ef8..afc5972d4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_endomorphism.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/twisted_curve_endomorphism.asm @@ -1,6 +1,6 @@ // Implementation of the BN254 twist endomorphism. -/// Frobenius map over BN254 quadratic extension. +// Frobenius map over BN254 quadratic extension. %macro frob_fp254_2 // stack: X = (x, x_) %conj_fp254_2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_12_mul.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_12_mul.asm index 45016ed15..c01f8f795 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_12_mul.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_12_mul.asm @@ -1,21 +1,21 @@ -/////////////////////////////////////// -///// GENERAL FP12 MULTIPLICATION ///// -/////////////////////////////////////// +////////////////////////// +//// GENERAL FP12 MULTIPLICATION //// +////////////////////////// -/// inputs: -/// F = f + f'z -/// G = g + g'z -/// -/// output: -/// H = h + h'z = FG -/// -/// h = fg + sh(f'g') -/// h' = (f+f')(g+g') - fg - f'g' -/// -/// memory pointers [ind' = ind+6] -/// {inA: f, inA: f', inB: g, inB':g', out: h, out': h'} -/// -/// f, f', g, g' consist of six elements on the stack +// inputs: +// F = f + f'z +// G = g + g'z +// +// output: +// H = h + h'z = FG +// +// h = fg + sh(f'g') +// h' = (f+f')(g+g') - fg - f'g' +// +// memory pointers [ind' = ind+6] +// {inA: f, inA: f', inB: g, inB':g', out: h, out': h'} +// +// f, f', g, g' consist of six elements on the stack global mul_fp254_12: // stack: inA, inB, out @@ -111,25 +111,25 @@ mul_fp254_12_3: JUMP -////////////////////////////////////// -///// SPARSE FP12 MULTIPLICATION ///// -////////////////////////////////////// +////////////////////////// +//// SPARSE FP12 MULTIPLICATION //// +////////////////////////// -/// input: -/// F = f + f'z -/// G = g0 + (G1)t + (G2)tz -/// -/// output: -/// H = h + h'z = FG -/// = g0 * [f + f'z] + G1 * [sh(f) + sh(f')z] + G2 * [sh2(f') + sh(f)z] -/// -/// h = g0 * f + G1 * sh(f ) + G2 * sh2(f') -/// h' = g0 * f' + G1 * sh(f') + G2 * sh (f ) -/// -/// memory pointers [ind' = ind+6, inB2 = inB1 + 2 = inB + 3] -/// { inA: f, inA': f', inB: g0, inB1: G1, inB2: G2, out: h, out': h'} -/// -/// f, f' consist of six elements; G1, G1' consist of two elements; and g0 of one element +// input: +// F = f + f'z +// G = g0 + (G1)t + (G2)tz +// +// output: +// H = h + h'z = FG +// = g0 * [f + f'z] + G1 * [sh(f) + sh(f')z] + G2 * [sh2(f') + sh(f)z] +// +// h = g0 * f + G1 * sh(f ) + G2 * sh2(f') +// h' = g0 * f' + G1 * sh(f') + G2 * sh (f ) +// +// memory pointers [ind' = ind+6, inB2 = inB1 + 2 = inB + 3] +// { inA: f, inA': f', inB: g0, inB1: G1, inB2: G2, out: h, out': h'} +// +// f, f' consist of six elements; G1, G1' consist of two elements; and g0 of one element global mul_fp254_12_sparse: // stack: inA, inB, out @@ -224,23 +224,23 @@ global mul_fp254_12_sparse: JUMP -///////////////////////// -///// FP12 SQUARING ///// -///////////////////////// +///////////////// +//// FP12 SQUARING //// +///////////////// -/// input: -/// F = f + f'z -/// -/// output: -/// H = h + h'z = FF -/// -/// h = ff + sh(f'f') -/// h' = 2ff' -/// -/// memory pointers [ind' = ind+6] -/// {inp: f, inp: f', out: h, out': h'} -/// -/// f, f' consist of six elements on the stack +// input: +// F = f + f'z +// +// output: +// H = h + h'z = FF +// +// h = ff + sh(f'f') +// h' = 2ff' +// +// memory pointers [ind' = ind+6] +// {inp: f, inp: f', out: h, out': h'} +// +// f, f' consist of six elements on the stack global square_fp254_12: // stack: inp, out diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_6_mul.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_6_mul.asm index db8b09e0c..00f30e34b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_6_mul.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/degree_6_mul.asm @@ -1,62 +1,62 @@ -////////////////////////////////////// -///// GENERAL FP6 MULTIPLICATION ///// -////////////////////////////////////// +////////////////////////// +//// GENERAL FP6 MULTIPLICATION //// +////////////////////////// -/// inputs: -/// C = C0 + C1t + C2t^2 -/// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 -/// -/// D = D0 + D1t + D2t^2 -/// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 -/// -/// output: -/// E = E0 + E1t + E2t^2 = CD -/// = (e0 + e0_i) + (e1 + e1_i)t + (e2 + e2_i)t^2 -/// -/// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest -/// final stack: e0, e0_, e1, e1_, e2, e2_ +// inputs: +// C = C0 + C1t + C2t^2 +// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 +// +// D = D0 + D1t + D2t^2 +// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 +// +// output: +// E = E0 + E1t + E2t^2 = CD +// = (e0 + e0_i) + (e1 + e1_i)t + (e2 + e2_i)t^2 +// +// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest +// final stack: e0, e0_, e1, e1_, e2, e2_ -/// computations: -/// -/// E0 = C0D0 + i9(C1D2 + C2D1) -/// -/// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i -/// -/// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i -/// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i -/// -/// CD12 = C1D2 + C2D1 -/// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i -/// -/// i9(CD12) = (9CD12 - CD12_) + (CD12 + 9CD12_)i -/// -/// e0 = 9CD12 - CD12_ + C0D0 -/// e0_ = 9CD12_ + CD12 + C0D0_ -/// -/// -/// E1 = C0D1 + C1D0 + i9(C2D2) -/// -/// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i -/// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i -/// -/// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) -/// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 -/// -/// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i -/// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i -/// -/// e1 = 9C2D2 - C2D2_ + CD01 -/// e1_ = C2D2 + 9C2D2_ + CD01_ -/// -/// -/// E2 = C0D2 + C1D1 + C2D0 -/// -/// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i -/// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i -/// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i -/// -/// e2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) -/// e2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 +// computations: +// +// E0 = C0D0 + i9(C1D2 + C2D1) +// +// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i +// +// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i +// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i +// +// CD12 = C1D2 + C2D1 +// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i +// +// i9(CD12) = (9CD12 - CD12_) + (CD12 + 9CD12_)i +// +// e0 = 9CD12 - CD12_ + C0D0 +// e0_ = 9CD12_ + CD12 + C0D0_ +// +// +// E1 = C0D1 + C1D0 + i9(C2D2) +// +// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i +// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i +// +// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) +// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 +// +// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i +// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i +// +// e1 = 9C2D2 - C2D2_ + CD01 +// e1_ = C2D2 + 9C2D2_ + CD01_ +// +// +// E2 = C0D2 + C1D1 + C2D0 +// +// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i +// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i +// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i +// +// e2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) +// e2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 // cost: 157 global mul_fp254_6: @@ -261,48 +261,48 @@ global mul_fp254_6: JUMP -//////////////////////// -///// FP6 SQUARING ///// -//////////////////////// +//////////////// +//// FP6 SQUARING //// +//////////////// -/// inputs: -/// C = C0 + C1t + C2t^2 -/// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 -/// -/// output: -/// E = E0 + E1t + E2t^2 = C^2 -/// = (e0 + e0_i) + (e1 + e1_i)t + (e2 + e2_i)t^2 -/// -/// initial stack: c0, c0_, c1, c1_, c2, c2_, retdest -/// final stack: e0, e0_, e1, e1_, e2, e2_ +// inputs: +// C = C0 + C1t + C2t^2 +// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 +// +// output: +// E = E0 + E1t + E2t^2 = C^2 +// = (e0 + e0_i) + (e1 + e1_i)t + (e2 + e2_i)t^2 +// +// initial stack: c0, c0_, c1, c1_, c2, c2_, retdest +// final stack: e0, e0_, e1, e1_, e2, e2_ -/// computations: -/// -/// E0 = C0C0 + i9(2C1C2) = (c0+c0_i)^2 + i9(2(c1+c1_i)(c2+c2_i)) -/// = (c0^2 - c0_^2) + (2c0c0_)i + i9[2(c1c2 - c1_c2_) + 2(c1_c2 + c1c2_)i] -/// -/// E1 = 2*C0C1 + i9(C2C2) = 2(c0+c0_i)(c1+c1_i) + i9((c2+c2_i)(c2+c2_i)) -/// = 2(c0c1 - c0_c1_) + 2(c0c1_ + c0_c1)i + i9[(c2^2 - c2_^2) + (2c2c2_)i] -/// -/// E2 = 2*C0C2 + C1C1 -/// = 2(c0c2 - c0_c2_) + 2(c0_c2 + c2c0_)i + (c1^2 - c1_^2) + (2c1c1_)i -/// -/// e0 = (c0^2 - c0_^2) + x0 -/// e0_ = 2c0c0_ + x0_ -/// where x0_, x0 = %i9 c1c2 - c1_c2_, c1_c2 + c1c2_ -/// -/// e1 = 2(c0c1 - c0_c1_) + x1 -/// e1_ = 2(c0c1_ + c0_c1) + x1_ -/// where x1_, x1 = %i9 c2^2 - c2_^2, 2c2c2_ -/// -/// e2 = 2(c0c2 - c0_c2_) + (c1^2 - c1_^2) -/// e2_ = 2(c0_c2 + c2c0_) + 2c1c1_ +// computations: +// +// E0 = C0C0 + i9(2C1C2) = (c0+c0_i)^2 + i9(2(c1+c1_i)(c2+c2_i)) +// = (c0^2 - c0_^2) + (2c0c0_)i + i9[2(c1c2 - c1_c2_) + 2(c1_c2 + c1c2_)i] +// +// E1 = 2*C0C1 + i9(C2C2) = 2(c0+c0_i)(c1+c1_i) + i9((c2+c2_i)(c2+c2_i)) +// = 2(c0c1 - c0_c1_) + 2(c0c1_ + c0_c1)i + i9[(c2^2 - c2_^2) + (2c2c2_)i] +// +// E2 = 2*C0C2 + C1C1 +// = 2(c0c2 - c0_c2_) + 2(c0_c2 + c2c0_)i + (c1^2 - c1_^2) + (2c1c1_)i +// +// e0 = (c0^2 - c0_^2) + x0 +// e0_ = 2c0c0_ + x0_ +// where x0_, x0 = %i9 c1c2 - c1_c2_, c1_c2 + c1c2_ +// +// e1 = 2(c0c1 - c0_c1_) + x1 +// e1_ = 2(c0c1_ + c0_c1) + x1_ +// where x1_, x1 = %i9 c2^2 - c2_^2, 2c2c2_ +// +// e2 = 2(c0c2 - c0_c2_) + (c1^2 - c1_^2) +// e2_ = 2(c0_c2 + c2c0_) + 2c1c1_ // cost: 101 global square_fp254_6: - /// e0 = (c0^2 - c0_^2) + x0 - /// e0_ = 2c0c0_ + x0_ - /// where x0_, x0 = %i9 2(c1c2 - c1_c2_), 2(c1_c2 + c1c2_) + // e0 = (c0^2 - c0_^2) + x0 + // e0_ = 2c0c0_ + x0_ + // where x0_, x0 = %i9 2(c1c2 - c1_c2_), 2(c1_c2 + c1c2_) DUP6 DUP4 MULFP254 @@ -346,9 +346,9 @@ global square_fp254_6: // stack: e0 SWAP3 - /// e1 = 2(c0c1 - c0_c1_) + x1 - /// e1_ = 2(c0c1_ + c0_c1 ) + x1_ - /// where x1_, x1 = %i9 c2^2 - c2_^2, 2c2c2_ + // e1 = 2(c0c1 - c0_c1_) + x1 + // e1_ = 2(c0c1_ + c0_c1 ) + x1_ + // where x1_, x1 = %i9 c2^2 - c2_^2, 2c2c2_ DUP7 DUP9 MULFP254 @@ -391,8 +391,8 @@ global square_fp254_6: ADDFP254 SWAP7 - /// e2 = 2(c0c2 - c0_c2_) + (c1^2 - c1_^2) - /// e2_ = 2(c0_c2 + c2c0_ + c1c1_) + // e2 = 2(c0c2 - c0_c2_) + (c1^2 - c1_^2) + // e2_ = 2(c0_c2 + c2c0_ + c1c1_) DUP1 DUP1 MULFP254 diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/frobenius.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/frobenius.asm index ee1e46791..81117a3a9 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/frobenius.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/frobenius.asm @@ -27,10 +27,10 @@ global test_frob_fp254_12_6: %jump(0xdeadbeef) -/// def frob_fp254_12_n(f, f'): -/// g = frob_fp254_6(n, f ) -/// g' = FROB_z[n] * frob_fp254_6(n, f') -/// return g, g' +// def frob_fp254_12_n(f, f'): +// g = frob_fp254_6(n, f ) +// g' = FROB_z[n] * frob_fp254_6(n, f') +// return g, g' %macro frob_fp254_12_1 // stack: ptr @@ -140,14 +140,14 @@ global test_frob_fp254_6_3: %jump(0xdeadbeef) -/// let Z` denote the complex conjugate of Z +// let Z` denote the complex conjugate of Z -/// def frob_fp254_6_n(C0, C1, C2): -/// if n%2: -/// D0, D1, D2 = C0`, FROB_T1[n] * C1`, FROB_T2[n] * C2` -/// else: -/// D0, D1, D2 = C0 , FROB_T1[n] * C1 , FROB_T2[n] * C2 -/// return D0, D1, D2 +// def frob_fp254_6_n(C0, C1, C2): +// if n%2: +// D0, D1, D2 = C0`, FROB_T1[n] * C1`, FROB_T2[n] * C2` +// else: +// D0, D1, D2 = C0 , FROB_T1[n] * C1 , FROB_T2[n] * C2 +// return D0, D1, D2 %macro frob_fp254_6_1 // stack: C0 , C1 , C2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm index ee9dd7ffa..7b391e421 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/bn254/field_arithmetic/util.asm @@ -62,7 +62,7 @@ // stack: x0, x1 %endmacro -/// complex conjugate +// complex conjugate %macro conj_fp254_2 // stack: a, b SWAP1 @@ -125,9 +125,9 @@ // stack: z, z_ %endmacro -/// Given z = x + iy: Fp254_2, return complex conjugate z': Fp254_2 -/// where input is represented z.re, z.im and output as z'.im, z'.re -/// cost: 9; note this returns y, x for the output x + yi +// Given z = x + iy: Fp254_2, return complex conjugate z': Fp254_2 +// where input is represented z.re, z.im and output as z'.im, z'.re +// cost: 9; note this returns y, x for the output x + yi %macro i9 // stack: a , b DUP2 @@ -540,8 +540,8 @@ // stack: f: 6, X: 8, f: 6 %endmacro -/// multiply (a + bt + ct^2) by t: -/// t(a + bt + ct^2) = at + bt^2 + ct^3 = (9+i)c + at + bt^2 +// multiply (a + bt + ct^2) by t: +// t(a + bt + ct^2) = at + bt^2 + ct^3 = (9+i)c + at + bt^2 %macro sh_fp254_6 // stack: a, b, c %stack (a: 2, b: 2, c: 2) -> (c, a, b) @@ -669,14 +669,14 @@ // stack: c * f0, c * f1, c * f2, c * f3, c * f4, c * f5 %endmacro -/// cost: -/// -/// G0 + G1t + G2t^2 = (a+bi) * (F0 + F1t + F2t^2) -/// = (a+bi)F0 + (a+bi)F1t + (a+bi)F2t^2 -/// -/// G0 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i -/// G1 = (a+bi)(f1+f1_i) = (af1 - bf1_) + (bf1 + af1_)i -/// G2 = (a+bi)(f2+f2_i) = (af2 - bf2_) + (bf2 + af2_)i +// cost: +// +// G0 + G1t + G2t^2 = (a+bi) * (F0 + F1t + F2t^2) +// = (a+bi)F0 + (a+bi)F1t + (a+bi)F2t^2 +// +// G0 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i +// G1 = (a+bi)(f1+f1_i) = (af1 - bf1_) + (bf1 + af1_)i +// G2 = (a+bi)(f2+f2_i) = (af2 - bf2_) + (bf2 + af2_)i %macro scale_fp254_6 // stack: a, b, f0, f0_, f1, f1_, f2, f2_ @@ -759,15 +759,15 @@ // stack: g0, g0_, g1, g1_, g2, g2_ %endmacro -/// cost: 1 i9 (9) + 16 dups + 15 swaps + 12 muls + 6 adds/subs = 58 -/// -/// G0 + G1t + G2t^2 = (a+bi)t * (F0 + F1t + F2t^2) -/// = (c+di)F2 + (a+bi)F0t + (a+bi)F1t^2 -/// where c+di = (a+bi)(9+i) = (9a-b) + (a+9b)i -/// -/// G0 = (c+di)(f2+f2_i) = (cf2 - df2_) + (df2 + cf2_)i -/// G1 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i -/// G2 = (a+bi)(f1+f1_i) = (af1 - bf1_) + (bf1 + af1_)i +// cost: 1 i9 (9) + 16 dups + 15 swaps + 12 muls + 6 adds/subs = 58 +// +// G0 + G1t + G2t^2 = (a+bi)t * (F0 + F1t + F2t^2) +// = (c+di)F2 + (a+bi)F0t + (a+bi)F1t^2 +// where c+di = (a+bi)(9+i) = (9a-b) + (a+9b)i +// +// G0 = (c+di)(f2+f2_i) = (cf2 - df2_) + (df2 + cf2_)i +// G1 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i +// G2 = (a+bi)(f1+f1_i) = (af1 - bf1_) + (bf1 + af1_)i %macro scale_fp254_6_sh // stack: a, b, f0, f0_, f1, f1_, f2, f2_ @@ -853,15 +853,15 @@ // stack: g0, g0_, g1, g1_, g2, g2_ %endmacro -/// cost: 1 i9 (9) + 16 dups + 17 swaps + 12 muls + 6 adds/subs = 60 -/// -/// G0 + G1t + G2t^2 = (a+bi)t^2 * (F0 + F1t + F2t^2) -/// = (c+di)F1 + (c+di)F2t + (a+bi)F0t^2 -/// where c+di = (a+bi)(9+i) = (9a-b) + (a+9b)i -/// -/// G0 = (c+di)(f1+f1_i) = (cf1 - df1_) + (df1 + cf1_)i -/// G1 = (a+bi)(f2+f2_i) = (cf2 - df2_) + (df2 + cf2_)i -/// G2 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i +// cost: 1 i9 (9) + 16 dups + 17 swaps + 12 muls + 6 adds/subs = 60 +// +// G0 + G1t + G2t^2 = (a+bi)t^2 * (F0 + F1t + F2t^2) +// = (c+di)F1 + (c+di)F2t + (a+bi)F0t^2 +// where c+di = (a+bi)(9+i) = (9a-b) + (a+9b)i +// +// G0 = (c+di)(f1+f1_i) = (cf1 - df1_) + (df1 + cf1_)i +// G1 = (a+bi)(f2+f2_i) = (cf2 - df2_) + (df2 + cf2_)i +// G2 = (a+bi)(f0+f0_i) = (af0 - bf0_) + (bf0 + af0_)i %macro scale_fp254_6_sh2 // stack: a, b, f0, f0_, f1, f1_, f2, f2_ @@ -1076,8 +1076,8 @@ // stack: %endmacro -/// moves fp254_12 from src..src+12 to dest..dest+12 -/// these should not overlap. leaves scaled DEST on stack +// moves fp254_12 from src..src+12 to dest..dest+12 +// these should not overlap. leaves scaled DEST on stack %macro move_fp254_12 // stack: src, dest PUSH @SEGMENT_BN_PAIRING diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/inverse_scalar.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/inverse_scalar.asm index f10242bc3..b3e80c85c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/inverse_scalar.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/inverse_scalar.asm @@ -1,4 +1,4 @@ -/// Division modulo 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141, the Secp256k1 scalar field order +// Division modulo 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141, the Secp256k1 scalar field order %macro mulmodn_secp_scalar // stack: x, y diff --git a/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/moddiv.asm b/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/moddiv.asm index f9fbd624b..080e27403 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/moddiv.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/curve/secp256k1/moddiv.asm @@ -1,4 +1,4 @@ -/// Division modulo 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f, the Secp256k1 base field order +// Division modulo 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f, the Secp256k1 base field order // Returns y * (x^-1) where the inverse is taken modulo N %macro moddiv_secp_base diff --git a/evm_arithmetization/src/cpu/kernel/asm/exp.asm b/evm_arithmetization/src/cpu/kernel/asm/exp.asm index 4b798e841..83b9682ae 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/exp.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/exp.asm @@ -1,13 +1,13 @@ -/// Recursive implementation of exp. -/// Equivalent to: -/// def exp(x, e): -/// if e == 0: -/// # The path where JUMPI does not jump to `step_case` -/// return 1 -/// else: -/// # This is under the `step_case` label -/// return (x if e % 2 else 1) * exp(x * x, e // 2) -/// Note that this correctly handles exp(0, 0) == 1. +// Recursive implementation of exp. +// Equivalent to: +// def exp(x, e): +// if e == 0: +// # The path where JUMPI does not jump to `step_case` +// return 1 +// else: +// # This is under the `step_case` label +// return (x if e % 2 else 1) * exp(x * x, e // 2) +// Note that this correctly handles exp(0, 0) == 1. global exp: // stack: x, e, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/box.asm b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/box.asm index 6cb16c6e8..555bd7c82 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/box.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/box.asm @@ -1,19 +1,19 @@ -/// Note that we unpack STATE: 5 to a, b, c, d, e -/// All additions are u32 -/// -/// def box(a, b, c, d, e, F, K): -/// -/// box = get_box(sides, rounds, boxes) -/// a += F(b, c, d) -/// r = load(r)(box) -/// x = load_offset(r) -/// a += x + K -/// s = load(s)(box) -/// a = rol(s, a) -/// a += e -/// c = rol(10, c) -/// -/// return e, a, b, c, d, F, K +// Note that we unpack STATE: 5 to a, b, c, d, e +// All additions are u32 +// +// def box(a, b, c, d, e, F, K): +// +// box = get_box(sides, rounds, boxes) +// a += F(b, c, d) +// r = load(r)(box) +// x = load_offset(r) +// a += x + K +// s = load(s)(box) +// a = rol(s, a) +// a += e +// c = rol(10, c) +// +// return e, a, b, c, d, F, K global box: // stack: a, b, c, d, e, F, K, boxes, rounds, sides, virt diff --git a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/compression.asm b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/compression.asm index a83bf8322..ebe403b65 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/compression.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/compression.asm @@ -1,25 +1,25 @@ -/// _block is stored in memory: its address virt stays on the stack -/// def compress(STATE: 5, _block): -/// -/// STATEL = STATE -/// STATEL = loop(STATEL) -/// -/// STATER = state -/// STATER = loop(STATER) -/// -/// return mix(STATER, STATEL, STATE) -/// -/// -/// def mix(STATER, STATEL, STATE): -/// return -/// u32(s1 + l2 + r3), -/// u32(s2 + l3 + r4), -/// u32(s3 + l4 + r0), -/// u32(s4 + l0 + r1), -/// u32(s0 + l1 + r2) -/// -/// where si, li, ri, oi, VR, RD respectively denote -/// STATE[i], STATEL[i], STATER[i], OUTPUT[i], virt, retdest +// _block is stored in memory: its address virt stays on the stack +// def compress(STATE: 5, _block): +// +// STATEL = STATE +// STATEL = loop(STATEL) +// +// STATER = state +// STATER = loop(STATER) +// +// return mix(STATER, STATEL, STATE) +// +// +// def mix(STATER, STATEL, STATE): +// return +// u32(s1 + l2 + r3), +// u32(s2 + l3 + r4), +// u32(s3 + l4 + r0), +// u32(s4 + l0 + r1), +// u32(s0 + l1 + r2) +// +// where si, li, ri, oi, VR, RD respectively denote +// STATE[i], STATEL[i], STATER[i], OUTPUT[i], virt, retdest global compress: // stack: STATE, virt, retdest @@ -96,21 +96,21 @@ mix: JUMP -/// def loop(STATE: 5): -/// while rounds: -/// update_round_vars() -/// round(STATE: 5, F, K, rounds, sides) -/// -/// def update_round_vars(): -/// F = load(F)(sides, rounds) -/// K = load(K)(sides, rounds) -/// -/// def round(STATE, rounds, sides): -/// while boxes: -/// box(STATE, F, K) -/// boxes -= 1 -/// boxes = 16 -/// rounds -= 1 +// def loop(STATE: 5): +// while rounds: +// update_round_vars() +// round(STATE: 5, F, K, rounds, sides) +// +// def update_round_vars(): +// F = load(F)(sides, rounds) +// K = load(K)(sides, rounds) +// +// def round(STATE, rounds, sides): +// while boxes: +// box(STATE, F, K) +// boxes -= 1 +// boxes = 16 +// rounds -= 1 loop: // stack: STATE, F, K, 16, rounds, sides, virt, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/functions.asm b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/functions.asm index de2fdcf62..40e634080 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/functions.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/functions.asm @@ -1,5 +1,5 @@ -/// def rol(n, x): -/// return (u32(x << n)) | (x >> (32 - n)) +// def rol(n, x): +// return (u32(x << n)) | (x >> (32 - n)) global rol: // stack: n, x, retdest @@ -61,8 +61,8 @@ global rol: // stack: (rnd==j)*F + acc, rnd %endmacro -/// def F0(x, y, z): -/// return x ^ y ^ z +// def F0(x, y, z): +// return x ^ y ^ z global F0: // stack: x , y , z, retdest @@ -73,8 +73,8 @@ global F0: SWAP1 JUMP -/// def F1(x, y, z): -/// return (x & y) | (u32(~x) & z) +// def F1(x, y, z): +// return (x & y) | (u32(~x) & z) global F1: // stack: x, y, z, retdest @@ -97,8 +97,8 @@ global F1: SWAP1 JUMP -/// def F2(x, y, z): -/// return (x | u32(~y)) ^ z +// def F2(x, y, z): +// return (x | u32(~y)) ^ z global F2: // stack: x , y, z, retdest @@ -113,8 +113,8 @@ global F2: SWAP1 JUMP -/// def F3(x, y, z): -/// return (x & z) | (u32(~z) & y) +// def F3(x, y, z): +// return (x & z) | (u32(~z) & y) global F3: // stack: x, y , z , retdest @@ -133,8 +133,8 @@ global F3: SWAP1 JUMP -/// def F4(x, y, z): -/// return x ^ (y | u32(~z)) +// def F4(x, y, z): +// return x ^ (y | u32(~z)) global F4: // stack: x, y, z, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/main.asm b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/main.asm index 19016127f..11650cc5d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/main.asm @@ -1,19 +1,19 @@ -/// Variables beginning with _ are in memory -/// -/// def ripemd160(_input): -/// STATE, count, _buffer = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], 0, [0]*64 -/// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, len(input) , bytes = _input ) -/// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, padlength(len(input)), bytes = [0x80]+[0]*63) -/// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, 8, bytes = size(len(_input))) -/// return process(STATE) -/// -/// The hardcoded memory structure, where each register is only a byte, is given as follows -/// { 0-63: buffer, 64-71: bytes(8*len(_input)), 72-135: [0x80]+[0]*63 } -/// -/// ripemd_update receives and return the stack in the form: -/// stack: STATE, count, length, virt -/// where virt is the virtual address of the bytes argument -/// +// Variables beginning with _ are in memory +// +// def ripemd160(_input): +// STATE, count, _buffer = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], 0, [0]*64 +// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, len(input) , bytes = _input ) +// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, padlength(len(input)), bytes = [0x80]+[0]*63) +// STATE, count, _buffer = ripemd_update(STATE, count, _buffer, 8, bytes = size(len(_input))) +// return process(STATE) +// +// The hardcoded memory structure, where each register is only a byte, is given as follows +// { 0-63: buffer, 64-71: bytes(8*len(_input)), 72-135: [0x80]+[0]*63 } +// +// ripemd_update receives and return the stack in the form: +// stack: STATE, count, length, virt +// where virt is the virtual address of the bytes argument +// global ripemd: // stack: virt, length @@ -102,9 +102,9 @@ process: JUMP -/// def padlength(length): -/// t = length % 64 -/// return 56 + 64*(t > 55) - t +// def padlength(length): +// t = length % 64 +// return 56 + 64*(t > 55) - t %macro padlength // stack: count diff --git a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/update.asm b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/update.asm index c5783cc71..6219ddf29 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/update.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/hash/ripemd/update.asm @@ -1,21 +1,21 @@ -/// ripemd_update will receive and return the stack in the form: -/// stack: STATE, count, length, virt -/// -/// def ripemd_update(state, count, buffer, length, bytestring): -/// have = (count // 8) % 64 -/// need = 64 - have -/// shift = 0 -/// P = length >= need and have -/// Q = length >= need -/// if P: -/// update_1() -/// if Q: -/// update_2() -/// R = length > shift -/// if R: -/// buffer_update(virt + shift, have, length - shift) -/// -/// return state, count + 8*length, buffer +// ripemd_update will receive and return the stack in the form: +// stack: STATE, count, length, virt +// +// def ripemd_update(state, count, buffer, length, bytestring): +// have = (count // 8) % 64 +// need = 64 - have +// shift = 0 +// P = length >= need and have +// Q = length >= need +// if P: +// update_1() +// if Q: +// update_2() +// R = length > shift +// if R: +// buffer_update(virt + shift, have, length - shift) +// +// return state, count + 8*length, buffer global ripemd_update: // stack: STATE, count, length, virt, retdest @@ -67,11 +67,11 @@ return_step: JUMP -/// def update_1(): -/// buffer_update(virt, have, need) -/// shift = need -/// have = 0 -/// state = compress(state, buffer) +// def update_1(): +// buffer_update(virt, have, need) +// shift = need +// have = 0 +// state = compress(state, buffer) update_1: // stack: Q, STATE, shift, need, have, count, length, virt, retdest @@ -83,10 +83,10 @@ update_1a: // stack: STATE, 0, update_2, shift = need, need, have = 0, count, length, virt, retdest %jump(compress) -/// def update_2(): -/// while length >= shift + 64: -/// shift += 64 -/// state = compress(state, bytestring[shift-64:]) +// def update_2(): +// while length >= shift + 64: +// shift += 64 +// state = compress(state, bytestring[shift-64:]) update_2: // stack: STATE, shift, need, have, count, length, virt, retdest @@ -108,9 +108,9 @@ update_2: %jump(compress) -/// def buffer_update(get, set, times): -/// for i in range(times): -/// buffer[set+i] = bytestring[get+i] +// def buffer_update(get, set, times): +// for i in range(times): +// buffer[set+i] = bytestring[get+i] buffer_update: // stack: get , set , times , retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/memory/metadata.asm b/evm_arithmetization/src/cpu/kernel/asm/memory/metadata.asm index 5ac85f1b3..adc6acaf1 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/memory/metadata.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/memory/metadata.asm @@ -277,7 +277,7 @@ global sys_basefee: SWAP1 EXIT_KERNEL -/// Blob-related macros are only available for Ethereum mainnet. +// Blob-related macros are only available for Ethereum mainnet. #[cfg(feature = eth_mainnet)] { global sys_blobhash: diff --git a/evm_arithmetization/src/cpu/kernel/asm/memory/transient_storage.asm b/evm_arithmetization/src/cpu/kernel/asm/memory/transient_storage.asm index 8aa32c3e2..78292e0cd 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/memory/transient_storage.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/memory/transient_storage.asm @@ -1,15 +1,15 @@ // Transient data storage -/// The transient storage is stored in an array. The length of the array is stored in the global metadata. -/// For storage keys, the address and key are stored as two consecutive elements. -/// The array is stored in the SEGMENT_TRANSIENT_STORAGE segment in the kernel memory (context=0). -/// Searching and inserting is done by doing a linear search through the array. -/// If the key isn't found in the array, it is inserted at the end. -/// TODO: Look into using a more efficient data structure. - -/// The initial length, 0, must be scaled by its segment for -/// comparison with the accumulator when iterating through the list. +// The transient storage is stored in an array. The length of the array is stored in the global metadata. +// For storage keys, the address and key are stored as two consecutive elements. +// The array is stored in the SEGMENT_TRANSIENT_STORAGE segment in the kernel memory (context=0). +// Searching and inserting is done by doing a linear search through the array. +// If the key isn't found in the array, it is inserted at the end. +// TODO: Look into using a more efficient data structure. + +// The initial length, 0, must be scaled by its segment for +// comparison with the accumulator when iterating through the list. %macro init_transient_storage_len PUSH @SEGMENT_TRANSIENT_STORAGE %mstore_global_metadata(@GLOBAL_METADATA_TRANSIENT_STORAGE_LEN) @@ -22,9 +22,9 @@ // stack: (is_present, pos, addr, key, val) %endmacro -/// Looks for an address, key pair into the transient storage. -/// Returns 1 and the position in @SEGMENT_TRANSIENT_STORAGE if present, -/// or 0 and @GLOBAL_METADATA_TRANSIENT_STORAGE_LEN if not. +// Looks for an address, key pair into the transient storage. +// Returns 1 and the position in @SEGMENT_TRANSIENT_STORAGE if present, +// or 0 and @GLOBAL_METADATA_TRANSIENT_STORAGE_LEN if not. global search_transient_storage: // stack: addr, key, retdest %mload_global_metadata(@GLOBAL_METADATA_TRANSIENT_STORAGE_LEN) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 650d69db2..29a021b1a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -1,32 +1,32 @@ -/// Linked lists for accounts and storage slots. -/// The accounts linked list is stored in SEGMENT_ACCOUNTS_LINKED_LIST while the slots -/// are stored in SEGMENT_STORAGE_LINKED_LIST. The length of -/// the segments is stored in the associated global metadata. -/// Both arrays are stored in the kernel memory (context=0). -/// Searching and inserting is done by guessing the predecessor in the list. -/// If the address/storage key isn't found in the array, it is inserted -/// at the correct location. These linked lists are used to keep track of -/// inserted and deleted accounts/slots during the execution, so that the -/// initial and final MPT state tries can be reconstructed at the end of the execution. -/// An empty account linked list is written as -/// [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. -/// The linked list is preinitialized by appending accounts to the segment. Each account is encoded -/// using 4 values. -/// The values at the respective positions are: -/// - 0: The account key -/// - 1: A ptr to the payload (the account values) -/// - 2: A ptr to the initial payload. -/// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. -/// Similarly, an empty storage linked list is written as -/// [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. -/// The linked list is preinitialized by appending storage slots to the segment. -/// Each slot is encoded using 5 values. -/// The values at the respective positions are: -/// - 0: The account key -/// - 1: The slot key -/// - 2: The slot value. -/// - 3: The initial slot value. -/// - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. +// Linked lists for accounts and storage slots. +// The accounts linked list is stored in SEGMENT_ACCOUNTS_LINKED_LIST while the slots +// are stored in SEGMENT_STORAGE_LINKED_LIST. The length of +// the segments is stored in the associated global metadata. +// Both arrays are stored in the kernel memory (context=0). +// Searching and inserting is done by guessing the predecessor in the list. +// If the address/storage key isn't found in the array, it is inserted +// at the correct location. These linked lists are used to keep track of +// inserted and deleted accounts/slots during the execution, so that the +// initial and final MPT state tries can be reconstructed at the end of the execution. +// An empty account linked list is written as +// [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. +// The linked list is preinitialized by appending accounts to the segment. Each account is encoded +// using 4 values. +// The values at the respective positions are: +// - 0: The account key +// - 1: A ptr to the payload (the account values) +// - 2: A ptr to the initial payload. +// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. +// Similarly, an empty storage linked list is written as +// [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. +// The linked list is preinitialized by appending storage slots to the segment. +// Each slot is encoded using 5 values. +// The values at the respective positions are: +// - 0: The account key +// - 1: The slot key +// - 2: The slot value. +// - 3: The initial slot value. +// - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. %macro store_initial_accounts PUSH %%after @@ -34,15 +34,15 @@ %%after: %endmacro -/// Iterates over the initial account linked list and shallow copies -/// the accounts, storing a pointer to the copied account in the node. -/// Computes the length of `SEGMENT_ACCOUNTS_LINKED_LIST` and -/// stores it in `GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE`. -/// It also checks that the next node address is current address + 4 -/// and that all keys are strictly increasing. -/// NOTE: It may be more efficient to check that the next node addres != U256_MAX -/// (i.e. node was not deleted) and ensure that no node with repeated key -/// is ever read. +// Iterates over the initial account linked list and shallow copies +// the accounts, storing a pointer to the copied account in the node. +// Computes the length of `SEGMENT_ACCOUNTS_LINKED_LIST` and +// stores it in `GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_NEXT_AVAILABLE`. +// It also checks that the next node address is current address + 4 +// and that all keys are strictly increasing. +// NOTE: It may be more efficient to check that the next node addres != U256_MAX +// (i.e. node was not deleted) and ensure that no node with repeated key +// is ever read. global store_initial_accounts: // stack: retdest PUSH @ACCOUNTS_LINKED_LISTS_NODE_SIZE @@ -256,8 +256,8 @@ insert_new_account: JUMP -/// Searches the account addr in the linked list. -/// Returns 0 if the account was not found or `original_ptr` if it was already present. +// Searches the account addr in the linked list. +// Returns 0 if the account was not found or `original_ptr` if it was already present. global search_account: // stack: addr_key, retdest PROVER_INPUT(linked_list::search_account) @@ -311,8 +311,8 @@ account_not_found: %%after: %endmacro -/// Removes the address and its value from the access list. -/// Panics if the key is not in the list. +// Removes the address and its value from the access list. +// Panics if the key is not in the list. global remove_account: // stack: addr_key, retdest PROVER_INPUT(linked_list::remove_account) @@ -356,15 +356,15 @@ global remove_account: %endmacro -/// Iterates over the initial account linked list and shallow copies -/// the accounts, storing a pointer to the copied account in the node. -/// Computes the length of `SEGMENT_STORAGE_LINKED_LIST` and -/// checks against `GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE`. -/// It also checks that the next node address is current address + 5 -/// and that all keys are strictly increasing. -/// NOTE: It may be more efficient to check that the next node addres != U256_MAX -/// (i.e. node was not deleted) and ensure that no node with repeated key -/// is ever read. +// Iterates over the initial account linked list and shallow copies +// the accounts, storing a pointer to the copied account in the node. +// Computes the length of `SEGMENT_STORAGE_LINKED_LIST` and +// checks against `GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE`. +// It also checks that the next node address is current address + 5 +// and that all keys are strictly increasing. +// NOTE: It may be more efficient to check that the next node addres != U256_MAX +// (i.e. node was not deleted) and ensure that no node with repeated key +// is ever read. global store_initial_slots: // stack: retdest PUSH @STORAGE_LINKED_LISTS_NODE_SIZE @@ -486,8 +486,8 @@ store_initial_slots_end: %add_const(@SEGMENT_STORAGE_LINKED_LIST) %endmacro -/// Inserts the pair (address_key, storage_key) and a new payload pointer into the linked list if it is not already present, -/// or modifies its payload if it was already present. +// Inserts the pair (address_key, storage_key) and a new payload pointer into the linked list if it is not already present, +// or modifies its payload if it was already present. global insert_slot_with_value: // stack: addr_key, key, value, retdest PROVER_INPUT(linked_list::insert_slot) @@ -638,9 +638,9 @@ slot_found_write_value: // stack: (empty) %endmacro -/// Inserts the pair (address_key, storage_key) and payload pointer into the linked list if it is not already present, -/// or modifies its payload if it was already present. -/// Returns `value` if the storage key was inserted, `old_value` if it was already present. +// Inserts the pair (address_key, storage_key) and payload pointer into the linked list if it is not already present, +// or modifies its payload if it was already present. +// Returns `value` if the storage key was inserted, `old_value` if it was already present. global insert_slot: // stack: addr_key, key, value, retdest PROVER_INPUT(linked_list::insert_slot) @@ -782,8 +782,8 @@ next_node_ok: %stack (addr_key, key, value, retdest) -> (retdest, value) JUMP -/// Searches the pair (address_key, storage_key) in the storage the linked list. -/// Returns `value` if the storage key was inserted, `old_value` if it was already present. +// Searches the pair (address_key, storage_key) in the storage the linked list. +// Returns `value` if the storage key was inserted, `old_value` if it was already present. global search_slot: // stack: addr_key, key, value, retdest PROVER_INPUT(linked_list::search_slot) @@ -859,8 +859,8 @@ slot_found_no_write: %%after: %endmacro -/// Removes the storage key and its value from the list. -/// Panics if the key is not in the list. +// Removes the storage key and its value from the list. +// Panics if the key is not in the list. global remove_slot: // stack: addr_key, key, retdest PROVER_INPUT(linked_list::remove_slot) @@ -898,7 +898,7 @@ global remove_slot: %pop2 JUMP -/// Called when an account is deleted: it deletes all slots associated with the account. +// Called when an account is deleted: it deletes all slots associated with the account. global remove_all_account_slots: // stack: addr_key, retdest PROVER_INPUT(linked_list::remove_address_slots) diff --git a/evm_arithmetization/src/cpu/kernel/asm/shift.asm b/evm_arithmetization/src/cpu/kernel/asm/shift.asm index ee9ccbfae..bd403b946 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/shift.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/shift.asm @@ -1,6 +1,6 @@ -/// Initialise the lookup table of binary powers for doing left/right shifts -/// -/// Specifically, set SHIFT_TABLE_SEGMENT[i] = 2^i for i = 0..255. +// Initialise the lookup table of binary powers for doing left/right shifts +// +// Specifically, set SHIFT_TABLE_SEGMENT[i] = 2^i for i = 0..255. %macro shift_table_init push @SEGMENT_SHIFT_TABLE // segment, ctx == virt == 0 push 1 // 2^0 diff --git a/evm_arithmetization/src/cpu/kernel/asm/signed.asm b/evm_arithmetization/src/cpu/kernel/asm/signed.asm index 566d7d5ae..50bb8a406 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/signed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/signed.asm @@ -172,14 +172,14 @@ global _sys_slt: JUMP -/// These are the global entry-points for the signed system -/// calls. They just delegate to a subroutine with the same name -/// preceded by an underscore. -/// -/// NB: The only reason to structure things this way is so that the -/// test suite can call the _sys_opcode versions, since the test_suite -/// uses our interpreter which doesn't handle `EXIT_KERNEL` in a way -/// that allows for easy testing. The cost is two extra JUMPs per call. +// These are the global entry-points for the signed system +// calls. They just delegate to a subroutine with the same name +// preceded by an underscore. +// +// NB: The only reason to structure things this way is so that the +// test suite can call the _sys_opcode versions, since the test_suite +// uses our interpreter which doesn't handle `EXIT_KERNEL` in a way +// that allows for easy testing. The cost is two extra JUMPs per call. global sys_sdiv: %charge_gas_const(@GAS_LOW) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm index 6ee92ca2b..4a4518b20 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm @@ -244,7 +244,7 @@ sload_with_addr: SWAP1 JUMP -/// Type-3 transactions specific decoding helper macros. +// Type-3 transactions specific decoding helper macros. #[cfg(feature = eth_mainnet)] { %macro decode_and_store_max_fee_per_blob_gas diff --git a/evm_arithmetization/src/cpu/kernel/asm/util/basic_macros.asm b/evm_arithmetization/src/cpu/kernel/asm/util/basic_macros.asm index 395852810..aa5647c12 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/util/basic_macros.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/util/basic_macros.asm @@ -303,9 +303,9 @@ // stack: ceil(x / c), ... %endmacro -/// Same as `%as_u32`, but does not rely on -/// the AND operation. -/// *Note*: This is heavier, `%as_u32` should be preferred. +// Same as `%as_u32`, but does not rely on +// the AND operation. +// *Note*: This is heavier, `%as_u32` should be preferred. %macro as_u32_no_and // stack: word PUSH 0x100000000 From ee543bedecd8a6aa4a9b8fa55db3dfdcc71f860f Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 11:38:37 +0100 Subject: [PATCH 3/6] chore: push -> PUSH --- evm_arithmetization/src/cpu/kernel/asm/exp.asm | 12 ++++++------ evm_arithmetization/src/cpu/kernel/asm/shift.asm | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/exp.asm b/evm_arithmetization/src/cpu/kernel/asm/exp.asm index 83b9682ae..9e359c494 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/exp.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/exp.asm @@ -19,7 +19,7 @@ global exp: // stack: e, retdest pop // stack: retdest - push 1 + PUSH 1 // stack: 1, retdest swap1 // stack: retdest, 1 @@ -29,7 +29,7 @@ step_case: // stack: x, e, retdest push recursion_return // stack: recursion_return, x, e, retdest - push 2 + PUSH 2 // stack: 2, recursion_return, x, e, retdest dup4 // stack: e, 2, recursion_return, x, e, retdest @@ -42,13 +42,13 @@ step_case: %jump(exp) recursion_return: // stack: exp(x * x, e / 2), x, e, retdest - push 2 + PUSH 2 // stack: 2, exp(x * x, e / 2), x, e, retdest dup4 // stack: e, 2, exp(x * x, e / 2), x, e, retdest mod // stack: e % 2, exp(x * x, e / 2), x, e, retdest - push 1 + PUSH 1 // stack: 1, e % 2, exp(x * x, e / 2), x, e, retdest dup4 // stack: x, 1, e % 2, exp(x * x, e / 2), x, e, retdest @@ -56,7 +56,7 @@ recursion_return: // stack: x - 1, e % 2, exp(x * x, e / 2), x, e, retdest mul // stack: (x - 1) * (e % 2), exp(x * x, e / 2), x, e, retdest - push 1 + PUSH 1 // stack: 1, (x - 1) * (e % 2), exp(x * x, e / 2), x, e, retdest add // stack: 1 + (x - 1) * (e % 2), exp(x * x, e / 2), x, e, retdest @@ -74,7 +74,7 @@ recursion_return: global sys_exp: %stack (return_info, x, e) -> (x, e, return_info) - push 0 + PUSH 0 // stack: shift, x, e, return_info %jump(sys_exp_gas_loop_enter) sys_exp_gas_loop: diff --git a/evm_arithmetization/src/cpu/kernel/asm/shift.asm b/evm_arithmetization/src/cpu/kernel/asm/shift.asm index bd403b946..4a1e00e4e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/shift.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/shift.asm @@ -2,8 +2,8 @@ // // Specifically, set SHIFT_TABLE_SEGMENT[i] = 2^i for i = 0..255. %macro shift_table_init - push @SEGMENT_SHIFT_TABLE // segment, ctx == virt == 0 - push 1 // 2^0 + PUSH @SEGMENT_SHIFT_TABLE // segment, ctx == virt == 0 + PUSH 1 // 2^0 %rep 255 // stack: 2^i, addr_i dup2 From 9f6d8d1856a8bab000bd871b963b6ae8a3d3b73d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 11:39:24 +0100 Subject: [PATCH 4/6] chore: non goals --- evm_arithmetization/src/cpu/kernel/ast2.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/evm_arithmetization/src/cpu/kernel/ast2.rs b/evm_arithmetization/src/cpu/kernel/ast2.rs index ec32ee082..8ab13e50d 100644 --- a/evm_arithmetization/src/cpu/kernel/ast2.rs +++ b/evm_arithmetization/src/cpu/kernel/ast2.rs @@ -8,6 +8,7 @@ //! - Representing trivia such as comments. This must be done in a separate step //! in the language server, as the implementation complexity is not worth it. //! - A Concrete Syntax Tree for formatting. +//! - Representing invalid parse trees. use derive_quote_to_tokens::ToTokens; use derive_syn_parse::Parse; From 64dc2e505e3451c3919afdc7727506aa0e7c4ed1 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 12:43:23 +0100 Subject: [PATCH 5/6] test: round trip ast --- Cargo.lock | 1 + evm_arithmetization/Cargo.toml | 1 + evm_arithmetization/src/cpu/kernel/ast2.rs | 84 ++++++++++++++-------- evm_arithmetization/tests/parse.rs | 12 +++- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd925b1a1..0cfdcb831 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2058,6 +2058,7 @@ name = "evm_arithmetization" version = "0.4.0" dependencies = [ "anyhow", + "assert2", "bytes", "camino", "criterion", diff --git a/evm_arithmetization/Cargo.toml b/evm_arithmetization/Cargo.toml index 926eb5ecf..9114a3ab3 100644 --- a/evm_arithmetization/Cargo.toml +++ b/evm_arithmetization/Cargo.toml @@ -56,6 +56,7 @@ zk_evm_common.workspace = true zk_evm_proc_macro.workspace = true [dev-dependencies] +assert2 = "0.3.15" camino = "1.1.9" criterion.workspace = true glob = "0.3.1" diff --git a/evm_arithmetization/src/cpu/kernel/ast2.rs b/evm_arithmetization/src/cpu/kernel/ast2.rs index 8ab13e50d..76505740a 100644 --- a/evm_arithmetization/src/cpu/kernel/ast2.rs +++ b/evm_arithmetization/src/cpu/kernel/ast2.rs @@ -19,7 +19,7 @@ use syn::parse::{Parse, ParseStream, Peek}; use syn::punctuated::Punctuated; use syn::{braced, bracketed, parenthesized, token, Token}; -/// Keywords +/// Keywords. pub mod kw { macro_rules! keywords { ($($ident:ident),* $(,)?) => { @@ -101,6 +101,48 @@ pub mod pc { } } +pub mod pun { + //! Custom punctuation. + //! + //! We take care to preserve round-tripping the printed tokenstream for our + //! tests. + + use derive_quote_to_tokens::ToTokens; + use proc_macro2::{Punct, Spacing}; + use syn::parse::{Parse, ParseStream}; + + #[derive(ToTokens)] + pub struct Percent2 { + punct0: Punct, + punct1: Punct, + } + + impl Parse for Percent2 { + fn parse(input: ParseStream) -> syn::Result { + input.step(|cursor| { + match cursor + .punct() + .and_then(|(p0, next)| next.punct().map(|(p1, n)| (p0, p1, n))) + { + Some((punct0, punct1, n)) + if itertools::all([&punct0, &punct1], |it| it.as_char() == '%') + && punct0.spacing() == Spacing::Joint => + { + Ok((Percent2 { punct0, punct1 }, n)) + } + _ => Err(input.error("expected `%%`")), + } + }) + } + } + + impl Percent2 { + pub fn peek(input: ParseStream) -> bool { + input.fork().parse::().is_ok() + } + } +} + pub struct File { pub items: Vec, } @@ -124,10 +166,6 @@ impl ToTokens for File { } } -fn peek2pc(input: ParseStream) -> bool { - input.peek(Token![%]) && input.peek2(Token![%]) -} - fn peek2(token: T) -> impl Fn(ParseStream) -> bool { move |it| it.peek2(token) } @@ -174,7 +212,7 @@ pub enum Item { Repeat(Repeat), #[peek_with(pc::stack::peek, name = "%stack")] Stack(Stack), - #[peek_with(peek2pc, name = "a `%%..` macro decl")] + #[peek_with(pun::Percent2::peek, name = "a `%%..` macro decl")] MacroDecl(MacroDecl), #[peek(Token![%], name = "MacroCall")] MacroCall(MacroCall), @@ -196,8 +234,7 @@ pub enum Item { #[derive(Parse, ToTokens)] pub struct MacroLabel { - pub percent0: Token![%], - pub percent1: Token![%], + pub percent: pun::Percent2, pub ident: Ident, } @@ -303,7 +340,7 @@ pub enum Target { Literal(Literal), #[peek_with(Ident::peek, name = "Ident")] Ident(Ident), - #[peek_with(peek2pc, name = "a `%%..` macro label")] + #[peek_with(pun::Percent2::peek, name = "a `%%..` macro label")] MacroLabel(MacroLabel), #[peek(Token![$], name = "a `$..` variable")] Variable(Variable), @@ -352,44 +389,35 @@ impl ToTokens for Repeat { } } +#[derive(Parse)] pub struct Stack { pub stack: pc::stack, + #[paren] pub placeholders_paren: token::Paren, + #[inside(placeholders_paren)] + #[call(Punctuated::parse_terminated)] pub placeholders: Punctuated, - pub arrow: (Token![-], Token![>]), + pub arrow: Token![->], + #[paren] pub replacements_paren: token::Paren, + #[inside(replacements_paren)] + #[call(Punctuated::parse_terminated)] pub replacements: Punctuated, } -impl Parse for Stack { - fn parse(input: ParseStream) -> syn::Result { - let placeholders; - let replacements; - Ok(Self { - stack: input.parse()?, - placeholders_paren: parenthesized!(placeholders in input), - placeholders: { Punctuated::parse_terminated(&placeholders)? }, - arrow: (input.parse()?, input.parse()?), - replacements_paren: parenthesized!(replacements in input), - replacements: Punctuated::parse_terminated(&replacements)?, - }) - } -} - impl ToTokens for Stack { fn to_tokens(&self, tokens: &mut TokenStream) { let Self { stack, placeholders_paren, placeholders, - arrow: (arrow0, arrow1), + arrow, replacements_paren, replacements, } = self; stack.to_tokens(tokens); placeholders_paren.surround(tokens, |tokens| placeholders.to_tokens(tokens)); - arrow0.to_tokens(tokens); - arrow1.to_tokens(tokens); + arrow.to_tokens(tokens); replacements_paren.surround(tokens, |tokens| replacements.to_tokens(tokens)); } } diff --git a/evm_arithmetization/tests/parse.rs b/evm_arithmetization/tests/parse.rs index 30540d8b3..34a4d208a 100644 --- a/evm_arithmetization/tests/parse.rs +++ b/evm_arithmetization/tests/parse.rs @@ -4,6 +4,8 @@ use anyhow::Context as _; use camino::Utf8Path; use evm_arithmetization::cpu::kernel::ast2; use libtest_mimic::{Arguments, Failed, Trial}; +use proc_macro2::TokenStream; +use quote::ToTokens; fn main() -> anyhow::Result<()> { let mut trials = vec![]; @@ -13,10 +15,18 @@ fn main() -> anyhow::Result<()> { let path = Utf8Path::from_path(&path).context("invalid path")?; let friendly = path.strip_prefix(asm_folder).unwrap_or(path); let source = fs::read_to_string(path)?; + trials.push(Trial::test( friendly.to_owned(), move || match syn::parse_str::(&source) { - Ok(_) => Ok(()), + Ok(file) => { + let source_tokens = source + .parse::() + .expect("lexing must have succeeded if parsing succeeded"); + let parsed_tokens = file.to_token_stream(); + assert2::assert!(source_tokens.to_string() == parsed_tokens.to_string()); + Ok(()) + } Err(e) => Err(Failed::from(syn_miette::Error::new(e, source).render())), }, )); From d81b24dd8bc4bf1b0ebd9aaf605af11b697b946b Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 1 Oct 2024 12:50:16 +0100 Subject: [PATCH 6/6] wibble --- Cargo.lock | 12 +++++++++++- evm_arithmetization/Cargo.toml | 2 +- evm_arithmetization/tests/parse.rs | 15 +++++++++++---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cfdcb831..131c062ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2058,7 +2058,6 @@ name = "evm_arithmetization" version = "0.4.0" dependencies = [ "anyhow", - "assert2", "bytes", "camino", "criterion", @@ -2083,6 +2082,7 @@ dependencies = [ "plonky2", "plonky2_maybe_rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "plonky2_util", + "pretty_assertions", "proc-macro2", "quote", "rand", @@ -3832,6 +3832,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "pretty_env_logger" version = "0.5.0" diff --git a/evm_arithmetization/Cargo.toml b/evm_arithmetization/Cargo.toml index 9114a3ab3..b620a6d88 100644 --- a/evm_arithmetization/Cargo.toml +++ b/evm_arithmetization/Cargo.toml @@ -56,12 +56,12 @@ zk_evm_common.workspace = true zk_evm_proc_macro.workspace = true [dev-dependencies] -assert2 = "0.3.15" camino = "1.1.9" criterion.workspace = true glob = "0.3.1" hex.workspace = true libtest-mimic = "0.7.3" +pretty_assertions = "1.4.1" ripemd.workspace = true syn-miette = "0.3.0" diff --git a/evm_arithmetization/tests/parse.rs b/evm_arithmetization/tests/parse.rs index 34a4d208a..717e8a038 100644 --- a/evm_arithmetization/tests/parse.rs +++ b/evm_arithmetization/tests/parse.rs @@ -4,6 +4,7 @@ use anyhow::Context as _; use camino::Utf8Path; use evm_arithmetization::cpu::kernel::ast2; use libtest_mimic::{Arguments, Failed, Trial}; +use pretty_assertions::StrComparison; use proc_macro2::TokenStream; use quote::ToTokens; @@ -22,10 +23,16 @@ fn main() -> anyhow::Result<()> { Ok(file) => { let source_tokens = source .parse::() - .expect("lexing must have succeeded if parsing succeeded"); - let parsed_tokens = file.to_token_stream(); - assert2::assert!(source_tokens.to_string() == parsed_tokens.to_string()); - Ok(()) + .expect("lexing must have succeeded if parsing succeeded") + .to_string(); + let parsed_tokens = file.to_token_stream().to_string(); + match source_tokens == parsed_tokens { + true => Ok(()), + false => Err(Failed::from(StrComparison::new( + &source_tokens, + &parsed_tokens, + ))), + } } Err(e) => Err(Failed::from(syn_miette::Error::new(e, source).render())), },