-
Notifications
You must be signed in to change notification settings - Fork 164
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a0f8806
commit 1c031e4
Showing
11 changed files
with
422 additions
and
66 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
cairo_programs/stwo_exclusive_programs/blake2s_opcode_test.cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
%builtins range_check | ||
|
||
from starkware.cairo.common.alloc import alloc | ||
from starkware.cairo.common.cairo_blake2s.blake2s import blake2s_inner, INPUT_BLOCK_BYTES, STATE_SIZE_FELTS, INPUT_BLOCK_FELTS | ||
|
||
const COUNTER = 128; | ||
|
||
// Tests the Blake2s opcode runner using a preexisting implementation within the repo as reference. | ||
// The initial state, a random message of 68 bytes and counter are used as input. | ||
// Both the opcode and the reference implementation are run on the same inputs and then their outputs are compared. | ||
// Before comparing the outputs, it is verified that the opcode runner has written the output to the correct location. | ||
func main{range_check_ptr}() { | ||
alloc_locals; | ||
|
||
let (local random_message) = alloc(); | ||
assert random_message[0] = 930933030; | ||
assert random_message[1] = 1766240503; | ||
assert random_message[2] = 3660871006; | ||
assert random_message[3] = 388409270; | ||
assert random_message[4] = 1948594622; | ||
assert random_message[5] = 3119396969; | ||
assert random_message[6] = 3924579183; | ||
assert random_message[7] = 2089920034; | ||
assert random_message[8] = 3857888532; | ||
assert random_message[9] = 929304360; | ||
assert random_message[10] = 1810891574; | ||
assert random_message[11] = 860971754; | ||
assert random_message[12] = 1822893775; | ||
assert random_message[13] = 2008495810; | ||
assert random_message[14] = 2958962335; | ||
assert random_message[15] = 2340515744; | ||
assert random_message[16] = 1111307871; | ||
|
||
let (local blake2s_ptr_start) = alloc(); | ||
let blake2s_ptr = blake2s_ptr_start; | ||
// Set the initial state to IV (IV[0] is modified). | ||
assert blake2s_ptr[0] = 0x6B08E647; // IV[0] ^ 0x01010020 (config: no key, 32 bytes output). | ||
assert blake2s_ptr[1] = 0xBB67AE85; | ||
assert blake2s_ptr[2] = 0x3C6EF372; | ||
assert blake2s_ptr[3] = 0xA54FF53A; | ||
assert blake2s_ptr[4] = 0x510E527F; | ||
assert blake2s_ptr[5] = 0x9B05688C; | ||
assert blake2s_ptr[6] = 0x1F83D9AB; | ||
assert blake2s_ptr[7] = 0x5BE0CD19; | ||
static_assert STATE_SIZE_FELTS == 8; | ||
let blake2s_ptr = blake2s_ptr + STATE_SIZE_FELTS; | ||
|
||
let (cairo_output) = blake2s_inner{range_check_ptr=range_check_ptr, blake2s_ptr=blake2s_ptr}(data=random_message, n_bytes=INPUT_BLOCK_BYTES+4, counter=COUNTER); | ||
|
||
let relevant_output_start = blake2s_ptr_start+INPUT_BLOCK_FELTS+2+STATE_SIZE_FELTS; | ||
|
||
let vm_output_start = run_blake2s( | ||
dst=COUNTER+INPUT_BLOCK_BYTES, | ||
op0=blake2s_ptr_start, | ||
op1=random_message, | ||
); | ||
|
||
tempvar check_nonempty = vm_output_start[0]; | ||
tempvar check_nonempty = vm_output_start[1]; | ||
tempvar check_nonempty = vm_output_start[2]; | ||
tempvar check_nonempty = vm_output_start[3]; | ||
tempvar check_nonempty = vm_output_start[4]; | ||
tempvar check_nonempty = vm_output_start[5]; | ||
tempvar check_nonempty = vm_output_start[6]; | ||
tempvar check_nonempty = vm_output_start[7]; | ||
|
||
assert vm_output_start[0] = relevant_output_start[0]; | ||
assert vm_output_start[1] = relevant_output_start[1]; | ||
assert vm_output_start[2] = relevant_output_start[2]; | ||
assert vm_output_start[3] = relevant_output_start[3]; | ||
assert vm_output_start[4] = relevant_output_start[4]; | ||
assert vm_output_start[5] = relevant_output_start[5]; | ||
assert vm_output_start[6] = relevant_output_start[6]; | ||
assert vm_output_start[7] = relevant_output_start[7]; | ||
|
||
return (); | ||
} | ||
|
||
// Forces the runner to execute the Blake2s with the given operands. | ||
// op0 is a pointer to an array of 8 felts as u32 integers of the state. | ||
// op1 is a pointer to an array of 16 felts as u32 integers of the messsage. | ||
// dst is a felt representing a u32 of the counter. | ||
// ap contains a pointer to an array of 8 felts as u32 integers of the output state. | ||
// Those values are stored within addresses fp-5, fp-4 and fp-3 respectively. | ||
// An instruction encoding is built from offsets -5, -4, -3 and flags which are all 0 except for | ||
// those denoting uses of fp as the base for operand addresses and flag_opcode_blake (16th flag). | ||
// The instruction is then written to [pc] and the runner is forced to execute Blake2s. | ||
func run_blake2s( | ||
dst: felt, | ||
op0: felt*, | ||
op1: felt*, | ||
) -> felt* { | ||
alloc_locals; | ||
let offset0 = (2**15)-5; | ||
let offset1 = (2**15)-4; | ||
let offset2 = (2**15)-3; | ||
static_assert dst == [fp -5]; | ||
static_assert op0 == [fp -4]; | ||
static_assert op1 == [fp -3]; | ||
let flag_dst_base_fp = 1; | ||
let flag_op0_base_fp = 1; | ||
let flag_op1_imm = 0; | ||
let flag_op1_base_fp = 1; | ||
let flag_op1_base_ap = 0; | ||
let flag_res_add = 0; | ||
let flag_res_mul = 0; | ||
let flag_PC_update_jump = 0; | ||
let flag_PC_update_jump_rel = 0; | ||
let flag_PC_update_jnz = 0; | ||
let flag_ap_update_add = 0; | ||
let flag_ap_update_add_1 = 0; | ||
let flag_opcode_call = 0; | ||
let flag_opcode_ret = 0; | ||
let flag_opcode_assert_eq = 0; | ||
let flag_opcode_blake2s = 1; | ||
let flag_num = flag_dst_base_fp+flag_op0_base_fp*(2**1)+flag_op1_imm*(2**2)+flag_op1_base_fp*(2**3)+flag_opcode_blake2s*(2**15); | ||
let instruction_num = offset0 + offset1*(2**16) + offset2*(2**32) + flag_num*(2**48); | ||
static_assert instruction_num==9226608988349300731; | ||
let (local vm_output_start) = alloc(); | ||
assert [ap] = cast(vm_output_start, felt); | ||
dw 9226608988349300731; | ||
let vm_output_start = cast([ap], felt*); | ||
return vm_output_start; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.