ethereum.crypto.blake2
The Blake2 Implementation.
spit_le_to_uint
Extracts 8 byte words from a given data.
Parameters
data : The data in bytes from which the words need to be extracted start : Position to start the extraction num_words: The number of words to be extracted
                def spit_le_to_uint(data: bytes, start: int, num_words: int) -> List[Uint]:
            
| 11 |     """ | 
|---|---|
| 12 |     Extracts 8 byte words from a given data. | 
| 13 |  | 
| 14 |     Parameters | 
| 15 |     ---------- | 
| 16 |     data : | 
| 17 |         The data in bytes from which the words need to be extracted | 
| 18 |     start : | 
| 19 |         Position to start the extraction | 
| 20 |     num_words: | 
| 21 |         The number of words to be extracted | 
| 22 |  | 
| 23 |     """ | 
| 24 |     words = [] | 
| 25 |     for i in range(num_words): | 
| 26 |         start_position = start + (i * 8) | 
| 27 |         words.append( | 
| 28 |             Uint.from_le_bytes(data[start_position : start_position + 8]) | 
| 29 |         ) | 
| 30 | |
| 31 |     return words | 
Blake2
Implementation of the BLAKE2 cryptographic hashing algorithm.
Please refer the following document for details: https://datatracker.ietf.org/doc/html/rfc7693
| 34 | @dataclass | 
|---|
class Blake2:
w
| 43 |     w: Uint | 
|---|
mask_bits
| 44 |     mask_bits: Uint | 
|---|
word_format
| 45 |     word_format: str | 
|---|
R1
| 47 |     R1: Uint | 
|---|
R2
| 48 |     R2: Uint | 
|---|
R3
| 49 |     R3: Uint | 
|---|
R4
| 50 |     R4: Uint | 
|---|
max_word
Largest value for a given Blake2 flavor.
| 52 |     @property | 
|---|
                def max_word(self) -> Uint:
            
| 54 |         """ | 
|---|---|
| 55 |         Largest value for a given Blake2 flavor. | 
| 56 |         """ | 
| 57 |         return Uint(2) ** self.w | 
w_R1
(w - R1) value for a given Blake2 flavor. Used in the function G.
| 59 |     @property | 
|---|
                def w_R1(self) -> Uint:
            
| 61 |         """ | 
|---|---|
| 62 |         (w - R1) value for a given Blake2 flavor. | 
| 63 |         Used in the function G. | 
| 64 |         """ | 
| 65 |         return self.w - self.R1 | 
w_R2
(w - R2) value for a given Blake2 flavor. Used in the function G.
| 67 |     @property | 
|---|
                def w_R2(self) -> Uint:
            
| 69 |         """ | 
|---|---|
| 70 |         (w - R2) value for a given Blake2 flavor. | 
| 71 |         Used in the function G. | 
| 72 |         """ | 
| 73 |         return self.w - self.R2 | 
w_R3
(w - R3) value for a given Blake2 flavor. Used in the function G.
| 75 |     @property | 
|---|
                def w_R3(self) -> Uint:
            
| 77 |         """ | 
|---|---|
| 78 |         (w - R3) value for a given Blake2 flavor. | 
| 79 |         Used in the function G. | 
| 80 |         """ | 
| 81 |         return self.w - self.R3 | 
w_R4
(w - R4) value for a given Blake2 flavor. Used in the function G.
| 83 |     @property | 
|---|
                def w_R4(self) -> Uint:
            
