fixes galore

This commit is contained in:
Nicholas Ward 2022-11-29 16:22:23 -08:00
parent d3a7201348
commit 245e5faa6d
6 changed files with 221 additions and 94 deletions

View File

@ -21,8 +21,8 @@
%mload_kernel_general %mload_kernel_general
// stack: num_blocks // stack: num_blocks
%mul_const(128) %mul_const(128)
%increment %add_const(2)
// stack: num_bytes+1 // stack: num_bytes+2
%endmacro %endmacro
// Address where the working version of the compression internal state is stored. // Address where the working version of the compression internal state is stored.
@ -56,41 +56,108 @@
// stack: h_i' = v_(i+8) ^ v_i ^ h_i, ... // stack: h_i' = v_(i+8) ^ v_i ^ h_i, ...
%endmacro %endmacro
%macro invert_bytes_blake_word
// stack: word, ...
DUP1
%and_const(0xff)
%shl_const(56)
SWAP1
// stack: word, first_byte, ...
DUP1
%shr_const(8)
%and_const(0xff)
%shl_const(48)
SWAP1
// stack: word, second_byte, first_byte, ...
DUP1
%shr_const(16)
%and_const(0xff)
%shl_const(40)
SWAP1
DUP1
%shr_const(24)
%and_const(0xff)
%shl_const(32)
SWAP1
DUP1
%shr_const(32)
%and_const(0xff)
%shl_const(24)
SWAP1
DUP1
%shr_const(40)
%and_const(0xff)
%shl_const(16)
SWAP1
DUP1
%shr_const(48)
%and_const(0xff)
%shl_const(8)
SWAP1
%shr_const(56)
%and_const(0xff)
%rep 7
OR
%endrep
%endmacro
global blake_compression: global blake_compression:
// stack: retdest // stack: retdest
%stack () -> (0, 0, 0) PUSH 0
// stack: cur_block = 0, t_0 = 0, t_1 = 0, retdest // stack: cur_block = 0, retdest
%blake_initial_hash_value %blake_initial_hash_value
// stack: h_0, ..., h_7, cur_block, t_0, t_1, retdest // stack: h_0, ..., h_7, cur_block, retdest
%blake_hash_value_addr %blake_hash_value_addr
// stack: addr, h_0, ..., h_7, cur_block, t_0, t_1, retdest // stack: addr, h_0, ..., h_7, cur_block, retdest
%rep 8 %rep 8
SWAP1 SWAP1
DUP2 DUP2
%mstore_kernel_general %mstore_kernel_general
%increment %increment
%endrep %endrep
// stack: addr, cur_block, t_0, t_1, retdest // stack: addr, cur_block, retdest
POP POP
// stack: cur_block, t_0, t_1, retdest // stack: cur_block, retdest
compression_loop: compression_loop:
// stack: cur_block, t_0, t_1, retdest // stack: cur_block, retdest
PUSH 0 PUSH 0
%mload_kernel_general %mload_kernel_general
// stack: num_blocks, cur_block, t_0, t_1, retdest // stack: num_blocks, cur_block, retdest
%decrement %decrement
// stack: num_blocks - 1, cur_block, t_0, t_1, retdest // stack: num_blocks - 1, cur_block, retdest
DUP2 DUP2
// stack: cur_block, num_blocks - 1, cur_block, t_0, t_1, retdest // stack: cur_block, num_blocks - 1, cur_block, retdest
EQ EQ
// stack: is_last_block, cur_block, t_0, t_1, retdest // stack: is_last_block, cur_block, retdest
SWAP1 SWAP1
// stack: cur_block, is_last_block, t_0, t_1, retdest // stack: cur_block, is_last_block, retdest
PUSH 1
%mload_kernel_general
// stack: num_bytes, cur_block, is_last_block, retdest
DUP3
// stack: is_last_block, num_bytes, cur_block, is_last_block, retdest
MUL
// stack: is_last_block * num_bytes, cur_block, is_last_block, retdest
DUP2
// stack: cur_block, is_last_block * num_bytes, cur_block, is_last_block, retdest
%mul_const(128) %mul_const(128)
%increment // stack: cur_block * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest
// stack: cur_block_start_byte, is_last_block, t_0, t_1, retdest DUP4
// stack: is_last_block, cur_block * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest
ISZERO
// stack: not_last_block, cur_block * 128, is_last_block * num_bytes, cur_block, is_last_block, retdest
MUL
// stack: not_last_block * (cur_block * 128), is_last_block * num_bytes, cur_block, is_last_block, retdest
ADD
// stack: t = not_last_block * (cur_block * 128) + is_last_block * num_bytes, cur_block, is_last_block, retdest
SWAP1
// stack: cur_block, t, is_last_block, retdest
// stack: cur_block, t, is_last_block, retdest
%mul_const(128)
%add_const(2)
// stack: cur_block_start_byte, t, is_last_block, retdest
%blake_message_addr %blake_message_addr
// stack: message_addr, cur_block_start_byte, is_last_block, t_0, t_1, retdest // stack: message_addr, cur_block_start_byte, t, is_last_block, retdest
%rep 16 %rep 16
// stack: cur_message_addr, cur_block_byte, ... // stack: cur_message_addr, cur_block_byte, ...
DUP2 DUP2
@ -105,19 +172,19 @@ compression_loop:
// stack: cur_message_addr + 1, cur_block_byte, ... // stack: cur_message_addr + 1, cur_block_byte, ...
SWAP1 SWAP1
// stack: cur_block_byte, cur_message_addr + 1, ... // stack: cur_block_byte, cur_message_addr + 1, ...
%add_const(64) %add_const(8)
// stack: cur_block_byte + 64, cur_message_addr + 1, ... // stack: cur_block_byte + 8, cur_message_addr + 1, ...
SWAP1 SWAP1
// stack: cur_message_addr + 1, cur_block_byte + 64, ... // stack: cur_message_addr + 1, cur_block_byte + 8, ...
%endrep %endrep
// stack: end_message_addr, end_block_start_byte, is_last_block, t_0, t_1, retdest // stack: end_message_addr, end_block_start_byte, t, is_last_block, retdest
POP POP
POP POP
// stack: is_last_block, t_0, t_1, retdest // stack: t, is_last_block, retdest
SWAP1
// stack: is_last_block, t, retdest
%mul_const(0xFFFFFFFFFFFFFFFF) %mul_const(0xFFFFFFFFFFFFFFFF)
// stack: invert_if_last_block, t_0, t_1, retdest // stack: invert_if_last_block, t, retdest
%stack (l, t0, t1) -> (t0, t1, l, 0)
// stack: t_0, t_1, invert_if_last_block, 0, retdest
%blake_hash_value_addr %blake_hash_value_addr
%add_const(7) %add_const(7)
%rep 8 %rep 8
@ -130,11 +197,11 @@ compression_loop:
// stack: addr, val, ... // stack: addr, val, ...
%decrement %decrement
%endrep %endrep
// stack: addr, h_0, ..., h_7, t_0, t_1, invert_if_last_block, 0, retdest // stack: addr, h_0, ..., h_7, invert_if_last_block, t, retdest
POP POP
// stack: h_0, ..., h_7, t_0, t_1, invert_if_last_block, 0, retdest // stack: h_0, ..., h_7, invert_if_last_block, t, retdest
%blake_internal_state_addr %blake_internal_state_addr
// stack: start, h_0, ..., h_7, t_0, t_1, invert_if_last_block, 0, retdest // stack: start, h_0, ..., h_7, invert_if_last_block, t, retdest
// First eight words of compression state: current state h_0, ..., h_7. // First eight words of compression state: current state h_0, ..., h_7.
%rep 8 %rep 8
SWAP1 SWAP1
@ -142,9 +209,9 @@ compression_loop:
%mstore_kernel_general %mstore_kernel_general
%increment %increment
%endrep %endrep
// stack: start + 8, t_0, t_1, invert_if_last_block, 0, retdest // stack: start + 8, invert_if_last_block, t, retdest
PUSH 0 PUSH 0
// stack: 0, start + 8, t_0, t_1, invert_if_last_block, 0, retdest // stack: 0, start + 8, invert_if_last_block, t, retdest
%rep 4 %rep 4
// stack: i, loc, ... // stack: i, loc, ...
DUP2 DUP2
@ -162,8 +229,22 @@ compression_loop:
SWAP1 SWAP1
// stack: i + 1, loc + 1,... // stack: i + 1, loc + 1,...
%endrep %endrep
// stack: 4, start + 12, t_0, t_1, invert_if_last_block, 0, retdest // stack: 4, start + 12, invert_if_last_block, t, retdest
// XOR the values (t_0, t_1, invert_if, 0) into the last four IV values. %stack (i, loc, inv, t) -> (t, t, i, loc, inv)
// stack: t, t, 4, start + 12, invert_if_last_block, retdest
%shr_const(64)
// stack: t >> 64, t, 4, start + 12, invert_if_last_block, retdest
SWAP1
// stack: t, t >> 64, 4, start + 12, invert_if_last_block, retdest
PUSH 1
%shl_const(64)
// stack: 1 << 64, t, t >> 64, 4, start + 12, invert_if_last_block, retdest
SWAP1
MOD
// stack: t_lo = t % (1 << 64), t_hi = t >> 64, 4, start + 12, invert_if_last_block, retdest
%stack (t_lo, t_hi, i, loc, inv) -> (i, loc, t_lo, t_hi, inv, 0)
// stack: 4, start + 12, t_lo, t_hi, invert_if_last_block, 0, retdest
// XOR the values (t % 2**64, t >> 64, invert_if, 0) into the last four IV values.
%rep 4 %rep 4
// stack: i, loc, val, next_val,... // stack: i, loc, val, next_val,...
%stack (i, loc, val) -> (i, val, loc, i, loc) %stack (i, loc, val) -> (i, val, loc, i, loc)
@ -182,24 +263,6 @@ compression_loop:
SWAP1 SWAP1
// stack: i + 1, loc + 1, next_val,... // stack: i + 1, loc + 1, next_val,...
%endrep %endrep
%blake_internal_state_addr
%add_const(15)
%rep 16
// stack: addr, ...
DUP1
// stack: addr, addr, ...
%mload_kernel_general
// stack: val, addr, ...
SWAP1
// stack: addr, val, ...
%decrement
%endrep
POP
STOP
// stack: 8, loc + 16, retdest // stack: 8, loc + 16, retdest
POP POP
POP POP
@ -227,13 +290,21 @@ compression_loop:
POP POP
// stack: retdest // stack: retdest
%blake_generate_new_hash_value(7) %blake_generate_new_hash_value(7)
%invert_bytes_blake_word
%blake_generate_new_hash_value(6) %blake_generate_new_hash_value(6)
%invert_bytes_blake_word
%blake_generate_new_hash_value(5) %blake_generate_new_hash_value(5)
%invert_bytes_blake_word
%blake_generate_new_hash_value(4) %blake_generate_new_hash_value(4)
%invert_bytes_blake_word
%blake_generate_new_hash_value(3) %blake_generate_new_hash_value(3)
%invert_bytes_blake_word
%blake_generate_new_hash_value(2) %blake_generate_new_hash_value(2)
%invert_bytes_blake_word
%blake_generate_new_hash_value(1) %blake_generate_new_hash_value(1)
%invert_bytes_blake_word
%blake_generate_new_hash_value(0) %blake_generate_new_hash_value(0)
%invert_bytes_blake_word
// stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', retdest // stack: h_0', h_1', h_2', h_3', h_4', h_5', h_6', h_7', retdest
%shl_const(64) %shl_const(64)
OR OR
@ -250,7 +321,7 @@ compression_loop:
OR OR
%shl_const(64) %shl_const(64)
OR OR
// stack: hash_first = h_4' || h_5' || h_6' || h_7', hash_second = h_0' || h_1' || h_2' || h_3', retdest // stack: hash_second = h_4' || h_5' || h_6' || h_7', hash_first = h_0' || h_1' || h_2' || h_3', retdest
SWAP2 %stack (second, first, ret) -> (ret, second, first)
// stack: retdest, hash_first, hash_second // stack: retdest, hash_first, hash_second
JUMP JUMP

