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]:
13
    """
14
    Extracts 8 byte words from a given data.
15
16
    Parameters
17
    ----------
18
    data :
19
        The data in bytes from which the words need to be extracted
20
    start :
21
        Position to start the extraction
22
    num_words:
23
        The number of words to be extracted
24
    """
25
    words = []
26
    for i in range(num_words):
27
        start_position = start + (i * 8)
28
        words.append(
29
            Uint.from_le_bytes(data[start_position : start_position + 8])
30
        )
31
32
    return words

Blake2

Implementation of the BLAKE2 cryptographic hashing algorithm.

Please refer the following document for details: https://datatracker.ietf.org/doc/html/rfc7693

35
@dataclass
class Blake2:

w

44
    w: int

mask_bits

45
    mask_bits: int

word_format

46
    word_format: str

R1

48
    R1: int

R2

49
    R2: int

R3

50
    R3: int

R4

51
    R4: int

max_word

Largest value for a given Blake2 flavor.

53
    @property
def max_word(self) -> int:
55
        """
56
        Largest value for a given Blake2 flavor.
57
        """
58
        return 2**self.w

w_R1

(w - R1) value for a given Blake2 flavor. Used in the function G

60
    @property
def w_R1(self) -> int:
62
        """
63
        (w - R1) value for a given Blake2 flavor.
64
        Used in the function G
65
        """
66
        return self.w - self.R1

w_R2

(w - R2) value for a given Blake2 flavor. Used in the function G

68
    @property
def w_R2(self) -> int:
70
        """
71
        (w - R2) value for a given Blake2 flavor.
72
        Used in the function G
73
        """
74
        return self.w - self.R2

w_R3

(w - R3) value for a given Blake2 flavor. Used in the function G

76
    @property
def w_R3(self) -> int:
78
        """
79
        (w - R3) value for a given Blake2 flavor.
80
        Used in the function G
81
        """
82
        return self.w - self.R3

w_R4

(w - R4) value for a given Blake2 flavor. Used in the function G

84
    @property
def w_R4(self) -> int:
86
        """
87
        (w - R4) value for a given Blake2 flavor.
88
        Used in the function G
89
        """
90
        return self.w - self.R4

sigma

92
    sigma: Tuple = (
93
        (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15),
94
        (14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3),
95
        (11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4),
96
        (7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8),
97
        (9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13),
98
        (2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9),
99
        (12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11),
100
        (13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10),
101
        (6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5),
102
        (10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0),
103
    )

IV

105
    IV: Tuple = (
106
        0x6A09E667F3BCC908,
107
        0xBB67AE8584CAA73B,
108
        0x3C6EF372FE94F82B,
109
        0xA54FF53A5F1D36F1,
110
        0x510E527FADE682D1,
111
        0x9B05688C2B3E6C1F,
112
        0x1F83D9ABFB41BD6B,
113
        0x5BE0CD19137E2179,
114
    )

sigma_len

Length of the sigma parameter.

116
    @property
def sigma_len(self) -> int:
118
        """
119
        Length of the sigma parameter.
120
        """
121
        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:
124
        """
125
        Extract the parameters required in the Blake2 compression function
126
        from the provided bytes data.
127
128
        Parameters
129
        ----------
130
        data :
131
            The bytes data that has been passed in the message.
132
        """
133
        rounds = Uint.from_be_bytes(data[:4])
134
        h = spit_le_to_uint(data, 4, 8)
135
        m = spit_le_to_uint(data, 68, 16)
136
        t_0, t_1 = spit_le_to_uint(data, 196, 2)
137
        f = Uint.from_be_bytes(data[212:])
138
139
        return (rounds, h, m, t_0, t_1, f)

G

The mixing function used in Blake2 https://datatracker.ietf.org/doc/html/rfc7693#section-3.1

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: int, ​​b: int, ​​c: int, ​​d: int, ​​x: int, ​​y: int) -> List:
144
        """
145
        The mixing function used in Blake2
146
        https://datatracker.ietf.org/doc/html/rfc7693#section-3.1
147
148
        Parameters
149
        ----------
150
        v :
151
            The working vector to be mixed.
152
        a, b, c, d :
153
            Indexes within v of the words to be mixed.
154
        x, y :
155
            The two input words for the mixing.
156
        """
157
        v[a] = (v[a] + v[b] + x) % self.max_word
158
        v[d] = ((v[d] ^ v[a]) >> self.R1) ^ (
159
            (v[d] ^ v[a]) << self.w_R1
160
        ) % self.max_word
161
162
        v[c] = (v[c] + v[d]) % self.max_word
163
        v[b] = ((v[b] ^ v[c]) >> self.R2) ^ (
164
            (v[b] ^ v[c]) << self.w_R2
165
        ) % self.max_word
166
167
        v[a] = (v[a] + v[b] + y) % self.max_word
168
        v[d] = ((v[d] ^ v[a]) >> self.R3) ^ (
169
            (v[d] ^ v[a]) << self.w_R3
170
        ) % self.max_word
171
172
        v[c] = (v[c] + v[d]) % self.max_word
173
        v[b] = ((v[b] ^ v[c]) >> self.R4) ^ (
174
            (v[b] ^ v[c]) << self.w_R4
175
        ) % self.max_word
176
177
        return v

compress

'F Compression' from section 3.2 of RFC 7693: https://tools.ietf.org/html/rfc7693#section-3.2

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:
188
        """
189
        'F Compression' from section 3.2 of RFC 7693:
190
        https://tools.ietf.org/html/rfc7693#section-3.2
191
192
        Parameters
193
        ----------
194
        num_rounds :
195
            The number of rounds. A 32-bit unsigned big-endian word
196
        h :
197
            The state vector. 8 unsigned 64-bit little-endian words
198
        m :
199
            The message block vector. 16 unsigned 64-bit little-endian words
200
        t_0, t_1 :
201
            Offset counters. 2 unsigned 64-bit little-endian words
202
        f:
203
            The final block indicator flag. An 8-bit word
204
        """
205
        # Initialize local work vector v[0..15]
206
        v = [0] * 16
207
        v[0:8] = h  # First half from state
208
        v[8:15] = self.IV  # Second half from IV
209
210
        v[12] = t_0 ^ self.IV[4]  # Low word of the offset
211
        v[13] = t_1 ^ self.IV[5]  # High word of the offset
212
213
        if f:
214
            v[14] = v[14] ^ self.mask_bits  # Invert all bits for last block
215
216
        # Mixing
217
        for r in range(num_rounds):
218
            # for more than sigma_len rounds, the schedule
219
            # wraps around to the beginning
220
            s = self.sigma[r % self.sigma_len]
221
222
            v = self.G(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
223
            v = self.G(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
224
            v = self.G(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
225
            v = self.G(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
226
            v = self.G(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
227
            v = self.G(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
228
            v = self.G(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
229
            v = self.G(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
230
231
        result_message_words = (h[i] ^ v[i] ^ v[i + 8] for i in range(8))
232
        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.

236
@dataclass
class Blake2b:

w

243
    w: int = 64

mask_bits

244
    mask_bits: int = 0xFFFFFFFFFFFFFFFF

word_format

245
    word_format: str = "Q"

R1

247
    R1: int = 32

R2

248
    R2: int = 24

R3

249
    R3: int = 16

R4

250
    R4: int = 63