This commit is contained in:
Daniel Lubarov 2022-07-20 00:10:52 -07:00
parent 1a0d6f4413
commit 78fb34a9b6
5 changed files with 39 additions and 30 deletions

View File

@ -11,6 +11,7 @@ anyhow = "1.0.40"
env_logger = "0.9.0"
ethereum-types = "0.13.1"
hex = { version = "0.4.3", optional = true }
hex-literal = "0.3.4"
itertools = "0.10.3"
log = "0.4.14"
once_cell = "1.13.0"
@ -24,7 +25,6 @@ keccak-rust = { git = "https://github.com/npwardberkeley/keccak-rust" }
keccak-hash = "0.9.0"
[dev-dependencies]
hex-literal = "0.3.4"
hex = "0.4.3"
[features]

View File

@ -3,6 +3,7 @@
use std::collections::HashMap;
use ethereum_types::U256;
use hex_literal::hex;
use itertools::Itertools;
use once_cell::sync::Lazy;
@ -14,6 +15,12 @@ pub static KERNEL: Lazy<Kernel> = Lazy::new(combined_kernel);
pub fn evm_constants() -> HashMap<String, U256> {
let mut c = HashMap::new();
c.insert(
"BN_BASE".into(),
U256::from_big_endian(&hex!(
"30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
)),
);
for segment in Segment::all() {
c.insert(segment.var_name().into(), (segment as u32).into());
}

View File

@ -94,14 +94,8 @@ global ec_add_valid_points:
ec_add_first_zero:
JUMPDEST
// stack: x0, y0, x1, y1, retdest
// Just return (x1,y1)
%pop2
// stack: x1, y1, retdest
SWAP1
// stack: y1, x1, retdest
SWAP2
// stack: retdest, x1, y1
%stack (x0, y0, x1, y1, retdest) -> (retdest, x1, y1)
JUMP
// BN254 elliptic curve addition.
@ -271,21 +265,7 @@ global ec_double:
// stack: y < N, x < N, x, y
AND
// stack: (y < N) & (x < N), x, y
SWAP2
// stack: y, x, (y < N) & (x < N), x
SWAP1
// stack: x, y, (y < N) & (x < N)
%bn_base
// stack: N, x, y, b
%bn_base
// stack: N, N, x, y, b
DUP3
// stack: x, N, N, x, y, b
%bn_base
// stack: N, x, N, N, x, y, b
DUP2
// stack: x, N, x, N, N, x, y, b
DUP1
%stack (b, x, y) -> (x, x, @BN_BASE, x, @BN_BASE, @BN_BASE, x, y, b)
// stack: x, x, N, x, N, N, x, y, b
MULMOD
// stack: x^2 % N, x, N, N, x, y, b

View File

@ -5,7 +5,7 @@ use itertools::izip;
use log::debug;
use super::ast::PushTarget;
use crate::cpu::kernel::ast::Literal;
use crate::cpu::kernel::ast::{Literal, StackReplacement};
use crate::cpu::kernel::keccak_util::hash_kernel;
use crate::cpu::kernel::stack_manipulation::expand_stack_manipulation;
use crate::cpu::kernel::{
@ -165,14 +165,31 @@ fn expand_repeats(body: Vec<Item>) -> Vec<Item> {
}
fn inline_constants(body: Vec<Item>, constants: &HashMap<String, U256>) -> Vec<Item> {
let resolve_const = |c| {
Literal::Decimal(
constants
.get(&c)
.unwrap_or_else(|| panic!("No such constant: {}", c))
.to_string(),
)
};
body.into_iter()
.map(|item| {
if let Item::Push(PushTarget::Constant(c)) = item {
let value = constants
.get(&c)
.unwrap_or_else(|| panic!("No such constant: {}", c));
let literal = Literal::Decimal(value.to_string());
Item::Push(PushTarget::Literal(literal))
Item::Push(PushTarget::Literal(resolve_const(c)))
} else if let Item::StackManipulation(from, to) = item {
let to = to
.into_iter()
.map(|replacement| {
if let StackReplacement::Constant(c) = replacement {
StackReplacement::Literal(resolve_const(c))
} else {
replacement
}
})
.collect();
Item::StackManipulation(from, to)
} else {
item
}
@ -446,6 +463,11 @@ mod tests {
let kernel = parse_and_assemble(&["%stack (a, b, c) -> (b)"]);
assert_eq!(kernel.code, vec![pop, swap1, pop]);
let mut consts = HashMap::new();
consts.insert("LIFE".into(), 42.into());
parse_and_assemble_with_constants(&["%stack (a, b) -> (b, @LIFE)"], consts);
// We won't check the code since there are two equally efficient implementations.
}
fn parse_and_assemble(files: &[&str]) -> Kernel {

View File

@ -39,7 +39,7 @@ fn expand(names: Vec<String>, replacements: Vec<StackReplacement>) -> Vec<Item>
StackReplacement::NamedItem(name) => StackItem::NamedItem(name),
StackReplacement::Literal(n) => StackItem::Literal(n),
StackReplacement::MacroVar(_) | StackReplacement::Constant(_) => {
panic!("Should have been expanded earlier")
panic!("Should have been expanded already: {:?}", item)
}
})
.collect_vec();