ripemd storage

This commit is contained in:
Dmitry Vagner 2022-09-19 12:09:57 -07:00
parent c45785f4a5
commit e151be5522
6 changed files with 200 additions and 109 deletions

View File

@ -85,32 +85,6 @@
// stack: (((((c_3 << 8) | c_2) << 8) | c_1) << 8) | c_0
%endmacro
// Load a little-endian u32, consisting of 4 bytes (c_0, c_1, c_2, c_3),
// from kernel code.
%macro mload_kernel_code_u32_LE
// stack: offset
DUP1
%mload_kernel_code
// stack: c_0, offset
DUP2
%add_const(1)
%mload_kernel_code
%shl_const(8)
// stack: c0 | (c1 << 8), offset
DUP2
%add_const(2)
%mload_kernel_code
%shl_const(16)
// stack: c0 | (c1 << 8) | (c2 << 16), offset
SWAP1
%add_const(3)
%mload_kernel_code
%shl_const(24)
// stack: c0 | (c1 << 8) | (c2 << 16) | (c3 << 24)
%endmacro
// Store a single byte to kernel code.
%macro mstore_kernel_code
// stack: offset, value

View File

@ -1,8 +1,8 @@
/// _block is stored in memory and its address block remains on the stack
/// _offset is stored in memory and its address offset remains on the stack
/// Note that state takes up 5 stack slots
/// def compression(state, _block):
/// def compression(state, _offset):
///
/// stateL = state
/// stateL = loop(stateL)
@ -22,10 +22,10 @@
/// u32(s0 + l1 + r2)
///
/// where si, li, ri, oi, BL, RD respectively denote
/// state[i], stateL[i], stateR[i], output[i], block, retdest
/// state[i], stateL[i], stateR[i], output[i], offset, retdest
global compression:
// stack: *state, block, retdest
// stack: *state, offset, retdest
PUSH switch
DUP7
PUSH 1
@ -33,16 +33,16 @@ global compression:
PUSH 16
PUSH 0
PUSH 0
// stack: 0, 0, 16, 5, 1, block, switch, *state, block, retdest
// stack: 0, 0, 16, 5, 1, offset, switch, *state, offset, retdest
DUP12
DUP12
DUP12
DUP12
DUP12
// stack: *state, 0, 0, 16, 5, 1, block, switch, *state, block, retdest
// stack: *state, 0, 0, 16, 5, 1, offset, switch, *state, offset, retdest
%jump(loop)
switch:
// stack: *stateL, *state, block, retdest
// stack: *stateL, *state, offset, retdest
PUSH mix
DUP12
PUSH 0
@ -50,13 +50,13 @@ switch:
PUSH 16
PUSH 0
PUSH 0
// stack: 0, 0, 16, 5, 0, block, mix, *stateL, *state, block, retdest
// stack: 0, 0, 16, 5, 0, offset, mix, *stateL, *state, offset, retdest
DUP17
DUP17
DUP17
DUP17
DUP17
// stack: *state, 0, 0, 16, 5, 0, block, mix, *stateL, *state, block, retdest
// stack: *state, 0, 0, 16, 5, 0, offset, mix, *stateL, *state, offset, retdest
%jump(loop)
mix:
// stack: r0, r1, r2, r3, r4, l0, l1, l2, l3, l4, s0, s1, s2, s3, s4, BL, RD
@ -123,50 +123,50 @@ mix:
loop:
// stack: *state, F, K, 16, rounds, sides, block, retdest
// stack: *state, F, K, 16, rounds, sides, offset, retdest
DUP9
// stack: round, *state, F, K, 16, rounds, sides, block, retdest
// stack: round, *state, F, K, 16, rounds, sides, offset, retdest
%jumpi(update_round_vars)
// stack: *state, F, K, 16, 0, sides, block, retdest
%stack (a, b, c, d, e, F, K, boxes, rounds, sides, block, retdest) -> (retdest, a, b, c, d, e)
// 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
JUMP
update_round_vars:
// stack: *state, F , K , 16, rounds, sides, block, retdest
// stack: *state, F , K , 16, rounds, sides, offset, retdest
DUP9
DUP11
%get_round
DUP1
// stack: rnd, rnd, *state, F , K , 16, rounds, sides, block, retdest
// stack: rnd, rnd, *state, F , K , 16, rounds, sides, offset, retdest
SWAP7
POP
%push_F
SWAP7
// stack: rnd, rnd, *state, F', K , 16, rounds, sides, block, retdest
// stack: rnd, rnd, *state, F', K , 16, rounds, sides, offset, retdest
SWAP8
POP
%load_u32(K_data)
%load_K
SWAP7
POP
// stack: *state, F', K', 16, rounds, sides, block, retdest
// stack: *state, F', K', 16, rounds, sides, offset, retdest
%jump(round)
round:
// stack: *state, F, K, boxes, rounds , sides, block, retdest
// stack: *state, F, K, boxes, rounds , sides, offset, retdest
DUP8
// stack: boxes, *state, F, K, boxes, rounds , sides, block, retdest
// stack: boxes, *state, F, K, boxes, rounds , sides, offset, retdest
%jumpi(box)
// stack: *state, F, K, 0, rounds , sides, block, retdest
// stack: *state, F, K, 0, rounds , sides, offset, retdest
SWAP7
POP
PUSH 16
SWAP7
// stack: *state, F, K, 16, rounds , sides, block, retdest
// stack: *state, F, K, 16, rounds , sides, offset, retdest
PUSH 1
DUP10
SUB
SWAP9
POP
// stack: *state, F, K, 16, rounds-1, sides, block, retdest
// stack: *state, F, K, 16, rounds-1, sides, offset, retdest
%jump(loop)
@ -178,7 +178,7 @@ round:
/// box = get_box(sides, rounds, boxes)
/// a += F(b, c, d)
/// r = load_byte(r)(box)
/// x = load_block(r)
/// x = load_offset(r)
/// a += x + K
/// s = load_byte(s)(box)
/// a = rol(s, a)
@ -189,66 +189,67 @@ round:
box:
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset
PUSH pre_rol
DUP5
DUP5
DUP5
DUP10
// stack: F, b, c, d, pre_rol, a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: F, b, c, d, pre_rol, a, b, c, d, e, F, K, boxes, rounds, sides, offset
JUMP
pre_rol:
// stack: F(b, c, d), a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: F(b, c, d), a, b, c, d, e, F, K, boxes, rounds, sides, offset
ADD
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset
%get_box
// stack: box, a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: box, a, b, c, d, e, F, K, boxes, rounds, sides, offset
DUP1
%load_byte(R_data)
DUP13
// stack: block, r, box, a, b, c, d, e, F, K, boxes, rounds, sides, block
%load_from_block
// stack: x, box, a, b, c, d, e, F, K, boxes, rounds, sides, block
ADD
// stack: offset + r, box, a, b, c, d, e, F, K, boxes, rounds, sides, offset
%load_u32_from_block
// stack: x, box, a, b, c, d, e, F, K, boxes, rounds, sides, offset
SWAP1
SWAP2
// stack: a, x, box, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, x, box, b, c, d, e, F, K, boxes, rounds, sides, offset
ADD
DUP8
ADD
%u32
// stack: a, box, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, box, b, c, d, e, F, K, boxes, rounds, sides, offset
PUSH mid_rol
SWAP2
// stack: box, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: box, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, offset
%load_byte(S_data)
// stack: s, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: s, a, mid_rol, b, c, d, e, F, K, boxes, rounds, sides, offset
%jump(rol)
mid_rol:
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset
DUP5
// stack: e, a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: e, a, b, c, d, e, F, K, boxes, rounds, sides, offset
ADD
%u32
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, block
// stack: a, b, c, d, e, F, K, boxes, rounds, sides, offset
SWAP1
SWAP2
PUSH post_rol
SWAP1
PUSH 10
// stack: 10, c, post_rol, b, a, d, e, F, K, boxes, rounds, sides, block
// stack: 10, c, post_rol, b, a, d, e, F, K, boxes, rounds, sides, offset
%jump(rol)
post_rol:
// stack: c, a, b, d, e, F, K, boxes , rounds, sides, block
// stack: c, a, b, d, e, F, K, boxes , rounds, sides, offset
SWAP3
// stack: d, a, b, c, e, F, K, boxes , rounds, sides, block
// stack: d, a, b, c, e, F, K, boxes , rounds, sides, offset
SWAP4
// stack: e, a, b, c, d, F, K, boxes , rounds, sides, block
// stack: e, a, b, c, d, F, K, boxes , rounds, sides, offset
SWAP7
PUSH 1
SWAP1
SUB
SWAP7
// stack: e, a, b, c, d, F, K, boxes-1, rounds, sides, block
// stack: e, a, b, c, d, F, K, boxes-1, rounds, sides, offset
%jump(round)
@ -258,7 +259,6 @@ post_rol:
// stack: 10 - 5*sides - rounds
%endmacro
%macro get_box
// stack: *7_args, boxes, rounds, sides
DUP10