| 85 |         """ | 
|---|---|
| 86 |         (w - R4) value for a given Blake2 flavor. | 
| 87 |         Used in the function G. | 
| 88 |         """ | 
| 89 |         return self.w - self.R4 | 
sigma
| 91 |     sigma: Tuple[Tuple[int, ...], ...] = ( | 
|---|---|
| 92 |         (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), | 
| 93 |         (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3), | 
| 94 |         (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4), | 
| 95 |         (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8), | 
| 96 |         (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13), | 
| 97 |         (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9), | 
| 98 |         (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11), | 
| 99 |         (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10), | 
| 100 |         (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5), | 
| 101 |         (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0), | 
| 102 |     ) | 
IV
| 104 |     IV: Tuple[Uint, ...] = ( | 
|---|---|
| 105 |         Uint(0x6A09E667F3BCC908), | 
| 106 |         Uint(0xBB67AE8584CAA73B), | 
| 107 |         Uint(0x3C6EF372FE94F82B), | 
| 108 |         Uint(0xA54FF53A5F1D36F1), | 
| 109 |         Uint(0x510E527FADE682D1), | 
| 110 |         Uint(0x9B05688C2B3E6C1F), | 
| 111 |         Uint(0x1F83D9ABFB41BD6B), | 
| 112 |         Uint(0x5BE0CD19137E2179), | 
| 113 |     ) | 
MIX_TABLE
| 115 |     MIX_TABLE: Final[Tuple[Tuple[Uint, Uint, Uint, Uint], ...]] = ( | 
|---|---|
| 116 |         (Uint(0), Uint(4), Uint(8), Uint(12)), | 
| 117 |         (Uint(1), Uint(5), Uint(9), Uint(13)), | 
| 118 |         (Uint(2), Uint(6), Uint(10), Uint(14)), | 
| 119 |         (Uint(3), Uint(7), Uint(11), Uint(15)), | 
| 120 |         (Uint(0), Uint(5), Uint(10), Uint(15)), | 
| 121 |         (Uint(1), Uint(6), Uint(11), Uint(12)), | 
| 122 |         (Uint(2), Uint(7), Uint(8), Uint(13)), | 
| 123 |         (Uint(3), Uint(4), Uint(9), Uint(14)), | 
| 124 |     ) | 
sigma_len
Length of the sigma parameter.
| 126 |     @property | 
|---|
                def sigma_len(self) -> int:
            
| 128 |         """ | 
|---|---|
| 129 |         Length of the sigma parameter. | 
| 130 |         """ | 
| 131 |         return len(self.sigma) | 
get_blake2_parameters
Extract the parameters required in the Blake2 compression function from the provided bytes data.
Parameters
data : The bytes data that has been passed in the message.
                def get_blake2_parameters(self, data: bytes) -> Tuple:
            
| 134 |         """ | 
|---|---|
| 135 |         Extract the parameters required in the Blake2 compression function | 
| 136 |         from the provided bytes data. | 
| 137 |  | 
| 138 |         Parameters | 
| 139 |         ---------- | 
| 140 |         data : | 
| 141 |             The bytes data that has been passed in the message. | 
| 142 |  | 
| 143 |         """ | 
| 144 |         rounds = Uint.from_be_bytes(data[:4]) | 
| 145 |         h = spit_le_to_uint(data, 4, 8) | 
| 146 |         m = spit_le_to_uint(data, 68, 16) | 
| 147 |         t_0, t_1 = spit_le_to_uint(data, 196, 2) | 
| 148 |         f = Uint.from_be_bytes(data[212:]) | 
| 149 | |
| 150 |         return (rounds, h, m, t_0, t_1, f) | 
G
The mixing function used in Blake2.
See RFC 7693 for more details.
Parameters
v : The working vector to be mixed. a, b, c, d : Indexes within v of the words to be mixed. x, y : The two input words for the mixing.
                def G(self, v: List, a: Uint, b: Uint, c: Uint, d: Uint, x: Uint, y: Uint) -> List:
            
| 155 |         """ | 
|---|---|
| 156 |         The mixing function used in Blake2. | 
| 157 |  | 
| 158 |         See [RFC 7693] for more details. | 
| 159 |  | 
| 160 |         [RFC 7693]: https://datatracker.ietf.org/doc/html/rfc7693#section-3.1 | 
| 161 |  | 
| 162 |         Parameters | 
| 163 |         ---------- | 
| 164 |         v : | 
| 165 |             The working vector to be mixed. | 
| 166 |         a, b, c, d : | 
| 167 |             Indexes within v of the words to be mixed. | 
| 168 |         x, y : | 
| 169 |             The two input words for the mixing. | 
| 170 |  | 
| 171 |         """ | 
| 172 |         v[a] = (v[a] + v[b] + x) % self.max_word | 
| 173 |         v[d] = ((v[d] ^ v[a]) >> self.R1) ^ ( | 
| 174 |             (v[d] ^ v[a]) << self.w_R1 | 
| 175 |         ) % self.max_word | 
| 176 | |
| 177 |         v[c] = (v[c] + v[d]) % self.max_word | 
| 178 |         v[b] = ((v[b] ^ v[c]) >> self.R2) ^ ( | 
| 179 |             (v[b] ^ v[c]) << self.w_R2 | 
| 180 |         ) % self.max_word | 
| 181 | |
| 182 |         v[a] = (v[a] + v[b] + y) % self.max_word | 
| 183 |         v[d] = ((v[d] ^ v[a]) >> self.R3) ^ ( | 
| 184 |             (v[d] ^ v[a]) << self.w_R3 | 
| 185 |         ) % self.max_word | 
| 186 | |
| 187 |         v[c] = (v[c] + v[d]) % self.max_word | 
| 188 |         v[b] = ((v[b] ^ v[c]) >> self.R4) ^ ( | 
| 189 |             (v[b] ^ v[c]) << self.w_R4 | 
| 190 |         ) % self.max_word | 
| 191 | |
| 192 |         return v | 
compress
'F Compression' from section 3.2 of RFC 7693.
Parameters
num_rounds : The number of rounds. A 32-bit unsigned big-endian word h : The state vector. 8 unsigned 64-bit little-endian words m : The message block vector. 16 unsigned 64-bit little-endian words t_0, t_1 : Offset counters. 2 unsigned 64-bit little-endian words f: The final block indicator flag. An 8-bit word
                def compress(self, num_rounds: Uint, h: List[Uint], m: List[Uint], t_0: Uint, t_1: Uint, f: bool) -> bytes:
            
