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 // stack: (((((c_3 << 8) | c_2) << 8) | c_1) << 8) | c_0
%endmacro %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. // Store a single byte to kernel code.
%macro mstore_kernel_code %macro mstore_kernel_code
// stack: offset, value // 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 /// Note that state takes up 5 stack slots
/// def compression(state, _block): /// def compression(state, _offset):
/// ///
/// stateL = state /// stateL = state
/// stateL = loop(stateL) /// stateL = loop(stateL)
@ -22,10 +22,10 @@
/// u32(s0 + l1 + r2) /// u32(s0 + l1 + r2)
/// ///
/// where si, li, ri, oi, BL, RD respectively denote /// 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: global compression:
// stack: *state, block, retdest // stack: *state, offset, retdest
PUSH switch PUSH switch
DUP7 DUP7
PUSH 1 PUSH 1
@ -33,16 +33,16 @@ global compression:
PUSH 16 PUSH 16
PUSH 0 PUSH 0
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 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) %jump(loop)
switch: switch:
// stack: *stateL, *state, block, retdest // stack: *stateL, *state, offset, retdest
PUSH mix PUSH mix
DUP12 DUP12
PUSH 0 PUSH 0
@ -50,13 +50,13 @@ switch:
PUSH 16 PUSH 16
PUSH 0 PUSH 0
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 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) %jump(loop)
mix: 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, BL, RD
@ -123,50 +123,50 @@ mix:
loop: loop:
// stack: *state, F, K, 16, rounds, sides, block, retdest // stack: *state, F, K, 16, rounds, sides, offset, retdest
DUP9 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) %jumpi(update_round_vars)
// stack: *state, F, K, 16, 0, sides, block, retdest // stack: *state, F, K, 16, 0, sides, offset, retdest
%stack (a, b, c, d, e, F, K, boxes, rounds, sides, block, retdest) -> (retdest, a, b, c, d, e) %stack (a, b, c, d, e, F, K, boxes, rounds, sides, offset, retdest) -> (retdest, a, b, c, d, e)
// stack: retdest, *state // stack: retdest, *state
JUMP JUMP
update_round_vars: update_round_vars:
// stack: *state, F , K , 16, rounds, sides, block, retdest // stack: *state, F , K , 16, rounds, sides, offset, retdest
DUP9 DUP9
DUP11 DUP11
%get_round %get_round
DUP1 DUP1
// stack: rnd, rnd, *state, F , K , 16, rounds, sides, block, retdest // stack: rnd, rnd, *state, F , K , 16, rounds, sides, offset, retdest
SWAP7 SWAP7
POP POP
%push_F %push_F
SWAP7 SWAP7
// stack: rnd, rnd, *state, F', K , 16, rounds, sides, block, retdest // stack: rnd, rnd, *state, F', K , 16, rounds, sides, offset, retdest
SWAP8 SWAP8
POP POP
%load_u32(K_data) %load_K
SWAP7 SWAP7
POP POP
// stack: *state, F', K', 16, rounds, sides, block, retdest // stack: *state, F', K', 16, rounds, sides, offset, retdest
%jump(round) %jump(round)
round: round:
// stack: *state, F, K, boxes, rounds , sides, block, retdest // stack: *state, F, K, boxes, rounds , sides, offset, retdest
DUP8 DUP8
// stack: boxes, *state, F, K, boxes, rounds , sides, block, retdest // stack: boxes, *state, F, K, boxes, rounds , sides, offset, retdest
%jumpi(box) %jumpi(box)
// stack: *state, F, K, 0, rounds , sides, block, retdest // stack: *state, F, K, 0, rounds , sides, offset, retdest
SWAP7 SWAP7
POP POP
PUSH 16 PUSH 16
SWAP7 SWAP7
// stack: *state, F, K, 16, rounds , sides, block, retdest // stack: *state, F, K, 16, rounds , sides, offset, retdest
PUSH 1 PUSH 1
DUP10 DUP10
SUB SUB
SWAP9 SWAP9
POP POP
// stack: *state, F, K, 16, rounds-1, sides, block, retdest // stack: *state, F, K, 16, rounds-1, sides, offset, retdest
%jump(loop) %jump(loop)
@ -178,7 +178,7 @@ round:
/// box = get_box(sides, rounds, boxes) /// box = get_box(sides, rounds, boxes)
/// a += F(b, c, d) /// a += F(b, c, d)
/// r = load_byte(r)(box) /// r = load_byte(r)(box)
/// x = load_block(r) /// x = load_offset(r)
/// a += x + K /// a += x + K
/// s = load_byte(s)(box) /// s = load_byte(s)(box)
/// a = rol(s, a) /// a = rol(s, a)
@ -189,66 +189,67 @@ round:
box: 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 PUSH pre_rol
DUP5 DUP5
DUP5 DUP5
DUP5 DUP5
DUP10 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 JUMP
pre_rol: 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 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 %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 DUP1
%load_byte(R_data) %load_byte(R_data)
DUP13 DUP13
// stack: block, r, box, a, b, c, d, e, F, K, boxes, rounds, sides, block ADD
%load_from_block // stack: offset + r, 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, block %load_u32_from_block
// stack: x, box, a, b, c, d, e, F, K, boxes, rounds, sides, offset
SWAP1 SWAP1
SWAP2 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 ADD
DUP8 DUP8
ADD ADD
%u32 %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 PUSH mid_rol
SWAP2 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) %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) %jump(rol)
mid_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 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 ADD
%u32 %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 SWAP1
SWAP2 SWAP2
PUSH post_rol PUSH post_rol
SWAP1 SWAP1
PUSH 10 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) %jump(rol)
post_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 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 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 SWAP7
PUSH 1 PUSH 1
SWAP1 SWAP1
SUB SUB
SWAP7 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) %jump(round)
@ -258,7 +259,6 @@ post_rol:
// stack: 10 - 5*sides - rounds // stack: 10 - 5*sides - rounds
%endmacro %endmacro
%macro get_box %macro get_box
// stack: *7_args, boxes, rounds, sides // stack: *7_args, boxes, rounds, sides
DUP10 DUP10

