* Use static `KERNEL` in tests
* Print opcode count
* Update criterion
* Combine all syscalls into one flag (#802)
* Combine all syscalls into one flag
* Minor: typo
* Daniel PR comments
* Check that `le_sum` won't overflow
* security notes
* Test reverse_index_bits
Thanks to Least Authority for this
* clippy
* EVM shift left/right operations (#801)
* First parts of shift implementation.
* Disable range check errors.
* Tidy up ASM.
* Update comments; fix some .sum() expressions.
* First full draft of shift left/right.
* Missed a +1.
* Clippy.
* Address Jacqui's comments.
* Add comment.
* Fix missing filter.
* Address second round of comments from Jacqui.
* Remove signed operation placeholders from arithmetic table. (#812)
Co-authored-by: wborgeaud <williamborgeaud@gmail.com>
Co-authored-by: Daniel Lubarov <daniel@lubarov.com>
Co-authored-by: Jacqueline Nabaglo <jakub@mirprotocol.org>
Co-authored-by: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com>
* First draft of 256-bit addition.
* Update comment.
* cargo fmt
* Rename addition evaluation file.
* Port ALU logic from SZ.
* Give a name to some magic numbers.
* `addition.rs` -> `add.rs`; fix carry propagation in add; impl sub.
* Clippy.
* Combine hi and lo parts of the output.
* Implement MUL.
* Suppress Clippy's attempt to make my code even harder to read.
* Next draft of MUL.
* Make all limbs (i.e. input and output) 16-bits.
* Tidying.
* Use iterators instead of building arrays.
* Documentation.
* Clippy is wrong; also cargo fmt.
* Un-refactor equality checking, since it was wrong for sub.
* Daniel comments.
* Daniel comments.
* Rename folder 'alu' -> 'arithmetic'.
* Rename file.
* Finish changing name ALU -> Arithmetic Unit.
* Finish removing dependency on array_zip feature.
* Remove operations that will be handled elsewhere.
* Rename var; tidy up.
* Clean up columns; mark places where range-checks need to be done.
* Import all names in 'columns' to reduce verbiage.
* cargo fmt
* Fix aux_in calculation in mul.
* Remove redundant 'allow's; more precise range-check size.
* Document functions.
* Document MUL instruction verification technique.
* Initial tests for ADD.
* Minor test fixes; add test for SUB.
* Fix bugs in generate functions.
* Fix SUB verification; refactor equality verification.
* cargo fmt
* Add test for MUL and fix some bugs.
* Update doc.
* Quiet incorrect clippy error.
* Initial implementation of ADDMOD and MOD.
* Fixes to addmod.
* Update doc.
* Do 1000 random tests instead of just 1.
* Documentation fix.
* Working version of ADDMOD.
* Working version of MOD.
* Name magic number; do multiple MUL tests.
* Add code and test for special case; add some docs.
* Fix spelling mistake.
* Simplify asserts.
* Tidy comment.
* Remove unused module.
* cargo fmt
* Check that output is reduced.
* Add conversion of canonical `i64` to a `Field64`.
* Handle zero modulus within degree constraint.
* cargo fmt
* Fix some comments.
* Check that the top half of the product is zero!
* Start of refactor.
* Refactoring.
* Remove zero and reduction handling from addmod.
* Refactoring; renaming; bug fixes.
* Reuse intermediate calculations across all modular operations; don't negate quot poly unnecessarily.
* Fix bug where last elt of q*m wasn't checked.
* Refactoring.
* Move circuit poly functions to utils.rs.
* Rename ADDMOD stuff to MODULAR.
* Rename module addmod -> modular.
* Handle zero modulus.
* Verify that output is reduced.
* Implement recursive version of modular circuits.
* clippy
* Tidy up i64 -> Field conversion following Jacqui's comments.
* cargo fmt
* Improved documentation.
* Address Jacqui's comments.
* Save some gates by using builder.arithmetic_extension().
`keccak_rust` doesn't seem to have much usage, and it treats `x` as the major axis of its 5x5 input. This is not exactly wrong, since Keccak itself doesn't have a notion of axis order. However, there is a convention for mapping bits of the cube to a flat list of bits, which is
> The mapping between the bits of `s` and those of `a` is `s[w(5y + x) + z] = a[x][y][z]`.
Obeying this convention would be awkward with `keccak_rust` - the words in memory would need to be transposed.
The kernel is hashed using a Keccak based sponge for now. We could switch to Poseidon later if our kernel grows too large.
Note that we use simple zero-padding (pad0*) instead of the standard pad10* rule. It's simpler, and we don't care that the prover can add extra 0s at the end of the code. The program counter can never reach those bytes, and even if it could, they'd be 0 anyway given the EVM's zero-initialization rule.
In one CPU row, we can do a whole Keccak hash (via the CTL), absorbing 136 bytes. But we can't actually bootstrap that many bytes of kernel code in one row, because we're also limited by memory bandwidth. Currently we can write 4 bytes of the kernel to memory in one row.
So we treat the `keccak_input_limbs` columns as a buffer. We gradually fill up this buffer, 4 bytes (one `u32` word) at a time. Every `136 / 4 = 34` rows, the buffer will be full, so at that point we activate the Keccak CTL to absorb the buffer.
* Parse and assemble kernel functions
Written in "EVM++" assembly. Later on we will add some priviledged opcodes (in unused opcode ordinals), making it an extension of EVM bytecode.
I don't think there's much of a standard for EVM assembly, but I loosely based the syntax on this [proposal](https://gist.github.com/axic/17ddbbce4738ccf4040d30cbb5de484e).
* PR feedback
* tweaks for consistency
* terminology tweaks
* Update evm/src/cpu/kernel/opcodes.rs
Co-authored-by: Jacqueline Nabaglo <jakub@mirprotocol.org>
* Update evm/src/cpu/kernel/opcodes.rs
Co-authored-by: Jacqueline Nabaglo <jakub@mirprotocol.org>
* Update evm/src/cpu/kernel/opcodes.rs
Co-authored-by: Jacqueline Nabaglo <jakub@mirprotocol.org>
Co-authored-by: Jacqueline Nabaglo <jakub@mirprotocol.org>