| 203 |         """ | 
|---|---|
| 204 |         'F Compression' from section 3.2 of RFC 7693. | 
| 205 |  | 
| 206 |         Parameters | 
| 207 |         ---------- | 
| 208 |         num_rounds : | 
| 209 |             The number of rounds. A 32-bit unsigned big-endian word | 
| 210 |         h : | 
| 211 |             The state vector. 8 unsigned 64-bit little-endian words | 
| 212 |         m : | 
| 213 |             The message block vector. 16 unsigned 64-bit little-endian words | 
| 214 |         t_0, t_1 : | 
| 215 |             Offset counters. 2 unsigned 64-bit little-endian words | 
| 216 |         f: | 
| 217 |             The final block indicator flag. An 8-bit word | 
| 218 |  | 
| 219 |         """ | 
| 220 |         # Initialize local work vector v[0..15] | 
| 221 |         v = [Uint(0)] * 16 | 
| 222 |         v[0:8] = h  # First half from state | 
| 223 |         v[8:15] = self.IV  # Second half from IV | 
| 224 | |
| 225 |         v[12] = t_0 ^ self.IV[4]  # Low word of the offset | 
| 226 |         v[13] = t_1 ^ self.IV[5]  # High word of the offset | 
| 227 | |
| 228 |         if f: | 
| 229 |             v[14] = v[14] ^ self.mask_bits  # Invert all bits for last block | 
| 230 | |
| 231 |         # Mixing | 
| 232 |         for r in range(num_rounds): | 
| 233 |             # for more than sigma_len rounds, the schedule | 
| 234 |             # wraps around to the beginning | 
| 235 |             s = self.sigma[r % self.sigma_len] | 
| 236 |  | 
| 237 |             v = self.G(v, *self.MIX_TABLE[0], m[s[0]], m[s[1]]) | 
| 238 |             v = self.G(v, *self.MIX_TABLE[1], m[s[2]], m[s[3]]) | 
| 239 |             v = self.G(v, *self.MIX_TABLE[2], m[s[4]], m[s[5]]) | 
| 240 |             v = self.G(v, *self.MIX_TABLE[3], m[s[6]], m[s[7]]) | 
| 241 |             v = self.G(v, *self.MIX_TABLE[4], m[s[8]], m[s[9]]) | 
| 242 |             v = self.G(v, *self.MIX_TABLE[5], m[s[10]], m[s[11]]) | 
| 243 |             v = self.G(v, *self.MIX_TABLE[6], m[s[12]], m[s[13]]) | 
| 244 |             v = self.G(v, *self.MIX_TABLE[7], m[s[14]], m[s[15]]) | 
| 245 | |
| 246 |         result_message_words = (h[i] ^ v[i] ^ v[i + 8] for i in range(8)) | 
| 247 |         return struct.pack("<8%s" % self.word_format, *result_message_words) | 
Blake2b
The Blake2b flavor (64-bits) of Blake2. This version is used in the pre-compiled contract.
| 251 | @dataclass | 
|---|
class Blake2b:
w
| 258 |     w: Uint = Uint(64) | 
|---|
mask_bits
| 259 |     mask_bits: Uint = Uint(0xFFFFFFFFFFFFFFFF) | 
|---|
word_format
| 260 |     word_format: str = "Q" | 
|---|
R1
| 262 |     R1: Uint = Uint(32) | 
|---|
R2
| 263 |     R2: Uint = Uint(24) | 
|---|
R3
| 264 |     R3: Uint = Uint(16) | 
|---|
R4
| 265 |     R4: Uint = Uint(63) | 
|---|