Exponentiation kernel function (#574)

* Exponentiation kernel function

* Exponentiation: Hamish comments
This commit is contained in:
Jacqueline Nabaglo 2022-06-23 15:33:55 -07:00 committed by GitHub
parent af0e32506a
commit 191ddf7bc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 0 deletions

View File

@ -8,6 +8,7 @@ use crate::cpu::kernel::parser::parse;
#[allow(dead_code)] // TODO: Should be used once witness generation is done.
pub(crate) fn combined_kernel() -> Kernel {
let files = vec![
include_str!("asm/exp.asm"),
include_str!("asm/storage_read.asm"),
include_str!("asm/storage_write.asm"),
];

View File

@ -0,0 +1,81 @@
/// 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:
// We don't seem to handle global labels yet, so this function has a local label too for now:
exp:
// stack: x, e, retdest
dup2
// stack: e, x, e, retdest
push step_case
// stack: step_case, e, x, e, retdest
jumpi
// stack: x, e, retdest
pop
// stack: e, retdest
pop
// stack: retdest
push 1
// stack: 1, retdest
swap1
// stack: retdest, 1
jump
step_case:
// stack: x, e, retdest
push recursion_return
// stack: recursion_return, x, e, retdest
push 2
// stack: 2, recursion_return, x, e, retdest
dup4
// stack: e, 2, recursion_return, x, e, retdest
div
// stack: e / 2, recursion_return, x, e, retdest
dup3
// stack: x, e / 2, recursion_return, x, e, retdest
dup1
// stack: x, x, e / 2, recursion_return, x, e, retdest
mul
// stack: x * x, e / 2, recursion_return, x, e, retdest
push exp
// stack: exp, x * x, e / 2, recursion_return, x, e, retdest
jump
recursion_return:
// stack: exp(x * x, e / 2), x, e, retdest
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
// 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
sub
// 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
// 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
mul
// stack: (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2), x, e, retdest
swap3
// stack: retdest, x, e, (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2)
swap2
// stack: e, x, retdest, (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2)
pop
// stack: x, retdest, (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2)
pop
// stack: retdest, (1 + (x - 1) * (e % 2)) * exp(x * x, e / 2)
jump