View File

@ -1,11 +1,10 @@
%macro load_u32(loc)
%macro load_K
// stack: rnd
%mul_const(4)
push $loc
ADD
// stack: loc + 4*rnd
%add_const(K_data)
// stack: K_data + 4*rnd
%mload_kernel_code_u32
// stack: u32
// stack: K
%end_macro
K_data:

View File

@ -0,0 +1,138 @@
ripemd_storage: // starts by initializing buffer
// stack: i (init 64)
%store_zeros(64, ripemd_storage)
// stack:
%jump(store_size)
store_size:
// stack: length
%shl_const(3)
// stack: abcdefgh
%extract_and_store_byte(64)
// stack: abcdefg
%extract_and_store_byte(65)
// stack: abcdef
%extract_and_store_byte(66)
// stack: abcde
%extract_and_store_byte(67)
// stack: abcd
%extract_and_store_byte(68)
// stack: abc
%extract_and_store_byte(69)
// stack: ab
%extract_and_store_byte(70)
// stack: a
%mstore_ripemd(71)
// stack: 0x80 // padding has 0x80 in first position and zeros elsewhere
%mstore_ripemd(72) // store first padding term here so as to avoid extra label
%jump(store_padding)
store_padding:
// stack: i (init 63)
%store_zeros(136, store_padding)
%jump(store_input)
store_input:
// stack: ADDR , rem , length
DUP3
DUP3
DUP3
MLOAD_GENERAL
// stack: byte, ADDR , rem , length
DUP5
DUP7
SUB
%add_const(136)
// stack: offset, byte, ADDR , rem , length
%mstore_ripemd
// stack: ADDR , rem , length
SWAP2
%add_const(1)
SWAP2
// stack: ADDR + 1, rem , length
SWAP3
%sub_const(1)
SWAP3
// stack: ADDR + 1, rem - 1, length
DUP4
%jumpi(store_input)
// stack: ADDR , 0 , length
%pop4
// stack: length
%jump(ripemd_init)
%macro store_zeros(N, label)
// stack: i
%stack (i) -> ($N, i, 0, i)
SUB
// stack: offset = N-i, 0, i
%mstore_ripemd
// stack: i
%sub_const(1)
DUP1
// stack: i-1, i-1
%jumpi($label)
// stack: 0
POP
%endmacro
%macro extract_and_store_byte(offset)
// stack: xsy
PUSH 0x100
DUP2
MOD
// stack: y, xsy
%stack (y, xsy) -> (xsy, y, 0x100, y)
// stack: xsy, y, 0x100, y
SUB
DIV
SWAP1
// stack: y, xs
%mstore_ripemd($offset)
// stack: xs
%endmacro
%macro mstore_ripemd_offset($offset)
// stack: value
PUSH $offset
// stack: offset, value
%mstore_kernel(RipeMD)
// stack:
%endmacro
%macro mstore_ripemd
// stack: offset, value
%mstore_kernel(RipeMD)
// stack:
%endmacro
%macro mload_ripemd
%mload_kernel(RipeMD)
%endmacro
// Load LE u32 from 4 contiguous bytes a, b, c, d in RipeMD segment
%macro load_u32_from_block
// stack: offset
DUP1
%mload_ripemd
// stack: a, offset
DUP2
%add_const(1)
%mload_ripemd
%shl_const(8)
OR
// stack: a | (b << 8), offset
DUP2
%add_const(2)
%mload_ripemd
%shl_const(16)
OR
// stack: a | (b << 8) | (c << 16), offset
SWAP1
%add_const(3)
%mload_ripemd
%shl_const(24)
OR
// stack: a | (b << 8) | (c << 16) | (d << 24)
%endmacro

View File

@ -1,22 +0,0 @@
%macro load_from_block
// stack: block, r
ADD
// stack: offset = block + r
%endmacro
%macro init_buffer
%endmacro
%macro store_input
// stack: ADDR
%endmacro
%macro store_padding
%endmacro
%macro store_size
// stack: length
%shl_const(3)
// stack: length
%endmacro

View File

@ -2,24 +2,26 @@
///
/// def ripemd160(_input):
/// state, count, _buffer = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], 0, [0]*64
/// state, count, _buffer = ripemd_update(state, count, _buffer, len(input) , _input )
/// state, count, _buffer = ripemd_update(state, count, _buffer, padlength(len(input)), [0x80]+[0]*63)
/// state, count, _buffer = ripemd_update(state, count, _buffer, 8, size(len(_input)))
/// 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)
///
/// 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 its final positional argument
/// where offset is the virtual address of the bytes argument
global ripemd:
// stack: ADDR, length
DUP4
// stack: length, ADDR, length
%init_buffer // init _buffer at offset 0
%store_size // store _size at offset 64 [consumes length]
%store_padding // store _padding at offset 72
%store_input // store _input at offset 136 [consumes ADDR]
$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]
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