1
1
from starkware.cairo.common.alloc import alloc
2
2
from starkware.cairo.common.cairo_blake2s.blake2s import blake_with_opcode
3
3
4
+ // Gets a felt that represent a 256-bit unsigned integer stored as an array of eight 32-bit unsigned integers
5
+ // represented in little-endian notation. Return the felt representation of the integer modulo prime.
6
+ func felt_from_le_u32s (u256: felt *) -> felt {
7
+ let hash = u256[7 ] * 2 ** 224 + u256[6 ] * 2 ** 192 + u256[5 ] * 2 ** 160 + u256[4 ] * 2 ** 128 +
8
+ u256[3 ] * 2 ** 96 + u256[2 ] * 2 ** 64 + u256[1 ] * 2 ** 32 + u256[0 ];
9
+ return hash;
10
+ }
11
+
4
12
// Computes blake2s of `input` of size 16 felts, representing 32 bits each.
5
13
// The initial state is the standard BLAKE2s IV XORed with the parameter block P[0] = 0x01010020.
6
14
func blake_with_opcode_for_single_16_length_word (data: felt *, out: felt *, initial_state: felt *) {
@@ -51,10 +59,9 @@ func create_initial_state_for_blake2s() -> (initial_state: felt*) {
51
59
}
52
60
53
61
// Encodes a list of felt252s to a list of u32s, each felt is mapped to eight u32s.
54
- // Returns the length of the resulting list of u32s.
55
62
func naive_encode_felt252s_to_u32s (
56
63
packed_values_len: felt , packed_values: felt *, unpacked_u32s: felt *
57
- ) -> felt {
64
+ ) {
58
65
alloc_locals ;
59
66
60
67
local end: felt * = &packed_values[packed_values_len];
@@ -65,41 +72,29 @@ func naive_encode_felt252s_to_u32s(
65
72
66
73
loop:
67
74
if (end == packed_values) {
68
- return out - unpacked_u32s ;
75
+ return () ;
69
76
}
70
77
71
78
// TODO(Noa): Assert that the limbs represent a number in the range [0, PRIME-1].
72
79
// Assert that the limbs represent the number.
73
- assert packed_values[0 ] = (
74
- (out[7 ] + (2 ** 32 * out[6 ])) +
75
- 2 ** (32 * 2 ) * (out[5 ] + 2 ** 32 * out[4 ]) +
76
- 2 ** (32 * 4 ) * (out[3 ] + 2 ** 32 * out[2 ]) +
77
- 2 ** (32 * 6 ) * (out[1 ] + 2 ** 32 * out[0 ])
78
- );
80
+ let actual_value = felt_from_le_u32s(u256=out);
81
+ assert packed_values[0 ] = actual_value;
79
82
80
83
tempvar out = &out[8 ];
81
84
tempvar packed_values = &packed_values[1 ];
82
85
jmp loop;
83
86
}
84
87
85
- // Gets a felt that represent a 256-bit unsigned integer stored as an array of eight 32-bit unsigned integers
86
- // represented in little-endian notation. Return the felt representation of the integer modulo prime.
87
- func u256_to_felt (u256: felt *) -> felt {
88
- let hash = u256[7 ] * 2 ** 224 + u256[6 ] * 2 ** 192 + u256[5 ] * 2 ** 160 + u256[4 ] * 2 ** 128 +
89
- u256[3 ] * 2 ** 96 + u256[2 ] * 2 ** 64 + u256[1 ] * 2 ** 32 + u256[0 ];
90
- return hash;
91
- }
92
-
93
88
// / Encodes a slice of `Felt` values into 32-bit words, then hashes the resulting byte stream
94
89
// / with Blake2s-256 and returns the 256-bit digest to a 252-bit field element `Felt`.
95
90
func calc_blake_hash {range_check_ptr: felt } (data_len: felt , data: felt *) -> (hash: felt ) {
96
91
alloc_locals ;
97
92
let (local encoded_data: felt *) = alloc();
98
- let encoded_data_len = naive_encode_felt252s_to_u32s(
93
+ naive_encode_felt252s_to_u32s(
99
94
packed_values_len=data_len, packed_values=data, unpacked_u32s=encoded_data
100
95
);
101
96
let (local blake_output: felt *) = alloc();
102
- blake_with_opcode(len=encoded_data_len , data=encoded_data, out=blake_output);
103
- let hash = u256_to_felt (u256=blake_output);
97
+ blake_with_opcode(len=8 * data_len , data=encoded_data, out=blake_output);
98
+ let hash = felt_from_le_u32s (u256=blake_output);
104
99
return (hash=hash);
105
100
}
0 commit comments