v / vlib / crypto / blake3 / blake3_block_generic.v
77 lines · 66 sloc · 2.06 KB · 4a8345667a06096fc08dd9c71e7277c2eaae4b1f
Raw
1// Copyright (c) 2023 Kim Shrier. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4// Package blake3 implements the Blake3 cryptographic hash
5// as described in:
6// https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf
7// Version 20211102173700
8
9module blake3
10
11import math.bits
12
13// mixing function g
14@[direct_array_access; inline]
15fn g(mut v [16]u32, a u8, b u8, c u8, d u8, x u32, y u32) {
16 v[a] = v[a] + v[b] + x
17 v[d] = bits.rotate_left_32((v[d] ^ v[a]), nr1)
18 v[c] = v[c] + v[d]
19 v[b] = bits.rotate_left_32((v[b] ^ v[c]), nr2)
20 v[a] = v[a] + v[b] + y
21 v[d] = bits.rotate_left_32((v[d] ^ v[a]), nr3)
22 v[c] = v[c] + v[d]
23 v[b] = bits.rotate_left_32((v[b] ^ v[c]), nr4)
24}
25
26// one complete mixing round with the function g
27@[direct_array_access; inline]
28fn mixing_round(mut v [16]u32, m []u32, s [16]u8) {
29 g(mut v, 0, 4, 8, 12, m[s[0]], m[s[1]])
30 g(mut v, 1, 5, 9, 13, m[s[2]], m[s[3]])
31 g(mut v, 2, 6, 10, 14, m[s[4]], m[s[5]])
32 g(mut v, 3, 7, 11, 15, m[s[6]], m[s[7]])
33
34 g(mut v, 0, 5, 10, 15, m[s[8]], m[s[9]])
35 g(mut v, 1, 6, 11, 12, m[s[10]], m[s[11]])
36 g(mut v, 2, 7, 8, 13, m[s[12]], m[s[13]])
37 g(mut v, 3, 4, 9, 14, m[s[14]], m[s[15]])
38}
39
40// compression function f
41@[direct_array_access]
42fn f(h []u32, m []u32, counter u64, input_bytes u32, flags u32) []u32 {
43 mut v := [16]u32{}
44
45 // initialize the working vector
46 for i in 0 .. 8 {
47 v[i] = h[i]
48 }
49 for i in 0 .. 4 {
50 v[i + 8] = iv[i]
51 }
52 v[12] = u32(counter)
53 v[13] = u32(counter >> 32)
54 v[14] = input_bytes
55 v[15] = flags
56
57 // go 7 rounds of cryptographic mixing
58 //
59 // These could potentially be spawned in concurrent tasks
60 // to see if there is any real speed improvement.
61 mixing_round(mut v, m, sigma[0])
62 mixing_round(mut v, m, sigma[1])
63 mixing_round(mut v, m, sigma[2])
64 mixing_round(mut v, m, sigma[3])
65 mixing_round(mut v, m, sigma[4])
66 mixing_round(mut v, m, sigma[5])
67 mixing_round(mut v, m, sigma[6])
68
69 // combine internal hash state with both halves of the working vector
70
71 for i in 0 .. 8 {
72 v[i] ^= v[i + 8]
73 v[i + 8] ^= h[i]
74 }
75
76 return v[..]
77}
78