From 6193827733b76cf2a49cc26aaac03e93b3fe3e65 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Mon, 19 Sep 2022 18:11:07 -0700 Subject: [PATCH] finish?? --- evm/src/cpu/kernel/asm/ripemd/compression.asm | 144 ++++++++--------- evm/src/cpu/kernel/asm/ripemd/constants.asm | 2 +- evm/src/cpu/kernel/asm/ripemd/memory.asm | 23 ++- evm/src/cpu/kernel/asm/ripemd/ripemd.asm | 36 ++--- evm/src/cpu/kernel/asm/ripemd/update.asm | 151 ++++++++++++++++++ evm/src/memory/segments.rs | 4 +- 6 files changed, 261 insertions(+), 99 deletions(-) diff --git a/evm/src/cpu/kernel/asm/ripemd/compression.asm b/evm/src/cpu/kernel/asm/ripemd/compression.asm index 544d417c..fa68a9d7 100644 --- a/evm/src/cpu/kernel/asm/ripemd/compression.asm +++ b/evm/src/cpu/kernel/asm/ripemd/compression.asm @@ -1,8 +1,8 @@ -/// _offset is stored in memory and its address offset remains on the stack -/// Note that state takes up 5 stack slots +/// _block is stored in memory and its address virt remains on the stack +/// Note that STATE takes up 5 stack slots -/// def compression(state, _offset): +/// def compress(state, _block): /// /// stateL = state /// stateL = loop(stateL) @@ -13,7 +13,7 @@ /// return mix(state, stateL, stateR) /// /// -/// def mix(*stateR, *stateL, *state): +/// def mix(stateR, stateL, state): /// return /// u32(s1 + l2 + r3), /// u32(s2 + l3 + r4), @@ -21,11 +21,11 @@ /// u32(s4 + l0 + r1), /// u32(s0 + l1 + r2) /// -/// where si, li, ri, oi, BL, RD respectively denote -/// state[i], stateL[i], stateR[i], output[i], offset, retdest +/// where si, li, ri, oi, OF, RD respectively denote +/// state[i], stateL[i], stateR[i], output[i], virt, retdest -global compression: - // stack: *state, offset, retdest +global compress: + // stack: STATE, virt, retdest PUSH switch DUP7 PUSH 1 @@ -33,16 +33,16 @@ global compression: PUSH 16 PUSH 0 PUSH 0 - // stack: 0, 0, 16, 5, 1, offset, switch, *state, offset, retdest + // stack: 0, 0, 16, 5, 1, virt, switch, STATE, virt, retdest DUP12 DUP12 DUP12 DUP12 DUP12 - // stack: *state, 0, 0, 16, 5, 1, offset, switch, *state, offset, retdest + // stack: STATE, 0, 0, 16, 5, 1, virt, switch, STATE, virt, retdest %jump(loop) switch: - // stack: *stateL, *state, offset, retdest + // stack: STATEL, STATE, virt, retdest PUSH mix DUP12 PUSH 0 @@ -50,127 +50,127 @@ switch: PUSH 16 PUSH 0 PUSH 0 - // stack: 0, 0, 16, 5, 0, offset, mix, *stateL, *state, offset, retdest + // stack: 0, 0, 16, 5, 0, virt, mix, STATEL, STATE, virt, retdest DUP17 DUP17 DUP17 DUP17 DUP17 - // stack: *state, 0, 0, 16, 5, 0, offset, mix, *stateL, *state, offset, retdest + // stack: STATE, 0, 0, 16, 5, 0, virt, mix, STATEL, STATE, virt, retdest %jump(loop) mix: - // stack: r0, r1, r2, r3, r4, l0, l1, l2, l3, l4, s0, s1, s2, s3, s4, BL, RD + // stack: r0, r1, r2, r3, r4, l0, l1, l2, l3, l4, s0, s1, s2, s3, s4, VR, RD SWAP10 - // stack: s0, r1, r2, r3, r4, l0, l1, l2, l3, l4, r0, s1, s2, s3, s4, BL, RD + // stack: s0, r1, r2, r3, r4, l0, l1, l2, l3, l4, r0, s1, s2, s3, s4, VR, RD SWAP1 - // stack: r1, s0, r2, r3, r4, l0, l1, l2, l3, l4, r0, s1, s2, s3, s4, BL, RD + // stack: r1, s0, r2, r3, r4, l0, l1, l2, l3, l4, r0, s1, s2, s3, s4, VR, RD SWAP6 - // stack: l1, s0, r2, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, BL, RD + // stack: l1, s0, r2, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, VR, RD %add3_32 - // stack: o4, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, BL, RD + // stack: o4, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, VR, RD SWAP14 - // stack: RD, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, BL, o4 + // stack: RD, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, s3, s4, VR, o4 SWAP11 - // stack: s3, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, RD, s4, BL, o4 + // stack: s3, r3, r4, l0, r1, l2, l3, l4, r0, s1, s2, RD, s4, VR, o4 SWAP10 - // stack: s2, r3, r4, l0, r1, l2, l3, l4, r0, s1, s3, RD, s4, BL, o4 + // stack: s2, r3, r4, l0, r1, l2, l3, l4, r0, s1, s3, RD, s4, VR, o4 SWAP1 - // stack: r3, s2, r4, l0, r1, l2, l3, l4, r0, s1, s3, RD, s4, BL, o4 + // stack: r3, s2, r4, l0, r1, l2, l3, l4, r0, s1, s3, RD, s4, VR, o4 SWAP6 - // stack: l3, s2, r4, l0, r1, l2, r3, l4, r0, s1, s3, RD, s4, BL, o4 + // stack: l3, s2, r4, l0, r1, l2, r3, l4, r0, s1, s3, RD, s4, VR, o4 %add3_32 - // stack: o1, l0, r1, l2, r3, l4, r0, s1, s3, RD, s4, BL, o4 + // stack: o1, l0, r1, l2, r3, l4, r0, s1, s3, RD, s4, VR, o4 SWAP9 - // stack: RD, l0, r1, l2, r3, l4, r0, s1, s3, o1, s4, BL, o4 + // stack: RD, l0, r1, l2, r3, l4, r0, s1, s3, o1, s4, VR, o4 SWAP10 - // stack: s4, l0, r1, l2, r3, l4, r0, s1, s3, o1, RD, BL, o4 + // stack: s4, l0, r1, l2, r3, l4, r0, s1, s3, o1, RD, VR, o4 %add3_32 - // stack: o3, l2, r3, l4, r0, s1, s3, o1, RD, BL, o4 + // stack: o3, l2, r3, l4, r0, s1, s3, o1, RD, VR, o4 SWAP9 - // stack: BL, l2, r3, l4, r0, s1, s3, o1, RD, o3, o4 + // stack: VR, l2, r3, l4, r0, s1, s3, o1, RD, o3, o4 SWAP5 - // stack: s1, l2, r3, l4, r0, BL, s3, o1, RD, o3, o4 + // stack: s1, l2, r3, l4, r0, VR, s3, o1, RD, o3, o4 %add3_32 - // stack: o0, l4, r0, BL, s3, o1, RD, o3, o4 + // stack: o0, l4, r0, VR, s3, o1, RD, o3, o4 SWAP4 - // stack: s3, l4, r0, BL, o0, o1, RD, o3, o4 + // stack: s3, l4, r0, VR, o0, o1, RD, o3, o4 %add3_32 - // stack: o2, BL, o0, o1, RD, o3, o4 + // stack: o2, VR, o0, o1, RD, o3, o4 SWAP4 - // stack: RD, BL, o0, o1, o2, o3, o4 + // stack: RD, VR, o0, o1, o2, o3, o4 SWAP1 - // stack: BL, RD, o0, o1, o2, o3, o4 + // stack: VR, RD, o0, o1, o2, o3, o4 POP // stack: RD, o0, o1, o2, o3, o4 JUMP -/// def loop(*state): +/// def loop(STATE): /// while rounds: /// update_round_vars() -/// round(*state, F, K, rounds, sides) +/// round(STATE, F, K, rounds, sides) /// /// def update_round_vars(): /// F = load(F)(sides, rounds) /// K = load(K)(sides, rounds) /// -/// def round(*state, rounds, sides): +/// def round(STATE, rounds, sides): /// while boxes: -/// box(*state, F, K) +/// box(STATE, F, K) /// boxes -= 1 /// boxes = 16 /// rounds -= 1 loop: - // stack: *state, F, K, 16, rounds, sides, offset, retdest + // stack: STATE, F, K, 16, rounds, sides, virt, retdest DUP9 - // stack: round, *state, F, K, 16, rounds, sides, offset, retdest + // stack: round, STATE, F, K, 16, rounds, sides, virt, retdest %jumpi(update_round_vars) - // stack: *state, F, K, 16, 0, sides, offset, retdest - %stack (a, b, c, d, e, F, K, boxes, rounds, sides, offset, retdest) -> (retdest, a, b, c, d, e) - // stack: retdest, *state + // stack: STATE, F, K, 16, 0, sides, virt, retdest + %stack (a, b, c, d, e, F, K, boxes, rounds, sides, virt, retdest) -> (retdest, a, b, c, d, e) + // stack: retdest, STATE JUMP update_round_vars: - // stack: *state, F , K , 16, rounds, sides, offset, retdest + // stack: STATE, F , K , 16, rounds, sides, virt, retdest DUP9 DUP11 %get_round DUP1 - // stack: rnd, rnd, *state, F , K , 16, rounds, sides, offset, retdest + // stack: rnd, rnd, STATE, F , K , 16, rounds, sides, virt, retdest SWAP7 POP %push_F SWAP7 - // stack: rnd, rnd, *state, F', K , 16, rounds, sides, offset, retdest + // stack: rnd, rnd, STATE, F', K , 16, rounds, sides, virt, retdest SWAP8 POP %load_K SWAP7 POP - // stack: *state, F', K', 16, rounds, sides, offset, retdest + // stack: STATE, F', K', 16, rounds, sides, virt, retdest %jump(round) round: - // stack: *state, F, K, boxes, rounds , sides, offset, retdest + // stack: STATE, F, K, boxes, rounds , sides, virt, retdest DUP8 - // stack: boxes, *state, F, K, boxes, rounds , sides, offset, retdest + // stack: boxes, STATE, F, K, boxes, rounds , sides, virt, retdest %jumpi(box) - // stack: *state, F, K, 0, rounds , sides, offset, retdest + // stack: STATE, F, K, 0, rounds , sides, virt, retdest SWAP7 POP PUSH 16 SWAP7 - // stack: *state, F, K, 16, rounds , sides, offset, retdest + // stack: STATE, F, K, 16, rounds , sides, virt, retdest PUSH 1 DUP10 SUB SWAP9 POP - // stack: *state, F, K, 16, rounds-1, sides, offset, retdest + // stack: STATE, F, K, 16, rounds-1, sides, virt, retdest %jump(loop) -/// Note that we unpack *state to a, b, c, d, e +/// Note that we unpack STATE to a, b, c, d, e /// All additions are u32 /// /// def box(a, b, c, d, e, F, K): @@ -189,67 +189,67 @@ round: box: - // stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, b, c, d, e, F, K, boxes, rounds, sides, virt PUSH pre_rol DUP5 DUP5 DUP5 DUP10 - // stack: F, b, c, d, pre_rol, a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: F, b, c, d, pre_rol, a, b, c, d, e, F, K, boxes, rounds, sides, virt JUMP pre_rol: - // stack: F(b, c, d), a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: F(b, c, d), a, b, c, d, e, F, K, boxes, rounds, sides, virt ADD - // stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, b, c, d, e, F, K, boxes, rounds, sides, virt %get_box - // stack: box, a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: box, a, b, c, d, e, F, K, boxes, rounds, sides, virt DUP1 %load_byte(R_data) DUP13 ADD - // stack: offset + r, box, a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: virt + r, box, a, b, c, d, e, F, K, boxes, rounds, sides, virt %load_u32_from_block - // stack: x, box, a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: x, box, a, b, c, d, e, F, K, boxes, rounds, sides, virt SWAP1 SWAP2 - // stack: a, x, box, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, x, box, b, c, d, e, F, K, boxes, rounds, sides, virt ADD DUP8 ADD %u32 - // stack: a, box, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, box, b, c, d, e, F, K, boxes, rounds, sides, virt PUSH mid_rol SWAP2 - // stack: box, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: box, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, virt %load_byte(S_data) - // stack: s, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: s, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, virt %jump(rol) mid_rol: - // stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, b, c, d, e, F, K, boxes, rounds, sides, virt DUP5 - // stack: e, a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: e, a, b, c, d, e, F, K, boxes, rounds, sides, virt ADD %u32 - // stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset + // stack: a, b, c, d, e, F, K, boxes, rounds, sides, virt SWAP1 SWAP2 PUSH post_rol SWAP1 PUSH 10 - // stack: 10, c, post_rol, b, a, d, e, F, K, boxes, rounds, sides, offset + // stack: 10, c, post_rol, b, a, d, e, F, K, boxes, rounds, sides, virt %jump(rol) post_rol: - // stack: c, a, b, d, e, F, K, boxes , rounds, sides, offset + // stack: c, a, b, d, e, F, K, boxes , rounds, sides, virt SWAP3 - // stack: d, a, b, c, e, F, K, boxes , rounds, sides, offset + // stack: d, a, b, c, e, F, K, boxes , rounds, sides, virt SWAP4 - // stack: e, a, b, c, d, F, K, boxes , rounds, sides, offset + // stack: e, a, b, c, d, F, K, boxes , rounds, sides, virt SWAP7 PUSH 1 SWAP1 SUB SWAP7 - // stack: e, a, b, c, d, F, K, boxes-1, rounds, sides, offset + // stack: e, a, b, c, d, F, K, boxes-1, rounds, sides, virt %jump(round) diff --git a/evm/src/cpu/kernel/asm/ripemd/constants.asm b/evm/src/cpu/kernel/asm/ripemd/constants.asm index 69b75e86..b99df72a 100644 --- a/evm/src/cpu/kernel/asm/ripemd/constants.asm +++ b/evm/src/cpu/kernel/asm/ripemd/constants.asm @@ -28,7 +28,7 @@ K_data: ADD // stack: loc + box %mload_kernel_code - // stack: u8 + // stack: byte %endmacro diff --git a/evm/src/cpu/kernel/asm/ripemd/memory.asm b/evm/src/cpu/kernel/asm/ripemd/memory.asm index 0a170eb0..bc0e8a48 100644 --- a/evm/src/cpu/kernel/asm/ripemd/memory.asm +++ b/evm/src/cpu/kernel/asm/ripemd/memory.asm @@ -97,32 +97,32 @@ store_input: // stack: value PUSH $offset // stack: offset, value - %mstore_kernel(RipeMD) + %mstore_kernel(SEGMENT_RIPEMD) // stack: %endmacro %macro mstore_ripemd // stack: offset, value - %mstore_kernel(RipeMD) + %mstore_kernel(SEGMENT_RIPEMD) // stack: %endmacro %macro mload_ripemd - %mload_kernel(RipeMD) + %mload_kernel(SEGMENT_RIPEMD) %endmacro -// Load LE u32 from 4 contiguous bytes a, b, c, d in RipeMD segment +// Load LE u32 from 4 contiguous bytes a, b, c, d in SEGMENT_RIPEMD %macro load_u32_from_block // stack: offset DUP1 %mload_ripemd - // stack: a, offset + // stack: a , offset DUP2 %add_const(1) %mload_ripemd %shl_const(8) OR - // stack: a | (b << 8), offset + // stack: a | (b << 8) , offset DUP2 %add_const(2) %mload_ripemd @@ -136,3 +136,14 @@ store_input: OR // stack: a | (b << 8) | (c << 16) | (d << 24) %endmacro + +// set offset i to offset j in SEGMENT_RIPEMD +%macro mupdate_ripemd + // stack: j, i + %mload_ripemd + // stack: x, i + SWAP1 + %mstore_ripemd + // stack: +%endmacro + \ No newline at end of file diff --git a/evm/src/cpu/kernel/asm/ripemd/ripemd.asm b/evm/src/cpu/kernel/asm/ripemd/ripemd.asm index 46db0c2d..fb6777c7 100644 --- a/evm/src/cpu/kernel/asm/ripemd/ripemd.asm +++ b/evm/src/cpu/kernel/asm/ripemd/ripemd.asm @@ -9,43 +9,43 @@ /// /// ripemd is called on a stack with ADDR and length /// ripemd_update will receive and return the stack in the form: -/// stack: *state, count, length, offset -/// where offset is the virtual address of the bytes argument +/// stack: STATE, count, length, virt +/// where virt is the virtual address of the bytes argument global ripemd: // stack: ADDR, length $stack (a, b, c, length) -> (64, length, 0x80, 63, a, b, c, length, length) // stack: 64, length, 0x80, 63, a, b, c, length, length %jump(ripemd_storage) // stores the following into memory - // init _buffer at offset 0 [consumes 64] - // store _size at offset 64 [consumes length] - // store _padding at offset 72 [consumes 0x80, 63] - // store _input at offset 136 [consumes ADDR, length] + // init _buffer at virt 0 [consumes 64] + // store _size at virt 64 [consumes length] + // store _padding at virt 72 [consumes 0x80, 63] + // store _input at virt 136 [consumes ADDR, length] ripemd_init: // stack: length - %stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process) - // stack: count = 0, length, offset = 136, ripemd_1, ripemd_2, process + %stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process) + // stack: count = 0, length, virt = 136, ripemd_1, ripemd_2, process %stack (c, l, o, l1, l2, l3) -> (0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, c, l, o, l1, l2, l3) - // stack: 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, count, length, offset, *labels + // stack: 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0, count, length, virt, *labels %jump(ripemd_update) ripemd_1: - // stack: *state, count, length , offset, *labels + // stack: STATE, count, length , virt, *labels DUP7 - // stack: length, *state, count, length , offset, *labels + // stack: length, STATE, count, length , virt, *labels %padlength - // stack: padlength, *state, count, length , offset, *labels + // stack: padlength, STATE, count, length , virt, *labels SWAP7 POP - // stack: *state, count, length = padlength, offset, *labels - %stack (a, b, c, d, e, count, length, offset) -> (a, b, c, d, e, count, length, 72) + // stack: STATE, count, length = padlength, virt, *labels + %stack (a, b, c, d, e, count, length, virt) -> (a, b, c, d, e, count, length, 72) %jump(ripemd_update) ripemd_2: - // stack: *state, count, length, offset, *labels - %stack (a, b, c, d, e, count, length, offset) -> (a, b, c, d, e, count, 8, 64) - // stack: *state, count, length, offset, *labels + // stack: STATE, count, length, virt, *labels + %stack (a, b, c, d, e, count, length, virt) -> (a, b, c, d, e, count, 8, 64) + // stack: STATE, count, length, virt, *labels %jump(ripemd_update) process: - // stack: a , b, c, d, e, count, length, offset + // stack: a , b, c, d, e, count, length, virt %flip_bytes_u32 // stack: a', b, c, d, e, *vars SWAP1 diff --git a/evm/src/cpu/kernel/asm/ripemd/update.asm b/evm/src/cpu/kernel/asm/ripemd/update.asm index e69de29b..59b476a3 100644 --- a/evm/src/cpu/kernel/asm/ripemd/update.asm +++ b/evm/src/cpu/kernel/asm/ripemd/update.asm @@ -0,0 +1,151 @@ +/// 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 > 0 +/// if R: +/// buffer_update(virt + shift, have, length - shift) +/// +/// return state, count + 8*length, buffer + + +global ripemd_update: + // stack: STATE, count, length, virt, retdest + %stack (a, b, c, d, e, count, length, virt) -> (count, 8, 64, a, b, c, d, e, count, length, virt) + DIV + MOD + // stack: have, STATE, count, length, virt, retdest + DUP1 + PUSH 64 + SUB + PUSH 0 + // stack: shift, need, have, STATE, count, length, virt, retdest + %stack (shift, need, have, a, b, c, d, e, count, length) -> (length, need, a, b, c, d, e, 0, shift, need, have, count, length) + // stack: length, need, STATE, 0, shift, need, have, count, length, virt, retdest + LT + NOT + // stack: Q, STATE, 0, shift, need, have, count, length, virt, retdest + %stack (Q, STATE, 0, shift, need, have) -> (have, Q, Q, STATE, 0, shift, need, have) + AND + // stack: P, Q, STATE, 0, shift, need, have, count, length, virt, retdest + %jumpi(update_1) + // stack: Q, STATE, 0, shift, need, have, count, length, virt, retdest + %jumpi(update_2) +final_update: + // stack: shift, need, have, STATE, count, length, virt, retdest + %stack (shift, need, have, a, b, c, d, e, count, length) -> (length, shift, return_step, shift, need, have, a, b, c, d, e, count, length) + SUB + // stack: ARGS, shift, need, have, STATE, count, length, virt, retdest + %stack (a, r, shift, need, have, a, b, c, d, e, count, length, virt) -> (shift, virt, have, a, r, shift, need, have, a, b, c, d, e, count, length, virt) + ADD + // stack: ARGS, shift, need, have, STATE, count, length, virt, retdest + PUSH 0 + DUP4 + GT + // stack: R, ARGS, shift, need, have, STATE, count, length, virt, retdest + %jumpi(buffer_update) + // stack: ARGS, shift, need, have, STATE, count, length, virt, retdest + *pop3 + JUMP +return_step: + // stack: shift, need, have, STATE, count, length, virt, retdest + SWAP8 + DUP10 + %mul_const(8) + ADD + SWAP8 + // stack: shift, need, have, STATE, count += 8*length, length, virt, retdest + %stack (shift, need, have, a, b, c, d, e, count, length, virt, retdest) -> (retdest, a, b, c, d, e, count, length, virt) + JUMP + + +/// def update_1(): +/// buffer_update(virt, have, need) +/// shift = need +/// have = 0 +/// state = compress(state, buffer) + +update_1: + // stack: Q, STATE, 0, shift, need, have, count, length, virt, retdest + %stack (Q, a, b, c, d, e, 0, shift, need, have, count, length, virt) -> (virt, have, need, update_1a, a, b, c, d, e, 0, shift, need, have, count, length, virt) + %jump(buffer_update) +update_1a: + // stack: STATE, 0, shift, need, have, count, length, virt, retdest + %stack (a, b, c, d, e, 0, shift, need, have) -> (a, b, c, d, e, 0, update_2, need, need, 0) + // stack: STATE, 0, update_2, shift, need, have, count, length, virt, retdest + %jump(compress) + +/// def update_2(): +/// cond = length - shift - 64 +/// while cond >= 0: +/// state = compress(state, bytestring[shift:]) +/// shift += 64 +/// cond -= 64 + +update_2: + // stack: STATE, shift, need, have, count, length, virt, retdest + %stack (a, b, c, d, e, shift, need, have, count, length) -> (length, shift, a, b, c, d, e, shift, need, have, count, length) + SUB + SUB + // stack: cond, STATE, shift, need, have, count, length, virt, retdest + DUP12 + DUP8 + ADD + // stack: offset, cond, STATE, shift, need, have, count, length, virt, retdest + %stack (offset, cond, a, b, c, d, e) -> (cond, 0, a, b, c, d, e, offset, compression_loop, cond) + LT + NOT + // cond >= 0, STATE, offset, compression_loop, cond, shift, need, have, count, length, virt, retdest + %jumpi(compress) +compression_loop: + // stack: STATE, offset , cond , shift, need, have, count, length, virt, retdest + SWAP5 + %add_const(64) + SWAP5 + SWAP6 + %sub_const(64) + SWAP6 + SWAP7 + %add_const(64) + SWAP7 + // stack: STATE, offset+64, cond-64, shift+64, need, have, count, length, virt, retdest + %stack (a, b, c, d, e, offset, cond, shift) -> (cond, 0, a, b, c, d, e, offset, compression_loop, cond, shift) + %jumpi(compress) + // stack: STATE, offset , label, cond , shift , need, have, count, length, virt, retdest + %stack (a, b, c, d, e, offset, label, cond, shift, need, have, count, length, virt, retdest) -> (shift, need, have, a, b, c, d, e, count, length, virt, retdest) + %jump(final_update) + + +/// def buffer_update(get, set, times): +/// for i in range(times): +/// buffer[set+i] = bytestring[get+i] + +buffer_update: + // stack: get , set , times , retdest + DUP2 + DUP2 + // stack: get, set, get , set , times , retdest + %mupdate_ripemd + // stack: get , set , times , retdest + %add_const(1) + SWAP1 + %add_const(1) + SWAP1 + SWAP2 + %sub_const(1) + SWAP2 + // stack: get+1, set+1, times-1, retdest + DUP3 + %jumpi(buffer_update) + // stack: get , set , 0 , retdest + %pop3 + JUMP diff --git a/evm/src/memory/segments.rs b/evm/src/memory/segments.rs index b725211c..93ef8514 100644 --- a/evm/src/memory/segments.rs +++ b/evm/src/memory/segments.rs @@ -29,7 +29,7 @@ pub(crate) enum Segment { } impl Segment { - pub(crate) const COUNT: usize = 11; + pub(crate) const COUNT: usize = 12; pub(crate) fn all() -> [Self; Self::COUNT] { [ @@ -44,7 +44,7 @@ impl Segment { Self::TxnFields, Self::TxnData, Self::RlpRaw, - Self::RipeMD + Self::RipeMD, ] }