View File

@ -39,7 +39,7 @@
XOR XOR
%rotr_64(32) %rotr_64(32)
// stack: v[d]' = (v[d] ^ v[a]') >>> 32, v[a]', v[b], v[c], v[d], a, b, c, d, x, y, start // stack: v[d]' = (v[d] ^ v[a]') >>> 32, v[a]', v[b], v[c], v[d], a, b, c, d, x, y, start
%stack (top: 3, vd) -> (top) %stack (top: 4, vd) -> (top)
// stack: v[d]', v[a]', v[b], v[c], a, b, c, d, x, y, start // stack: v[d]', v[a]', v[b], v[c], a, b, c, d, x, y, start
%stack (d, a, b, c) -> (c, d, a, b, d) %stack (d, a, b, c) -> (c, d, a, b, d)
// stack: v[c], v[d]', v[a]', v[b], v[d]', a, b, c, d, x, y, start // stack: v[c], v[d]', v[a]', v[b], v[d]', a, b, c, d, x, y, start

View File

@ -1,3 +1,21 @@
global permutation_0_constants:
BYTES 0
BYTES 1
BYTES 2
BYTES 3
BYTES 4
BYTES 5
BYTES 6
BYTES 7
BYTES 8
BYTES 9
BYTES 10
BYTES 11
BYTES 12
BYTES 13
BYTES 14
BYTES 15
global permutation_1_constants: global permutation_1_constants:
BYTES 14 BYTES 14
BYTES 10 BYTES 10
@ -162,13 +180,15 @@ global permutation_9_constants:
%macro blake_permutation %macro blake_permutation
// stack: round, i // stack: round, i
PUSH permutation_1_constants PUSH permutation_0_constants
// stack: permutation_1_constants, round, i // stack: permutation_0_constants, round, i
SWAP1 SWAP1
// stack: round, permutation_1_constants, i // stack: round, permutation_1_constants, i
%mod_const(10) %mod_const(10)
// stack: round % 10, permutation_1_constants, i
%mul_const(16) %mul_const(16)
ADD ADD
// stack: permutation_(round)_constants, i
ADD ADD
%mload_kernel_code %mload_kernel_code
%endmacro %endmacro

