From ac281b4b504399838cd7d7ff2b2f855c20349ae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Thu, 27 Apr 2023 16:57:21 -0300 Subject: [PATCH 1/5] Add NewHint#34 Co-authored-by: Mario Rugiero --- cairo_programs/packed_sha256_test.cairo | 43 ++ cairo_programs/sha256.cairo | 408 +++++++++++++- cairo_programs/sha256_test.cairo | 512 ++++++++++++++++++ .../builtin_hint_processor_definition.rs | 18 +- .../builtin_hint_processor/hint_code.rs | 14 +- .../builtin_hint_processor/hint_utils.rs | 11 + .../builtin_hint_processor/sha256_utils.rs | 303 ++++++++++- .../builtin_hint_processor/uint384.rs | 10 +- src/tests/cairo_run_test.rs | 11 +- src/vm/errors/hint_errors.rs | 2 + 10 files changed, 1282 insertions(+), 50 deletions(-) create mode 100644 cairo_programs/packed_sha256_test.cairo create mode 100644 cairo_programs/sha256_test.cairo diff --git a/cairo_programs/packed_sha256_test.cairo b/cairo_programs/packed_sha256_test.cairo new file mode 100644 index 0000000000..b6316e4829 --- /dev/null +++ b/cairo_programs/packed_sha256_test.cairo @@ -0,0 +1,43 @@ +%builtins range_check bitwise +from starkware.cairo.common.alloc import alloc +from cairo_programs.packed_sha256 import ( + BLOCK_SIZE, + compute_message_schedule, + sha2_compress, + get_round_constants, + sha256, + finalize_sha256, +) +from starkware.cairo.common.cairo_builtins import BitwiseBuiltin + +func test_packed_sha256{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { + alloc_locals; + let input_len = 3; + let input: felt* = alloc(); + assert input[0] = 1214606444; + assert input[1] = 1864398703; + assert input[2] = 1919706112; + let n_bytes = 11; + + let (local sha256_ptr_start: felt*) = alloc(); + let sha256_ptr = sha256_ptr_start; + + let (local output: felt*) = sha256{sha256_ptr=sha256_ptr}(input, n_bytes); + assert output[0] = 1693223114; + assert output[1] = 11692261; + assert output[2] = 3122279783; + assert output[3] = 2317046550; + assert output[4] = 3524457715; + assert output[5] = 1722959730; + assert output[6] = 844319370; + assert output[7] = 3970137916; + + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + return (); +} + +func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { + test_packed_sha256(); + return (); +} diff --git a/cairo_programs/sha256.cairo b/cairo_programs/sha256.cairo index 4ead9ba4c7..9a46d494a3 100644 --- a/cairo_programs/sha256.cairo +++ b/cairo_programs/sha256.cairo @@ -1,38 +1,394 @@ -%builtins range_check bitwise from starkware.cairo.common.alloc import alloc +from starkware.cairo.common.registers import get_fp_and_pc +from starkware.cairo.common.cairo_builtins import BitwiseBuiltin +from starkware.cairo.common.math import assert_nn_le, unsigned_div_rem +from starkware.cairo.common.math_cmp import is_le_felt +from starkware.cairo.common.memcpy import memcpy +from starkware.cairo.common.memset import memset +from starkware.cairo.common.pow import pow + from cairo_programs.packed_sha256 import ( BLOCK_SIZE, compute_message_schedule, sha2_compress, get_round_constants, - sha256, - finalize_sha256, ) -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { +// Source: https://github.com/cartridge-gg/cairo-sha256/blob/8d2ae515ab5cc9fc530c2dcf3ed1172bd181136e/src/sha256.cairo +const SHA256_INPUT_CHUNK_SIZE_FELTS = 16; +const SHA256_INPUT_CHUNK_SIZE_BYTES = 64; +const SHA256_STATE_SIZE_FELTS = 8; +// Each instance consists of 16 words of message, 8 words for the input state and 8 words +// for the output state. +const SHA256_INSTANCE_SIZE = SHA256_INPUT_CHUNK_SIZE_FELTS + 2 * SHA256_STATE_SIZE_FELTS; + +// Computes SHA256 of 'input'. Inputs of arbitrary length are supported. +// To use this function, split the input into (up to) 14 words of 32 bits (big endian). +// For example, to compute sha256('Hello world'), use: +// input = [1214606444, 1864398703, 1919706112] +// where: +// 1214606444 == int.from_bytes(b'Hell', 'big') +// 1864398703 == int.from_bytes(b'o wo', 'big') +// 1919706112 == int.from_bytes(b'rld\x00', 'big') # Note the '\x00' padding. +// +// block layout: +// 0 - 15: Message +// 16 - 23: Input State +// 24 - 32: Output +// +// output is an array of 8 32-bit words (big endian). +// +// Note: You must call finalize_sha2() at the end of the program. Otherwise, this function +// is not sound and a malicious prover may return a wrong result. +// Note: the interface of this function may change in the future. +func sha256{range_check_ptr, sha256_ptr: felt*}(data: felt*, n_bytes: felt) -> (output: felt*) { + alloc_locals; + + // Set the initial input state to IV. + assert sha256_ptr[16] = 0x6A09E667; + assert sha256_ptr[17] = 0xBB67AE85; + assert sha256_ptr[18] = 0x3C6EF372; + assert sha256_ptr[19] = 0xA54FF53A; + assert sha256_ptr[20] = 0x510E527F; + assert sha256_ptr[21] = 0x9B05688C; + assert sha256_ptr[22] = 0x1F83D9AB; + assert sha256_ptr[23] = 0x5BE0CD19; + + sha256_inner(data=data, n_bytes=n_bytes, total_bytes=n_bytes); + + // Set `output` to the start of the final state. + let output = sha256_ptr; + // Set `sha256_ptr` to the end of the output state. + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + return (output,); +} + +// Computes the sha256 hash of the input chunk from `message` to `message + SHA256_INPUT_CHUNK_SIZE_FELTS` +func _sha256_chunk{range_check_ptr, sha256_start: felt*, state: felt*, output: felt*}() { + %{ + from starkware.cairo.common.cairo_sha256.sha256_utils import ( + compute_message_schedule, sha2_compress_function) + + _sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) + assert 0 <= _sha256_input_chunk_size_felts < 100 + _sha256_state_size_felts = int(ids.SHA256_STATE_SIZE_FELTS) + assert 0 <= _sha256_state_size_felts < 100 + w = compute_message_schedule(memory.get_range( + ids.sha256_start, _sha256_input_chunk_size_felts)) + new_state = sha2_compress_function(memory.get_range(ids.state, _sha256_state_size_felts), w) + segments.write_arg(ids.output, new_state) + %} + return (); +} + +// Inner loop for sha256. `sha256_ptr` points to the start of the block. +func sha256_inner{range_check_ptr, sha256_ptr: felt*}( + data: felt*, n_bytes: felt, total_bytes: felt +) { + alloc_locals; + + let message = sha256_ptr; + let state = sha256_ptr + SHA256_INPUT_CHUNK_SIZE_FELTS; + let output = state + SHA256_STATE_SIZE_FELTS; + + let zero_bytes = is_le_felt(n_bytes, 0); + let zero_total_bytes = is_le_felt(total_bytes, 0); + + // If the previous message block was full we are still missing "1" at the end of the message + let (_, r_div_by_64) = unsigned_div_rem(total_bytes, 64); + let missing_bit_one = is_le_felt(r_div_by_64, 0); + + // This works for 0 total bytes too, because zero_chunk will be -1 and, therefore, not 0. + let zero_chunk = zero_bytes - zero_total_bytes - missing_bit_one; + + let is_last_block = is_le_felt(n_bytes, 55); + if (is_last_block == 1) { + _sha256_input(data, n_bytes, SHA256_INPUT_CHUNK_SIZE_FELTS - 2, zero_chunk); + // Append the original message length at the end of the message block as a 64-bit big-endian integer. + assert sha256_ptr[0] = 0; + assert sha256_ptr[1] = total_bytes * 8; + let sha256_ptr = sha256_ptr + 2; + _sha256_chunk{sha256_start=message, state=state, output=output}(); + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + + return (); + } + + let (q, r) = unsigned_div_rem(n_bytes, SHA256_INPUT_CHUNK_SIZE_BYTES); + let is_remainder_block = is_le_felt(q, 0); + if (is_remainder_block == 1) { + _sha256_input(data, r, SHA256_INPUT_CHUNK_SIZE_FELTS, 0); + _sha256_chunk{sha256_start=message, state=state, output=output}(); + + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + memcpy( + output + SHA256_STATE_SIZE_FELTS + SHA256_INPUT_CHUNK_SIZE_FELTS, + output, + SHA256_STATE_SIZE_FELTS, + ); + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + + return sha256_inner(data=data, n_bytes=n_bytes - r, total_bytes=total_bytes); + } else { + _sha256_input(data, SHA256_INPUT_CHUNK_SIZE_BYTES, SHA256_INPUT_CHUNK_SIZE_FELTS, 0); + _sha256_chunk{sha256_start=message, state=state, output=output}(); + + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + memcpy( + output + SHA256_STATE_SIZE_FELTS + SHA256_INPUT_CHUNK_SIZE_FELTS, + output, + SHA256_STATE_SIZE_FELTS, + ); + let sha256_ptr = sha256_ptr + SHA256_STATE_SIZE_FELTS; + + return sha256_inner( + data=data + SHA256_INPUT_CHUNK_SIZE_FELTS, + n_bytes=n_bytes - SHA256_INPUT_CHUNK_SIZE_BYTES, + total_bytes=total_bytes, + ); + } +} + +// 1. Encode the input to binary using UTF-8 and append a single '1' to it. +// 2. Prepend that binary to the message block. +func _sha256_input{range_check_ptr, sha256_ptr: felt*}( + input: felt*, n_bytes: felt, n_words: felt, pad_chunk: felt +) { + alloc_locals; + + local full_word; + %{ ids.full_word = int(ids.n_bytes >= 4) %} + + if (full_word != 0) { + assert sha256_ptr[0] = input[0]; + let sha256_ptr = sha256_ptr + 1; + return _sha256_input( + input=input + 1, n_bytes=n_bytes - 4, n_words=n_words - 1, pad_chunk=pad_chunk + ); + } + + if (n_words == 0) { + return (); + } + + if (n_bytes == 0 and pad_chunk == 1) { + // Add zeros between the encoded message and the length integer so that the message block is a multiple of 512. + memset(dst=sha256_ptr, value=0, n=n_words); + let sha256_ptr = sha256_ptr + n_words; + return (); + } + + if (n_bytes == 0) { + // This is the last input word, so we should add a byte '0x80' at the end and fill the rest with zeros. + assert sha256_ptr[0] = 0x80000000; + // Add zeros between the encoded message and the length integer so that the message block is a multiple of 512. + memset(dst=sha256_ptr + 1, value=0, n=n_words - 1); + let sha256_ptr = sha256_ptr + n_words; + return (); + } + + assert_nn_le(n_bytes, 3); + let (padding) = pow(256, 3 - n_bytes); + local range_check_ptr = range_check_ptr; + + assert sha256_ptr[0] = input[0] + padding * 0x80; + + memset(dst=sha256_ptr + 1, value=0, n=n_words - 1); + let sha256_ptr = sha256_ptr + n_words; + return (); +} + +// Handles n blocks of BLOCK_SIZE SHA256 instances. +// Taken from: https://github.com/starkware-libs/cairo-examples/blob/0d88b41bffe3de112d98986b8b0afa795f9d67a0/sha256/sha256.cairo#L102 +func _finalize_sha256_inner{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( + sha256_ptr: felt*, n: felt, round_constants: felt* +) { + if (n == 0) { + return (); + } + + alloc_locals; + + local MAX_VALUE = 2 ** 32 - 1; + + let sha256_start = sha256_ptr; + + let (local message_start: felt*) = alloc(); + let (local input_state_start: felt*) = alloc(); + + // Handle message. + + tempvar message = message_start; + tempvar sha256_ptr = sha256_ptr; + tempvar range_check_ptr = range_check_ptr; + tempvar m = SHA256_INPUT_CHUNK_SIZE_FELTS; + + message_loop: + tempvar x0 = sha256_ptr[0 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 0] = x0; + assert [range_check_ptr + 1] = MAX_VALUE - x0; + tempvar x1 = sha256_ptr[1 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 2] = x1; + assert [range_check_ptr + 3] = MAX_VALUE - x1; + tempvar x2 = sha256_ptr[2 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 4] = x2; + assert [range_check_ptr + 5] = MAX_VALUE - x2; + tempvar x3 = sha256_ptr[3 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 6] = x3; + assert [range_check_ptr + 7] = MAX_VALUE - x3; + tempvar x4 = sha256_ptr[4 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 8] = x4; + assert [range_check_ptr + 9] = MAX_VALUE - x4; + tempvar x5 = sha256_ptr[5 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 10] = x5; + assert [range_check_ptr + 11] = MAX_VALUE - x5; + tempvar x6 = sha256_ptr[6 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 12] = x6; + assert [range_check_ptr + 13] = MAX_VALUE - x6; + assert message[0] = x0 + 2 ** 35 * x1 + 2 ** (35 * 2) * x2 + 2 ** (35 * 3) * x3 + 2 ** ( + 35 * 4 + ) * x4 + 2 ** (35 * 5) * x5 + 2 ** (35 * 6) * x6; + + tempvar message = message + 1; + tempvar sha256_ptr = sha256_ptr + 1; + tempvar range_check_ptr = range_check_ptr + 14; + tempvar m = m - 1; + jmp message_loop if m != 0; + + // Handle input state. + + tempvar input_state = input_state_start; + tempvar sha256_ptr = sha256_ptr; + tempvar range_check_ptr = range_check_ptr; + tempvar m = SHA256_STATE_SIZE_FELTS; + + input_state_loop: + tempvar x0 = sha256_ptr[0 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 0] = x0; + assert [range_check_ptr + 1] = MAX_VALUE - x0; + tempvar x1 = sha256_ptr[1 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 2] = x1; + assert [range_check_ptr + 3] = MAX_VALUE - x1; + tempvar x2 = sha256_ptr[2 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 4] = x2; + assert [range_check_ptr + 5] = MAX_VALUE - x2; + tempvar x3 = sha256_ptr[3 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 6] = x3; + assert [range_check_ptr + 7] = MAX_VALUE - x3; + tempvar x4 = sha256_ptr[4 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 8] = x4; + assert [range_check_ptr + 9] = MAX_VALUE - x4; + tempvar x5 = sha256_ptr[5 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 10] = x5; + assert [range_check_ptr + 11] = MAX_VALUE - x5; + tempvar x6 = sha256_ptr[6 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 12] = x6; + assert [range_check_ptr + 13] = MAX_VALUE - x6; + assert input_state[0] = x0 + 2 ** 35 * x1 + 2 ** (35 * 2) * x2 + 2 ** (35 * 3) * x3 + 2 ** ( + 35 * 4 + ) * x4 + 2 ** (35 * 5) * x5 + 2 ** (35 * 6) * x6; + + tempvar input_state = input_state + 1; + tempvar sha256_ptr = sha256_ptr + 1; + tempvar range_check_ptr = range_check_ptr + 14; + tempvar m = m - 1; + jmp input_state_loop if m != 0; + + // Run sha256 on the 7 instances. + + local sha256_ptr: felt* = sha256_ptr; + local range_check_ptr = range_check_ptr; + compute_message_schedule(message_start); + let (outputs) = sha2_compress(input_state_start, message_start, round_constants); + local bitwise_ptr: BitwiseBuiltin* = bitwise_ptr; + + // Handle outputs. + + tempvar outputs = outputs; + tempvar sha256_ptr = sha256_ptr; + tempvar range_check_ptr = range_check_ptr; + tempvar m = SHA256_STATE_SIZE_FELTS; + + output_loop: + tempvar x0 = sha256_ptr[0 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr] = x0; + assert [range_check_ptr + 1] = MAX_VALUE - x0; + tempvar x1 = sha256_ptr[1 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 2] = x1; + assert [range_check_ptr + 3] = MAX_VALUE - x1; + tempvar x2 = sha256_ptr[2 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 4] = x2; + assert [range_check_ptr + 5] = MAX_VALUE - x2; + tempvar x3 = sha256_ptr[3 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 6] = x3; + assert [range_check_ptr + 7] = MAX_VALUE - x3; + tempvar x4 = sha256_ptr[4 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 8] = x4; + assert [range_check_ptr + 9] = MAX_VALUE - x4; + tempvar x5 = sha256_ptr[5 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 10] = x5; + assert [range_check_ptr + 11] = MAX_VALUE - x5; + tempvar x6 = sha256_ptr[6 * SHA256_INSTANCE_SIZE]; + assert [range_check_ptr + 12] = x6; + assert [range_check_ptr + 13] = MAX_VALUE - x6; + + assert outputs[0] = x0 + 2 ** 35 * x1 + 2 ** (35 * 2) * x2 + 2 ** (35 * 3) * x3 + 2 ** ( + 35 * 4 + ) * x4 + 2 ** (35 * 5) * x5 + 2 ** (35 * 6) * x6; + + tempvar outputs = outputs + 1; + tempvar sha256_ptr = sha256_ptr + 1; + tempvar range_check_ptr = range_check_ptr + 14; + tempvar m = m - 1; + jmp output_loop if m != 0; + + return _finalize_sha256_inner( + sha256_ptr=sha256_start + SHA256_INSTANCE_SIZE * BLOCK_SIZE, + n=n - 1, + round_constants=round_constants, + ); +} + +// Verifies that the results of sha256() are valid. +// Taken from: https://github.com/starkware-libs/cairo-examples/blob/0d88b41bffe3de112d98986b8b0afa795f9d67a0/sha256/sha256.cairo#L246 +func finalize_sha256{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( + sha256_ptr_start: felt*, sha256_ptr_end: felt* +) { alloc_locals; - let input_len = 3; - let input: felt* = alloc(); - assert input[0] = 1214606444; - assert input[1] = 1864398703; - assert input[2] = 1919706112; - let n_bytes = 11; - - let (local sha256_ptr_start: felt*) = alloc(); - let sha256_ptr = sha256_ptr_start; - - let (local output: felt*) = sha256{sha256_ptr=sha256_ptr}(input, n_bytes); - assert output[0] = 1693223114; - assert output[1] = 11692261; - assert output[2] = 3122279783; - assert output[3] = 2317046550; - assert output[4] = 3524457715; - assert output[5] = 1722959730; - assert output[6] = 844319370; - assert output[7] = 3970137916; - - finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + let (__fp__, _) = get_fp_and_pc(); + + let (round_constants) = get_round_constants(); + + // We reuse the output state of the previous chunk as input to the next. + tempvar n = (sha256_ptr_end - sha256_ptr_start) / SHA256_INSTANCE_SIZE; + if (n == 0) { + return (); + } + + %{ + # Add dummy pairs of input and output. + from starkware.cairo.common.cairo_sha256.sha256_utils import ( + IV, compute_message_schedule, sha2_compress_function) + + _block_size = int(ids.BLOCK_SIZE) + assert 0 <= _block_size < 20 + _sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) + assert 0 <= _sha256_input_chunk_size_felts < 100 + + message = [0] * _sha256_input_chunk_size_felts + w = compute_message_schedule(message) + output = sha2_compress_function(IV, w) + padding = (message + IV + output) * (_block_size - 1) + segments.write_arg(ids.sha256_ptr_end, padding) + %} + + // Compute the amount of blocks (rounded up). + let (local q, r) = unsigned_div_rem(n + BLOCK_SIZE - 1, BLOCK_SIZE); + _finalize_sha256_inner(sha256_ptr_start, n=q, round_constants=round_constants); + return (); +} + +func main() { return (); } diff --git a/cairo_programs/sha256_test.cairo b/cairo_programs/sha256_test.cairo new file mode 100644 index 0000000000..2e53cb0cd4 --- /dev/null +++ b/cairo_programs/sha256_test.cairo @@ -0,0 +1,512 @@ +%builtins range_check bitwise + +from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin +from starkware.cairo.common.registers import get_label_location +from starkware.cairo.common.invoke import invoke +from starkware.cairo.common.alloc import alloc + +from cairo_programs.sha256 import sha256, finalize_sha256 + +// Taken from https://github.com/cartridge-gg/cairo-sha256/blob/8d2ae515ab5cc9fc530c2dcf3ed1172bd181136e/tests/test_sha256.cairo +func test_sha256_hello_world{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (hello_world) = alloc(); + assert hello_world[0] = 'hell'; + assert hello_world[1] = 'o wo'; + assert hello_world[2] = 'rld\x00'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(hello_world, 11); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 3108841401; + let b = hash[1]; + assert b = 2471312904; + let c = hash[2]; + assert c = 2771276503; + let d = hash[3]; + assert d = 3665669114; + let e = hash[4]; + assert e = 3297046499; + let f = hash[5]; + assert f = 2052292846; + let g = hash[6]; + assert g = 2424895404; + let h = hash[7]; + assert h = 3807366633; + + return (); +} + +func test_sha256_multichunks{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (phrase) = alloc(); + // phrase="this is an example message which should take multiple chunks" + // 01110100 01101000 01101001 01110011 + assert phrase[0] = 1952999795; + // 00100000 01101001 01110011 00100000 + assert phrase[1] = 543781664; + // 01100001 01101110 00100000 01100101 + assert phrase[2] = 1634607205; + // 01111000 01100001 01101101 01110000 + assert phrase[3] = 2019650928; + // 01101100 01100101 00100000 01101101 + assert phrase[4] = 1818566765; + // 01100101 01110011 01110011 01100001 + assert phrase[5] = 1702064993; + // 01100111 01100101 00100000 01110111 + assert phrase[6] = 1734680695; + // 01101000 01101001 01100011 01101000 + assert phrase[7] = 1751737192; + // 00100000 01110011 01101000 01101111 + assert phrase[8] = 544434287; + // 01110101 01101100 01100100 00100000 + assert phrase[9] = 1970037792; + // 01110100 01100001 01101011 01100101 + assert phrase[10] = 1952541541; + // 00100000 01101101 01110101 01101100 + assert phrase[11] = 544044396; + // 01110100 01101001 01110000 01101100 + assert phrase[12] = 1953067116; + // 01100101 00100000 01100011 01101000 + assert phrase[13] = 1696621416; + // 01110101 01101110 01101011 01110011 + assert phrase[14] = 1970170739; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(phrase, 60); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 3714276112; + let b = hash[1]; + assert b = 759782134; + let c = hash[2]; + assert c = 1331117438; + let d = hash[3]; + assert c = 1331117438; + let e = hash[4]; + assert e = 699003633; + let f = hash[5]; + assert f = 2214481798; + let g = hash[6]; + assert g = 3208491254; + let h = hash[7]; + assert h = 789740750; + + return (); +} + +// test vectors from: https://www.di-mgt.com.au/sha_testvectors.html + +func test_sha256_0bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (empty) = alloc(); + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(empty, 0); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 0xe3b0c442; + let b = hash[1]; + assert b = 0x98fc1c14; + let c = hash[2]; + assert c = 0x9afbf4c8; + let d = hash[3]; + assert d = 0x996fb924; + let e = hash[4]; + assert e = 0x27ae41e4; + let f = hash[5]; + assert f = 0x649b934c; + let g = hash[6]; + assert g = 0xa495991b; + let h = hash[7]; + assert h = 0x7852b855; + + return (); +} + +func test_sha256_24bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(new ('abc\x00'), 3); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 0xba7816bf; + let b = hash[1]; + assert b = 0x8f01cfea; + let c = hash[2]; + assert c = 0x414140de; + let d = hash[3]; + assert d = 0x5dae2223; + let e = hash[4]; + assert e = 0xb00361a3; + let f = hash[5]; + assert f = 0x96177a9c; + let g = hash[6]; + assert g = 0xb410ff61; + let h = hash[7]; + assert h = 0xf20015ad; + + return (); +} + +func test_sha256_448bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (input) = alloc(); + assert input[0] = 'abcd'; + assert input[1] = 'bcde'; + assert input[2] = 'cdef'; + assert input[3] = 'defg'; + assert input[4] = 'efgh'; + assert input[5] = 'fghi'; + assert input[6] = 'ghij'; + assert input[7] = 'hijk'; + assert input[8] = 'ijkl'; + assert input[9] = 'jklm'; + assert input[10] = 'klmn'; + assert input[11] = 'lmno'; + assert input[12] = 'mnop'; + assert input[13] = 'nopq'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 56); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 0x248d6a61; + let b = hash[1]; + assert b = 0xd20638b8; + let c = hash[2]; + assert c = 0xe5c02693; + let d = hash[3]; + assert d = 0x0c3e6039; + let e = hash[4]; + assert e = 0xa33ce459; + let f = hash[5]; + assert f = 0x64ff2167; + let g = hash[6]; + assert g = 0xf6ecedd4; + let h = hash[7]; + assert h = 0x19db06c1; + + return (); +} + +func test_sha256_504bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + // Input String: "0000111122223333444455556666777788889999aaaabbbbccccddddeeeefff" + let (input) = alloc(); + assert input[0] = '0000'; + assert input[1] = '1111'; + assert input[2] = '2222'; + assert input[3] = '3333'; + assert input[4] = '4444'; + assert input[5] = '5555'; + assert input[6] = '6666'; + assert input[7] = '7777'; + assert input[8] = '8888'; + assert input[9] = '9999'; + assert input[10] = 'aaaa'; + assert input[11] = 'bbbb'; + assert input[12] = 'cccc'; + assert input[13] = 'dddd'; + assert input[14] = 'eeee'; + assert input[15] = 'fff\x00'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 63); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + // Resulting hash: 214072bf9da123ca5a8925edb05a6f071fc48fa66494d08513b9ba1b82df20cd + let a = hash[0]; + assert a = 0x214072bf; + let b = hash[1]; + assert b = 0x9da123ca; + let c = hash[2]; + assert c = 0x5a8925ed; + let d = hash[3]; + assert d = 0xb05a6f07; + let e = hash[4]; + assert e = 0x1fc48fa6; + let f = hash[5]; + assert f = 0x6494d085; + let g = hash[6]; + assert g = 0x13b9ba1b; + let h = hash[7]; + assert h = 0x82df20cd; + + return (); +} + +func test_sha256_512bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + // Input String: "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" + let (input) = alloc(); + assert input[0] = '0000'; + assert input[1] = '1111'; + assert input[2] = '2222'; + assert input[3] = '3333'; + assert input[4] = '4444'; + assert input[5] = '5555'; + assert input[6] = '6666'; + assert input[7] = '7777'; + assert input[8] = '8888'; + assert input[9] = '9999'; + assert input[10] = 'aaaa'; + assert input[11] = 'bbbb'; + assert input[12] = 'cccc'; + assert input[13] = 'dddd'; + assert input[14] = 'eeee'; + assert input[15] = 'ffff'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 64); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + // Resulting hash: c7a7d8c0472c7f6234380e9dd3a55eb24d3e5dba9d106b74a260dc787f2f6df8 + let a = hash[0]; + assert a = 0xc7a7d8c0; + let b = hash[1]; + assert b = 0x472c7f62; + let c = hash[2]; + assert c = 0x34380e9d; + let d = hash[3]; + assert d = 0xd3a55eb2; + let e = hash[4]; + assert e = 0x4d3e5dba; + let f = hash[5]; + assert f = 0x9d106b74; + let g = hash[6]; + assert g = 0xa260dc78; + let h = hash[7]; + assert h = 0x7f2f6df8; + + return (); +} + +func test_sha256_1024bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + // Input String: "0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff" + let (input) = alloc(); + assert input[0] = '0000'; + assert input[1] = '1111'; + assert input[2] = '2222'; + assert input[3] = '3333'; + assert input[4] = '4444'; + assert input[5] = '5555'; + assert input[6] = '6666'; + assert input[7] = '7777'; + assert input[8] = '8888'; + assert input[9] = '9999'; + assert input[10] = 'aaaa'; + assert input[11] = 'bbbb'; + assert input[12] = 'cccc'; + assert input[13] = 'dddd'; + assert input[14] = 'eeee'; + assert input[15] = 'ffff'; + assert input[16] = '0000'; + assert input[17] = '1111'; + assert input[18] = '2222'; + assert input[19] = '3333'; + assert input[20] = '4444'; + assert input[21] = '5555'; + assert input[22] = '6666'; + assert input[23] = '7777'; + assert input[24] = '8888'; + assert input[25] = '9999'; + assert input[26] = 'aaaa'; + assert input[27] = 'bbbb'; + assert input[28] = 'cccc'; + assert input[29] = 'dddd'; + assert input[30] = 'eeee'; + assert input[31] = 'ffff'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 128); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + // Resulting hash: e324cc62be4f0465591b5cac1309ab4d5a9ee4ae8e99158c50cef7597898f046 + let a = hash[0]; + assert a = 0xe324cc62; + let b = hash[1]; + assert b = 0xbe4f0465; + let c = hash[2]; + assert c = 0x591b5cac; + let d = hash[3]; + assert d = 0x1309ab4d; + let e = hash[4]; + assert e = 0x5a9ee4ae; + let f = hash[5]; + assert f = 0x8e99158c; + let g = hash[6]; + assert g = 0x50cef759; + let h = hash[7]; + assert h = 0x7898f046; + + return (); +} + +func test_sha256_896bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (input) = alloc(); + assert input[0] = 'abcd'; + assert input[1] = 'efgh'; + assert input[2] = 'bcde'; + assert input[3] = 'fghi'; + assert input[4] = 'cdef'; + assert input[5] = 'ghij'; + assert input[6] = 'defg'; + assert input[7] = 'hijk'; + assert input[8] = 'efgh'; + assert input[9] = 'ijkl'; + assert input[10] = 'fghi'; + assert input[11] = 'jklm'; + assert input[12] = 'ghij'; + assert input[13] = 'klmn'; + assert input[14] = 'hijk'; + assert input[15] = 'lmno'; + assert input[16] = 'ijkl'; + assert input[17] = 'mnop'; + assert input[18] = 'jklm'; + assert input[19] = 'nopq'; + assert input[20] = 'klmn'; + assert input[21] = 'opqr'; + assert input[22] = 'lmno'; + assert input[23] = 'pqrs'; + assert input[24] = 'mnop'; + assert input[25] = 'qrst'; + assert input[26] = 'nopq'; + assert input[27] = 'rstu'; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 112); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 0xcf5b16a7; + let b = hash[1]; + assert b = 0x78af8380; + let c = hash[2]; + assert c = 0x036ce59e; + let d = hash[3]; + assert d = 0x7b049237; + let e = hash[4]; + assert e = 0x0b249b11; + let f = hash[5]; + assert f = 0xe8f07a51; + let g = hash[6]; + assert g = 0xafac4503; + let h = hash[7]; + assert h = 0x7afee9d1; + + return (); +} + +func test_sha256_client_data{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { + alloc_locals; + + let (client_data_json) = alloc(); + assert client_data_json[0] = 2065855609; + assert client_data_json[1] = 1885676090; + assert client_data_json[2] = 578250082; + assert client_data_json[3] = 1635087464; + assert client_data_json[4] = 1848534885; + assert client_data_json[5] = 1948396578; + assert client_data_json[6] = 1667785068; + assert client_data_json[7] = 1818586727; + assert client_data_json[8] = 1696741922; + assert client_data_json[9] = 813183028; + assert client_data_json[10] = 879047521; + assert client_data_json[11] = 1684224052; + assert client_data_json[12] = 895825200; + assert client_data_json[13] = 828518449; + assert client_data_json[14] = 1664497968; + assert client_data_json[15] = 878994482; + assert client_data_json[16] = 1647338340; + assert client_data_json[17] = 811872312; + assert client_data_json[18] = 878862896; + assert client_data_json[19] = 825373744; + assert client_data_json[20] = 959854180; + assert client_data_json[21] = 859398963; + assert client_data_json[22] = 825636148; + assert client_data_json[23] = 942761062; + assert client_data_json[24] = 1667327286; + assert client_data_json[25] = 896999980; + assert client_data_json[26] = 577729129; + assert client_data_json[27] = 1734962722; + assert client_data_json[28] = 975333492; + assert client_data_json[29] = 1953526586; + assert client_data_json[30] = 791634799; + assert client_data_json[31] = 1853125231; + assert client_data_json[32] = 1819043186; + assert client_data_json[33] = 761606451; + assert client_data_json[34] = 1886665079; + assert client_data_json[35] = 2004233840; + assert client_data_json[36] = 1919252073; + assert client_data_json[37] = 1702309475; + assert client_data_json[38] = 1634890866; + assert client_data_json[39] = 1768187749; + assert client_data_json[40] = 778528546; + assert client_data_json[41] = 740451186; + assert client_data_json[42] = 1869837135; + assert client_data_json[43] = 1919510377; + assert client_data_json[44] = 1847736934; + assert client_data_json[45] = 1634497381; + assert client_data_json[46] = 2097152000; + + let (local sha256_ptr: felt*) = alloc(); + let sha256_ptr_start = sha256_ptr; + let (hash) = sha256{sha256_ptr=sha256_ptr}(client_data_json, 185); + finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); + + let a = hash[0]; + assert a = 0x08ad1974; + let b = hash[1]; + assert b = 0x216096a7; + let c = hash[2]; + assert c = 0x6ff36a54; + let d = hash[3]; + assert d = 0x159891a3; + let e = hash[4]; + assert e = 0x57d21a90; + let f = hash[5]; + assert f = 0x2c358e6f; + let g = hash[6]; + assert g = 0xeb02f14c; + let h = hash[7]; + assert h = 0xcaf48fcd; + + return (); +} + +func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { + test_sha256_hello_world(); + test_sha256_multichunks(); + test_sha256_0bits(); + test_sha256_24bits(); + test_sha256_448bits(); + test_sha256_504bits(); + test_sha256_512bits(); + test_sha256_1024bits(); + test_sha256_896bits(); + test_sha256_client_data(); + return (); +} diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 4b77a7efdd..4248cd42af 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -68,7 +68,10 @@ use crate::{ }, segments::{relocate_segment, temporary_array}, set::set_add, - sha256_utils::{sha256_finalize, sha256_input, sha256_main}, + sha256_utils::{ + sha256_finalize, sha256_input, sha256_main_arbitrary_input_length, + sha256_main_constant_input_length, + }, signature::verify_ecdsa_signature, squash_dict_utils::{ squash_dict, squash_dict_inner_assert_len_keys, @@ -565,7 +568,18 @@ impl HintProcessor for BuiltinHintProcessor { &hint_data.ap_tracking, constants, ), - hint_code::SHA256_MAIN => sha256_main(vm, &hint_data.ids_data, &hint_data.ap_tracking), + hint_code::SHA256_MAIN_CONSTANT_INPUT_LENGTH => sha256_main_constant_input_length( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + constants, + ), + hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH => sha256_main_arbitrary_input_length( + vm, + &hint_data.ids_data, + &hint_data.ap_tracking, + constants, + ), hint_code::SHA256_INPUT => { sha256_input(vm, &hint_data.ids_data, &hint_data.ap_tracking) } diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs index 07de7c0153..58203626d3 100644 --- a/src/hint_processor/builtin_hint_processor/hint_code.rs +++ b/src/hint_processor/builtin_hint_processor/hint_code.rs @@ -740,7 +740,7 @@ pub const EC_DOUBLE_ASSIGN_NEW_Y: &str = r#"value = new_y = (slope * (x - new_x) pub const SHA256_INPUT: &str = r#"ids.full_word = int(ids.n_bytes >= 4)"#; -pub const SHA256_MAIN: &str = r#"from starkware.cairo.common.cairo_sha256.sha256_utils import ( +pub const SHA256_MAIN_CONSTANT_INPUT_LENGTH: &str = r#"from starkware.cairo.common.cairo_sha256.sha256_utils import ( IV, compute_message_schedule, sha2_compress_function) _sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) @@ -751,6 +751,18 @@ w = compute_message_schedule(memory.get_range( new_state = sha2_compress_function(IV, w) segments.write_arg(ids.output, new_state)"#; +pub const SHA256_MAIN_ARBITRARY_INPUT_LENGTH: &str = r#"from starkware.cairo.common.cairo_sha256.sha256_utils import ( + compute_message_schedule, sha2_compress_function) + +_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) +assert 0 <= _sha256_input_chunk_size_felts < 100 +_sha256_state_size_felts = int(ids.SHA256_STATE_SIZE_FELTS) +assert 0 <= _sha256_state_size_felts < 100 +w = compute_message_schedule(memory.get_range( + ids.sha256_start, _sha256_input_chunk_size_felts)) +new_state = sha2_compress_function(memory.get_range(ids.state, _sha256_state_size_felts), w) +segments.write_arg(ids.output, new_state)"#; + pub const SHA256_FINALIZE: &str = r#"# Add dummy pairs of input and output. from starkware.cairo.common.cairo_sha256.sha256_utils import ( IV, compute_message_schedule, sha2_compress_function) diff --git a/src/hint_processor/builtin_hint_processor/hint_utils.rs b/src/hint_processor/builtin_hint_processor/hint_utils.rs index 073e24efb3..cc34868687 100644 --- a/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -119,6 +119,17 @@ pub fn get_reference_from_var_name<'a>( .ok_or(HintError::UnknownIdentifier(var_name.to_string())) } +pub fn get_constant_from_var_name<'a>( + var_name: &'static str, + constants: &'a HashMap, +) -> Result<&'a Felt252, HintError> { + constants + .iter() + .find(|(k, _)| k.rsplit('.').next() == Some(var_name)) + .map(|(_, n)| n) + .ok_or(HintError::MissingConstant(var_name)) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/src/hint_processor/builtin_hint_processor/sha256_utils.rs index 7e84b1f250..0588f8096f 100644 --- a/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -14,12 +14,13 @@ use crate::{ }; use felt::Felt252; use generic_array::GenericArray; -use num_traits::{One, Zero}; +use num_traits::{One, ToPrimitive, Zero}; use sha2::compress256; use crate::hint_processor::hint_processor_definition::HintReference; -const SHA256_INPUT_CHUNK_SIZE_FELTS: usize = 16; +use super::hint_utils::get_constant_from_var_name; + const SHA256_STATE_SIZE_FELTS: usize = 8; const BLOCK_SIZE: usize = 7; const IV: [u32; SHA256_STATE_SIZE_FELTS] = [ @@ -47,29 +48,42 @@ pub fn sha256_input( ) } -pub fn sha256_main( +/// Inner implementation of [`sha256_main_constant_input_length`] and [`sha256_main_arbitrary_input_length`] +fn sha256_main( vm: &mut VirtualMachine, ids_data: &HashMap, ap_tracking: &ApTracking, + constants: &HashMap, + iv: &mut [u32; 8], ) -> Result<(), HintError> { let input_ptr = get_ptr_from_var_name("sha256_start", vm, ids_data, ap_tracking)?; - let mut message: Vec = Vec::with_capacity(4 * SHA256_INPUT_CHUNK_SIZE_FELTS); + // The original code gets it from `ids` in both cases, and this makes it easier + // to implement the arbitrary length one + let input_chunk_size_felts = + get_constant_from_var_name("SHA256_INPUT_CHUNK_SIZE_FELTS", constants)? + .to_usize() + .unwrap_or(100); // Hack: enough to fail the assertion + + if input_chunk_size_felts >= 100 { + return Err(HintError::AssertionFailed("AssertionError".to_string())); + } + + let mut message: Vec = Vec::with_capacity(4 * input_chunk_size_felts); - for i in 0..SHA256_INPUT_CHUNK_SIZE_FELTS { + for i in 0..input_chunk_size_felts { let input_element = vm.get_integer((input_ptr + i)?)?; let bytes = felt_to_u32(input_element.as_ref())?.to_be_bytes(); message.extend(bytes); } - let mut iv = IV; let new_message = GenericArray::clone_from_slice(&message); - compress256(&mut iv, &[new_message]); + compress256(iv, &[new_message]); - let mut output: Vec = Vec::with_capacity(SHA256_STATE_SIZE_FELTS); + let mut output: Vec = Vec::with_capacity(iv.len()); for new_state in iv { - output.push(Felt252::new(new_state).into()); + output.push(Felt252::new(*new_state).into()); } let output_base = get_ptr_from_var_name("output", vm, ids_data, ap_tracking)?; @@ -79,6 +93,77 @@ pub fn sha256_main( Ok(()) } +/* Implements hint: +from starkware.cairo.common.cairo_sha256.sha256_utils import ( + IV, compute_message_schedule, sha2_compress_function) + +_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) +assert 0 <= _sha256_input_chunk_size_felts < 100 + +w = compute_message_schedule(memory.get_range( + ids.sha256_start, _sha256_input_chunk_size_felts)) +new_state = sha2_compress_function(IV, w) +segments.write_arg(ids.output, new_state) + */ +pub fn sha256_main_constant_input_length( + vm: &mut VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, + constants: &HashMap, +) -> Result<(), HintError> { + let mut iv = IV; + sha256_main(vm, ids_data, ap_tracking, constants, &mut iv) +} + +/* Implements hint: +from starkware.cairo.common.cairo_sha256.sha256_utils import ( + compute_message_schedule, sha2_compress_function) + +_sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) +assert 0 <= _sha256_input_chunk_size_felts < 100 +_sha256_state_size_felts = int(ids.SHA256_STATE_SIZE_FELTS) +assert 0 <= _sha256_state_size_felts < 100 +w = compute_message_schedule(memory.get_range( + ids.sha256_start, _sha256_input_chunk_size_felts)) +new_state = sha2_compress_function(memory.get_range(ids.state, _sha256_state_size_felts), w) +segments.write_arg(ids.output, new_state) + */ +pub fn sha256_main_arbitrary_input_length( + vm: &mut VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, + constants: &HashMap, +) -> Result<(), HintError> { + let iv_ptr = get_ptr_from_var_name("state", vm, ids_data, ap_tracking)?; + + let state_size_felt = get_constant_from_var_name("SHA256_STATE_SIZE_FELTS", constants)?; + + let state_size = match state_size_felt.to_usize() { + Some(size) if size == SHA256_STATE_SIZE_FELTS => size, + // if size is valid, but not SHA256_STATE_SIZE_FELTS, throw error + // NOTE: in this case the python-vm fails with "not enough values to unpack" error + Some(size) if size < 100 => { + return Err(HintError::InvalidValue( + "SHA256_STATE_SIZE_FELTS", + state_size_felt.clone(), + Felt252::from(SHA256_STATE_SIZE_FELTS), + )) + } + // otherwise, fails the assert + _ => return Err(HintError::AssertionFailed("AssertionError".to_string())), + }; + + let mut iv = vm + .get_integer_range(iv_ptr, state_size)? + .into_iter() + .map(|x| felt_to_u32(x.as_ref())) + .collect::, _>>()? + .try_into() + .expect("size is constant"); + + sha256_main(vm, ids_data, ap_tracking, constants, &mut iv) +} + pub fn sha256_finalize( vm: &mut VirtualMachine, ids_data: &HashMap, @@ -120,14 +205,26 @@ mod tests { use super::*; use crate::{ - hint_processor::hint_processor_definition::HintReference, utils::test_utils::*, + any_box, + hint_processor::{ + builtin_hint_processor::{ + builtin_hint_processor_definition::{BuiltinHintProcessor, HintProcessorData}, + hint_code, + }, + hint_processor_definition::{HintProcessor, HintReference}, + }, + types::exec_scope::ExecutionScopes, + utils::test_utils::*, vm::vm_core::VirtualMachine, }; use assert_matches::assert_matches; + use rstest::rstest; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; + const SHA256_INPUT_CHUNK_SIZE_FELTS: usize = 16; + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn sha256_input_one() { @@ -154,7 +251,8 @@ mod tests { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] - fn sha256_ok() { + fn sha256_constant_input_length_ok() { + let hint_code = hint_code::SHA256_MAIN_CONSTANT_INPUT_LENGTH; let mut vm = vm_with_range_check!(); vm.segments = segments![ @@ -180,7 +278,14 @@ mod tests { ]; vm.run_context.fp = 2; let ids_data = ids_data!["sha256_start", "output"]; - assert_matches!(sha256_main(&mut vm, &ids_data, &ApTracking::new()), Ok(())); + let constants = HashMap::from([( + "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + )]); + assert_matches!( + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + Ok(()) + ); check_memory![ vm.segments.memory, @@ -194,4 +299,178 @@ mod tests { ((3, 7), 4231099170_u32) ]; } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn sha256_arbitrary_input_length_ok() { + let hint_code = hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH; + let mut vm = vm_with_range_check!(); + + vm.segments = segments![ + ((1, 0), (2, 0)), + ((1, 1), (3, 0)), + ((1, 2), (4, 0)), + ((2, 0), 22), + ((2, 1), 22), + ((2, 2), 22), + ((2, 3), 22), + ((2, 4), 22), + ((2, 5), 22), + ((2, 6), 22), + ((2, 7), 22), + ((2, 8), 22), + ((2, 9), 22), + ((2, 10), 22), + ((2, 11), 22), + ((2, 12), 22), + ((2, 13), 22), + ((2, 14), 22), + ((2, 15), 22), + ((3, 9), 0), + ((4, 0), 0x6A09E667), + ((4, 1), 0xBB67AE85), + ((4, 2), 0x3C6EF372), + ((4, 3), 0xA54FF53A), + ((4, 4), 0x510E527F), + ((4, 5), 0x9B05688C), + ((4, 6), 0x1F83D9AB), + ((4, 7), 0x5BE0CD18), + ]; + vm.run_context.fp = 3; + let ids_data = ids_data!["sha256_start", "output", "state"]; + let constants = HashMap::from([ + ( + "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + ), + ( + "SHA256_STATE_SIZE_FELTS".to_string(), + Felt252::from(SHA256_STATE_SIZE_FELTS), + ), + ]); + assert_matches!( + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + Ok(()) + ); + check_memory![ + vm.segments.memory, + ((3, 0), 1676947577_u32), + ((3, 1), 1555161467_u32), + ((3, 2), 2679819371_u32), + ((3, 3), 2084775296_u32), + ((3, 4), 3059346845_u32), + ((3, 5), 785647811_u32), + ((3, 6), 2729325562_u32), + ((3, 7), 2503090120_u32) + ]; + } + + #[rstest] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + #[case(hint_code::SHA256_MAIN_CONSTANT_INPUT_LENGTH)] + #[case(hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH)] + fn sha256_invalid_chunk_size(#[case] hint_code: &str) { + let mut vm = vm_with_range_check!(); + + vm.segments = segments![ + ((1, 0), (2, 0)), + ((1, 1), (3, 0)), + ((1, 2), (4, 0)), + ((4, 0), 0x6A09E667), + ((4, 1), 0xBB67AE85), + ((4, 2), 0x3C6EF372), + ((4, 3), 0xA54FF53A), + ((4, 4), 0x510E527F), + ((4, 5), 0x9B05688C), + ((4, 6), 0x1F83D9AB), + ((4, 7), 0x5BE0CD18), + ]; + vm.run_context.fp = 3; + let ids_data = ids_data!["sha256_start", "output", "state"]; + let constants = HashMap::from([ + ( + "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + Felt252::from(100), + ), + ( + "SHA256_STATE_SIZE_FELTS".to_string(), + Felt252::from(SHA256_STATE_SIZE_FELTS), + ), + ]); + assert_matches!( + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + Err(HintError::AssertionFailed(msg)) if msg == "AssertionError" + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn sha256_invalid_state_size() { + let hint_code = hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH; + let mut vm = vm_with_range_check!(); + + vm.segments = segments![ + ((1, 0), (2, 0)), + ((1, 1), (3, 0)), + ((1, 2), (4, 0)), + ((4, 0), 0x6A09E667), + ((4, 1), 0xBB67AE85), + ((4, 2), 0x3C6EF372), + ((4, 3), 0xA54FF53A), + ((4, 4), 0x510E527F), + ((4, 5), 0x9B05688C), + ((4, 6), 0x1F83D9AB), + ((4, 7), 0x5BE0CD18), + ]; + vm.run_context.fp = 3; + let ids_data = ids_data!["sha256_start", "output", "state"]; + let constants = HashMap::from([ + ( + "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + ), + ("SHA256_STATE_SIZE_FELTS".to_string(), Felt252::from(100)), + ]); + assert_matches!( + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + Err(HintError::AssertionFailed(msg)) if msg == "AssertionError" + ); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn sha256_unexpected_state_size() { + let hint_code = hint_code::SHA256_MAIN_ARBITRARY_INPUT_LENGTH; + let state_size = Felt252::from(9); + let mut vm = vm_with_range_check!(); + + vm.segments = segments![ + ((1, 0), (2, 0)), + ((1, 1), (3, 0)), + ((1, 2), (4, 0)), + ((4, 0), 0x6A09E667), + ((4, 1), 0xBB67AE85), + ((4, 2), 0x3C6EF372), + ((4, 3), 0xA54FF53A), + ((4, 4), 0x510E527F), + ((4, 5), 0x9B05688C), + ((4, 6), 0x1F83D9AB), + ((4, 7), 0x5BE0CD18), + ]; + vm.run_context.fp = 3; + let ids_data = ids_data!["sha256_start", "output", "state"]; + let constants = HashMap::from([ + ( + "SHA256_INPUT_CHUNK_SIZE_FELTS".to_string(), + Felt252::from(SHA256_INPUT_CHUNK_SIZE_FELTS), + ), + ("SHA256_STATE_SIZE_FELTS".to_string(), state_size.clone()), + ]); + let expected_size = Felt252::from(SHA256_STATE_SIZE_FELTS); + assert_matches!( + run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), + Err(HintError::InvalidValue("SHA256_STATE_SIZE_FELTS", got, expected)) + if got == state_size && expected == expected_size + ); + } } diff --git a/src/hint_processor/builtin_hint_processor/uint384.rs b/src/hint_processor/builtin_hint_processor/uint384.rs index d20c1362c5..ee2a2e5fea 100644 --- a/src/hint_processor/builtin_hint_processor/uint384.rs +++ b/src/hint_processor/builtin_hint_processor/uint384.rs @@ -15,8 +15,8 @@ use crate::{ }; use super::hint_utils::{ - get_integer_from_var_name, get_relocatable_from_var_name, insert_value_from_var_name, - insert_value_into_ap, + get_constant_from_var_name, get_integer_from_var_name, get_relocatable_from_var_name, + insert_value_from_var_name, insert_value_into_ap, }; use super::secp::bigint_utils::Uint384; // Notes: Hints in this lib use the type Uint384, which is equal to common lib's BigInt3 @@ -163,11 +163,7 @@ pub fn add_no_uint384_check( let a = Uint384::from_var_name("a", vm, ids_data, ap_tracking)?; let b = Uint384::from_var_name("b", vm, ids_data, ap_tracking)?; // This hint is not from the cairo commonlib, and its lib can be found under different paths, so we cant rely on a full path name - let shift = constants - .iter() - .find(|(k, _)| k.rsplit('.').next() == Some("SHIFT")) - .map(|(_, n)| n.to_biguint()) - .ok_or(HintError::MissingConstant("SHIFT"))?; + let shift = get_constant_from_var_name("SHIFT", constants)?.to_biguint(); let sum_d0 = a.d0.to_biguint() + b.d0.to_biguint(); let carry_d0 = Felt252::from((sum_d0 >= shift) as usize); diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs index ed0218b61a..6e0e023419 100644 --- a/src/tests/cairo_run_test.rs +++ b/src/tests/cairo_run_test.rs @@ -494,8 +494,8 @@ fn operations_with_data_structures() { #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] -fn sha256() { - let program_data = include_bytes!("../../cairo_programs/sha256.json"); +fn packed_sha256() { + let program_data = include_bytes!("../../cairo_programs/packed_sha256_test.json"); run_program_simple_with_memory_holes(program_data.as_slice(), 2); } @@ -932,3 +932,10 @@ fn cairo_run_normalize_address() { let program_data = include_bytes!("../../cairo_programs/normalize_address.json"); run_program_simple_with_memory_holes(program_data.as_slice(), 110); } + +#[test] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn cairo_run_sha256_test() { + let program_data = include_bytes!("../../cairo_programs/sha256_test.json"); + run_program_simple_with_memory_holes(program_data.as_slice(), 923); +} diff --git a/src/vm/errors/hint_errors.rs b/src/vm/errors/hint_errors.rs index 56d782032e..7f88c5d25c 100644 --- a/src/vm/errors/hint_errors.rs +++ b/src/vm/errors/hint_errors.rs @@ -177,4 +177,6 @@ pub enum HintError { InvalidLenValue(Felt252), #[error("recover_y: {0} does not represent the x coordinate of a point on the curve.")] RecoverYPointNotOnCurve(Felt252), + #[error("Invalid value for {0}. Got: {1}. Expected: {2}")] + InvalidValue(&'static str, Felt252, Felt252), } From 2fa79e910b41f797b69025418933ce3b26e7d73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Thu, 27 Apr 2023 17:46:35 -0300 Subject: [PATCH 2/5] Update changelog --- CHANGELOG.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f3054e89d..6d5aaac444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,26 @@ value = new_x = (pow(slope, 2, SECP_P) - x0 - x1) % SECP_P ``` +* Implement hint for cairo_sha256_arbitrary_input_length whitelist [#1091](https://github.com/lambdaclass/cairo-rs/pull/1091) + + `BuiltinHintProcessor` now supports the following hint: + + ```python + %{ + from starkware.cairo.common.cairo_sha256.sha256_utils import ( + compute_message_schedule, sha2_compress_function) + + _sha256_input_chunk_size_felts = int(ids.SHA256_INPUT_CHUNK_SIZE_FELTS) + assert 0 <= _sha256_input_chunk_size_felts < 100 + _sha256_state_size_felts = int(ids.SHA256_STATE_SIZE_FELTS) + assert 0 <= _sha256_state_size_felts < 100 + w = compute_message_schedule(memory.get_range( + ids.sha256_start, _sha256_input_chunk_size_felts)) + new_state = sha2_compress_function(memory.get_range(ids.state, _sha256_state_size_felts), w) + segments.write_arg(ids.output, new_state) + %} + ``` + * Add missing hint on vrf.json lib [#1053](https://github.com/lambdaclass/cairo-rs/pull/1053): `BuiltinHintProcessor` now supports the following hint: From 55c4a79eeefcf0bac00991a71f9c42a4c5aaf345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= <47506558+MegaRedHand@users.noreply.github.com> Date: Thu, 27 Apr 2023 18:50:10 -0300 Subject: [PATCH 3/5] Change `let` + `assert` for `assert` Co-authored-by: fmoletta <99273364+fmoletta@users.noreply.github.com> --- cairo_programs/sha256_test.cairo | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/cairo_programs/sha256_test.cairo b/cairo_programs/sha256_test.cairo index 2e53cb0cd4..f162eaa12b 100644 --- a/cairo_programs/sha256_test.cairo +++ b/cairo_programs/sha256_test.cairo @@ -21,22 +21,14 @@ func test_sha256_hello_world{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(hello_world, 11); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 3108841401; - let b = hash[1]; - assert b = 2471312904; - let c = hash[2]; - assert c = 2771276503; - let d = hash[3]; - assert d = 3665669114; - let e = hash[4]; - assert e = 3297046499; - let f = hash[5]; - assert f = 2052292846; - let g = hash[6]; - assert g = 2424895404; - let h = hash[7]; - assert h = 3807366633; + assert hash[0] = 3108841401; + assert hash[1] = 2471312904; + assert hash[2] = 2771276503; + assert hash[3] = 3665669114; + assert hash[4] = 3297046499; + assert hash[5] = 2052292846; + assert hash[6] = 2424895404; + assert hash[7] = 3807366633; return (); } From 79ca89623ae2fcb73859a8eb90419e3c996137b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Thu, 27 Apr 2023 19:00:15 -0300 Subject: [PATCH 4/5] Change AssertionFailed messages --- .../builtin_hint_processor/sha256_utils.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hint_processor/builtin_hint_processor/sha256_utils.rs b/src/hint_processor/builtin_hint_processor/sha256_utils.rs index 0588f8096f..259d3b9fb7 100644 --- a/src/hint_processor/builtin_hint_processor/sha256_utils.rs +++ b/src/hint_processor/builtin_hint_processor/sha256_utils.rs @@ -66,7 +66,9 @@ fn sha256_main( .unwrap_or(100); // Hack: enough to fail the assertion if input_chunk_size_felts >= 100 { - return Err(HintError::AssertionFailed("AssertionError".to_string())); + return Err(HintError::AssertionFailed( + "assert 0 <= _sha256_input_chunk_size_felts < 100".to_string(), + )); } let mut message: Vec = Vec::with_capacity(4 * input_chunk_size_felts); @@ -150,7 +152,11 @@ pub fn sha256_main_arbitrary_input_length( )) } // otherwise, fails the assert - _ => return Err(HintError::AssertionFailed("AssertionError".to_string())), + _ => { + return Err(HintError::AssertionFailed( + "assert 0 <= _sha256_state_size_felts < 100".to_string(), + )) + } }; let mut iv = vm @@ -399,7 +405,7 @@ mod tests { ]); assert_matches!( run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), - Err(HintError::AssertionFailed(msg)) if msg == "AssertionError" + Err(HintError::AssertionFailed(msg)) if msg == "assert 0 <= _sha256_input_chunk_size_felts < 100" ); } @@ -433,7 +439,7 @@ mod tests { ]); assert_matches!( run_hint!(&mut vm, ids_data, hint_code, exec_scopes_ref!(), &constants), - Err(HintError::AssertionFailed(msg)) if msg == "AssertionError" + Err(HintError::AssertionFailed(msg)) if msg == "assert 0 <= _sha256_state_size_felts < 100" ); } From 76e763222009606ff6bb8a40e2ef195a55513d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s?= Date: Fri, 28 Apr 2023 10:14:10 -0300 Subject: [PATCH 5/5] Change let + assert for simple assert --- cairo_programs/sha256_test.cairo | 216 +++++++++++-------------------- 1 file changed, 72 insertions(+), 144 deletions(-) diff --git a/cairo_programs/sha256_test.cairo b/cairo_programs/sha256_test.cairo index f162eaa12b..c6cb247ef8 100644 --- a/cairo_programs/sha256_test.cairo +++ b/cairo_programs/sha256_test.cairo @@ -74,22 +74,14 @@ func test_sha256_multichunks{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(phrase, 60); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 3714276112; - let b = hash[1]; - assert b = 759782134; - let c = hash[2]; - assert c = 1331117438; - let d = hash[3]; - assert c = 1331117438; - let e = hash[4]; - assert e = 699003633; - let f = hash[5]; - assert f = 2214481798; - let g = hash[6]; - assert g = 3208491254; - let h = hash[7]; - assert h = 789740750; + assert hash[0] = 3714276112; + assert hash[1] = 759782134; + assert hash[2] = 1331117438; + assert hash[3] = 1287649296; + assert hash[4] = 699003633; + assert hash[5] = 2214481798; + assert hash[6] = 3208491254; + assert hash[7] = 789740750; return (); } @@ -105,22 +97,14 @@ func test_sha256_0bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(empty, 0); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 0xe3b0c442; - let b = hash[1]; - assert b = 0x98fc1c14; - let c = hash[2]; - assert c = 0x9afbf4c8; - let d = hash[3]; - assert d = 0x996fb924; - let e = hash[4]; - assert e = 0x27ae41e4; - let f = hash[5]; - assert f = 0x649b934c; - let g = hash[6]; - assert g = 0xa495991b; - let h = hash[7]; - assert h = 0x7852b855; + assert hash[0] = 0xe3b0c442; + assert hash[1] = 0x98fc1c14; + assert hash[2] = 0x9afbf4c8; + assert hash[3] = 0x996fb924; + assert hash[4] = 0x27ae41e4; + assert hash[5] = 0x649b934c; + assert hash[6] = 0xa495991b; + assert hash[7] = 0x7852b855; return (); } @@ -133,22 +117,14 @@ func test_sha256_24bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(new ('abc\x00'), 3); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 0xba7816bf; - let b = hash[1]; - assert b = 0x8f01cfea; - let c = hash[2]; - assert c = 0x414140de; - let d = hash[3]; - assert d = 0x5dae2223; - let e = hash[4]; - assert e = 0xb00361a3; - let f = hash[5]; - assert f = 0x96177a9c; - let g = hash[6]; - assert g = 0xb410ff61; - let h = hash[7]; - assert h = 0xf20015ad; + assert hash[0] = 0xba7816bf; + assert hash[1] = 0x8f01cfea; + assert hash[2] = 0x414140de; + assert hash[3] = 0x5dae2223; + assert hash[4] = 0xb00361a3; + assert hash[5] = 0x96177a9c; + assert hash[6] = 0xb410ff61; + assert hash[7] = 0xf20015ad; return (); } @@ -177,22 +153,14 @@ func test_sha256_448bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 56); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 0x248d6a61; - let b = hash[1]; - assert b = 0xd20638b8; - let c = hash[2]; - assert c = 0xe5c02693; - let d = hash[3]; - assert d = 0x0c3e6039; - let e = hash[4]; - assert e = 0xa33ce459; - let f = hash[5]; - assert f = 0x64ff2167; - let g = hash[6]; - assert g = 0xf6ecedd4; - let h = hash[7]; - assert h = 0x19db06c1; + assert hash[0] = 0x248d6a61; + assert hash[1] = 0xd20638b8; + assert hash[2] = 0xe5c02693; + assert hash[3] = 0x0c3e6039; + assert hash[4] = 0xa33ce459; + assert hash[5] = 0x64ff2167; + assert hash[6] = 0xf6ecedd4; + assert hash[7] = 0x19db06c1; return (); } @@ -224,22 +192,14 @@ func test_sha256_504bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); // Resulting hash: 214072bf9da123ca5a8925edb05a6f071fc48fa66494d08513b9ba1b82df20cd - let a = hash[0]; - assert a = 0x214072bf; - let b = hash[1]; - assert b = 0x9da123ca; - let c = hash[2]; - assert c = 0x5a8925ed; - let d = hash[3]; - assert d = 0xb05a6f07; - let e = hash[4]; - assert e = 0x1fc48fa6; - let f = hash[5]; - assert f = 0x6494d085; - let g = hash[6]; - assert g = 0x13b9ba1b; - let h = hash[7]; - assert h = 0x82df20cd; + assert hash[0] = 0x214072bf; + assert hash[1] = 0x9da123ca; + assert hash[2] = 0x5a8925ed; + assert hash[3] = 0xb05a6f07; + assert hash[4] = 0x1fc48fa6; + assert hash[5] = 0x6494d085; + assert hash[6] = 0x13b9ba1b; + assert hash[7] = 0x82df20cd; return (); } @@ -271,22 +231,14 @@ func test_sha256_512bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); // Resulting hash: c7a7d8c0472c7f6234380e9dd3a55eb24d3e5dba9d106b74a260dc787f2f6df8 - let a = hash[0]; - assert a = 0xc7a7d8c0; - let b = hash[1]; - assert b = 0x472c7f62; - let c = hash[2]; - assert c = 0x34380e9d; - let d = hash[3]; - assert d = 0xd3a55eb2; - let e = hash[4]; - assert e = 0x4d3e5dba; - let f = hash[5]; - assert f = 0x9d106b74; - let g = hash[6]; - assert g = 0xa260dc78; - let h = hash[7]; - assert h = 0x7f2f6df8; + assert hash[0] = 0xc7a7d8c0; + assert hash[1] = 0x472c7f62; + assert hash[2] = 0x34380e9d; + assert hash[3] = 0xd3a55eb2; + assert hash[4] = 0x4d3e5dba; + assert hash[5] = 0x9d106b74; + assert hash[6] = 0xa260dc78; + assert hash[7] = 0x7f2f6df8; return (); } @@ -334,22 +286,14 @@ func test_sha256_1024bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); // Resulting hash: e324cc62be4f0465591b5cac1309ab4d5a9ee4ae8e99158c50cef7597898f046 - let a = hash[0]; - assert a = 0xe324cc62; - let b = hash[1]; - assert b = 0xbe4f0465; - let c = hash[2]; - assert c = 0x591b5cac; - let d = hash[3]; - assert d = 0x1309ab4d; - let e = hash[4]; - assert e = 0x5a9ee4ae; - let f = hash[5]; - assert f = 0x8e99158c; - let g = hash[6]; - assert g = 0x50cef759; - let h = hash[7]; - assert h = 0x7898f046; + assert hash[0] = 0xe324cc62; + assert hash[1] = 0xbe4f0465; + assert hash[2] = 0x591b5cac; + assert hash[3] = 0x1309ab4d; + assert hash[4] = 0x5a9ee4ae; + assert hash[5] = 0x8e99158c; + assert hash[6] = 0x50cef759; + assert hash[7] = 0x7898f046; return (); } @@ -392,22 +336,14 @@ func test_sha256_896bits{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(input, 112); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 0xcf5b16a7; - let b = hash[1]; - assert b = 0x78af8380; - let c = hash[2]; - assert c = 0x036ce59e; - let d = hash[3]; - assert d = 0x7b049237; - let e = hash[4]; - assert e = 0x0b249b11; - let f = hash[5]; - assert f = 0xe8f07a51; - let g = hash[6]; - assert g = 0xafac4503; - let h = hash[7]; - assert h = 0x7afee9d1; + assert hash[0] = 0xcf5b16a7; + assert hash[1] = 0x78af8380; + assert hash[2] = 0x036ce59e; + assert hash[3] = 0x7b049237; + assert hash[4] = 0x0b249b11; + assert hash[5] = 0xe8f07a51; + assert hash[6] = 0xafac4503; + assert hash[7] = 0x7afee9d1; return (); } @@ -469,22 +405,14 @@ func test_sha256_client_data{bitwise_ptr: BitwiseBuiltin*, range_check_ptr}() { let (hash) = sha256{sha256_ptr=sha256_ptr}(client_data_json, 185); finalize_sha256(sha256_ptr_start=sha256_ptr_start, sha256_ptr_end=sha256_ptr); - let a = hash[0]; - assert a = 0x08ad1974; - let b = hash[1]; - assert b = 0x216096a7; - let c = hash[2]; - assert c = 0x6ff36a54; - let d = hash[3]; - assert d = 0x159891a3; - let e = hash[4]; - assert e = 0x57d21a90; - let f = hash[5]; - assert f = 0x2c358e6f; - let g = hash[6]; - assert g = 0xeb02f14c; - let h = hash[7]; - assert h = 0xcaf48fcd; + assert hash[0] = 0x08ad1974; + assert hash[1] = 0x216096a7; + assert hash[2] = 0x6ff36a54; + assert hash[3] = 0x159891a3; + assert hash[4] = 0x57d21a90; + assert hash[5] = 0x2c358e6f; + assert hash[6] = 0xeb02f14c; + assert hash[7] = 0xcaf48fcd; return (); }