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)