View File

@ -12,8 +12,14 @@ global blake_store:
// stack: addr=0, num_blocks, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest // stack: addr=0, num_blocks, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest
%mstore_kernel_general %mstore_kernel_general
// stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest // stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest
DUP1
// stack: num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest
PUSH 1 PUSH 1
// stack: addr=1, counter=num_bytes, x[0], x[1], x[2], ... , x[num_bytes-1], retdest // stack: 1, num_bytes, num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest
%mstore_kernel_general
// stack: num_bytes, x[0], x[1], ..., x[num_bytes - 1], retdest
PUSH 2
// stack: addr=2, counter=num_bytes, x[0], x[1], x[2], ... , x[num_bytes-1], retdest
store_loop: store_loop:
// stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest // stack: addr, counter, x[num_bytes-counter], ... , x[num_bytes-1], retdest
DUP2 DUP2

View File

@ -2,14 +2,15 @@
%macro mload_blake_word %macro mload_blake_word
// stack: offset // stack: offset
DUP1 DUP1
%mload_kernel_general_u32 %mload_kernel_general_u32_LE
// stack: hi, offset // stack: lo, offset
%shl_const(32)
// stack: hi << 32, offset
SWAP1 SWAP1
// stack: offset, hi << 32 // stack: offset, lo
%add_const(4) %add_const(4)
%mload_kernel_general_u32 %mload_kernel_general_u32
// stack: hi, lo
%shl_const(32)
// stack: hi << 32, lo
OR OR
// stack: (hi << 32) | lo // stack: (hi << 32) | lo
%endmacro %endmacro