View File

@ -1,11 +1,10 @@
%macro load_u32(loc) %macro load_K
// stack: rnd // stack: rnd
%mul_const(4) %mul_const(4)
push $loc %add_const(K_data)
ADD // stack: K_data + 4*rnd
// stack: loc + 4*rnd
%mload_kernel_code_u32 %mload_kernel_code_u32
// stack: u32 // stack: K
%end_macro %end_macro
K_data: 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): /// def ripemd160(_input):
/// state, count, _buffer = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], 0, [0]*64 /// 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, len(input) , bytes = _input )
/// state, count, _buffer = ripemd_update(state, count, _buffer, padlength(len(input)), [0x80]+[0]*63) /// state, count, _buffer = ripemd_update(state, count, _buffer, padlength(len(input)), bytes = [0x80]+[0]*63)
/// state, count, _buffer = ripemd_update(state, count, _buffer, 8, size(len(_input))) /// state, count, _buffer = ripemd_update(state, count, _buffer, 8, bytes = size(len(_input)))
/// return process(state) /// return process(state)
///
/// ripemd is called on a stack with ADDR and length /// ripemd is called on a stack with ADDR and length
/// ripemd_update will receive and return the stack in the form: /// ripemd_update will receive and return the stack in the form:
/// stack: *state, count, length, offset /// 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: global ripemd:
// stack: ADDR, length // stack: ADDR, length
DUP4 $stack (a, b, c, length) -> (64, length, 0x80, 63, a, b, c, length, length)
// stack: length, ADDR, length // stack: 64, length, 0x80, 63, a, b, c, length, length
%init_buffer // init _buffer at offset 0 %jump(ripemd_storage) // stores the following into memory
%store_size // store _size at offset 64 [consumes length] // init _buffer at offset 0 [consumes 64]
%store_padding // store _padding at offset 72 // store _size at offset 64 [consumes length]
%store_input // store _input at offset 136 [consumes ADDR] // store _padding at offset 72 [consumes 0x80, 63]
// store _input at offset 136 [consumes ADDR, length]
ripemd_init:
// stack: length // stack: length
%stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process) %stack (length) -> ( 0, length, 136, ripemd_1, ripemd_2, process)
// stack: count = 0, length, offset = 136, ripemd_1, ripemd_2, process // stack: count = 0, length, offset = 136, ripemd_1, ripemd_2, process