View File

@ -41,7 +41,9 @@ fn make_random_input() -> Vec<u8> {
fn make_custom_input() -> Vec<u8> { fn make_custom_input() -> Vec<u8> {
// Hardcode a custom message // Hardcode a custom message
vec![ vec![
1, 2, 3 86, 124, 206, 245, 74, 57, 250, 43, 60, 30, 254, 43, 143, 144, 242, 215, 13, 103, 237, 61,
90, 105, 123, 250, 189, 181, 110, 192, 227, 57, 145, 46, 221, 238, 7, 181, 146, 111, 209,
150, 31, 157, 229, 126, 206, 105, 37, 17,
] ]
} }
@ -54,62 +56,89 @@ fn make_input_stack(message: Vec<u8>) -> Vec<U256> {
initial_stack initial_stack
} }
fn test_hash(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec<u8>) -> U512) -> Result<()> { fn test_hash_256(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec<u8>) -> U256) -> Result<()> {
// Make the input. // Make the input.
// let message_random = make_random_input(); let message_random = make_random_input();
let message_custom = make_custom_input(); let message_custom = make_custom_input();
// dbg!(message_random.clone());
// Hash the message using a standard implementation. // Hash the message using a standard implementation.
// // let expected_random = standard_implementation(message_random.clone()); let expected_random = standard_implementation(message_random.clone());
let expected_custom = standard_implementation(message_custom.clone()); let expected_custom = standard_implementation(message_custom.clone());
dbg!(expected_custom);
// Load the message onto the stack. // Load the message onto the stack.
// // let initial_stack_random = make_input_stack(message_random); let initial_stack_random = make_input_stack(message_random);
let initial_stack_custom = make_input_stack(message_custom); let initial_stack_custom = make_input_stack(message_custom);
// dbg!(initial_stack_random.clone());
// Make the kernel. // Make the kernel.
let kernel_function = KERNEL.global_labels[hash_fn_label]; let kernel_function = KERNEL.global_labels[hash_fn_label];
// Run the kernel code. // Run the kernel code.
// // let result_random = run_interpreter(kernel_function, initial_stack_random)?; let result_random = run_interpreter(kernel_function, initial_stack_random)?;
let result_custom = run_interpreter(kernel_function, initial_stack_custom)?; let result_custom = run_interpreter(kernel_function, initial_stack_custom)?;
dbg!(result_custom.stack());
// Extract the final output. // Extract the final output.
// let actual_random = result_random.stack()[0]; let actual_random = result_random.stack()[0];
let actual_custom_first = result_custom.stack()[0]; let actual_custom = result_custom.stack()[0];
let actual_custom_second = result_custom.stack()[1];
let mut actual_custom = U512::from(actual_custom_first);
actual_custom *= U512::from_big_endian(&[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
actual_custom += U512::from(actual_custom_second);
dbg!(actual_custom);
// Check that the result is correct. // Check that the result is correct.
// assert_eq!(expected_random, actual_random); assert_eq!(expected_random, actual_random);
// assert_eq!(expected_custom, actual_custom); assert_eq!(expected_custom, actual_custom);
Ok(()) Ok(())
} }
// #[test] fn combine_u256s(hi: U256, lo: U256) -> U512 {
// fn test_sha2() -> Result<()> { let mut result = U512::from(hi);
// test_hash("sha2", &sha2) result *= U512::from_big_endian(&[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]);
// } result += U512::from(lo);
result
}
// #[test] fn test_hash_512(hash_fn_label: &str, standard_implementation: &dyn Fn(Vec<u8>) -> U512) -> Result<()> {
// fn test_ripemd() -> Result<()> { // Make the input.
// test_hash("ripemd_stack", &ripemd) let message_random = make_random_input();
// } let message_custom = make_custom_input();
// Hash the message using a standard implementation.
let expected_random = standard_implementation(message_random.clone());
let expected_custom = standard_implementation(message_custom.clone());
// Load the message onto the stack.
let initial_stack_random = make_input_stack(message_random);
let initial_stack_custom = make_input_stack(message_custom);
// Make the kernel.
let kernel_function = KERNEL.global_labels[hash_fn_label];
// Run the kernel code.
let result_random = run_interpreter(kernel_function, initial_stack_random)?;
let result_custom = run_interpreter(kernel_function, initial_stack_custom)?;
let random_stack = result_random.stack();
let custom_stack = result_custom.stack();
// Extract the final output.
let actual_random = combine_u256s(random_stack[0], random_stack[1]);
let actual_custom = combine_u256s(custom_stack[0], custom_stack[1]);
// Check that the result is correct.
// assert_eq!(expected_random, actual_random);
assert_eq!(expected_custom, actual_custom);
Ok(())
}
#[test]
fn test_sha2() -> Result<()> {
test_hash_256("sha2", &sha2)
}
#[test]
fn test_ripemd() -> Result<()> {
test_hash_256("ripemd_stack", &ripemd)
}
#[test] #[test]
fn test_blake() -> Result<()> { fn test_blake() -> Result<()> {
test_hash("blake", &blake2b) test_hash_512("blake", &blake2b)
} }