v / vlib / crypto / blake2b / blake2b_block_generic.v
81 lines · 71 sloc · 2.27 KB · 9cc40aecc7b722385cdbe731026866a2432dc774
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 blake2b implements the Blake2b 512, 384, 256, and
5// 160 bit hash algorithms
6// as defined in IETF RFC 7693.
7// Based off: https://datatracker.ietf.org/doc/html/rfc7693
8// Last updated: November 2015
9module blake2b
10
11import math.bits
12
13// mixing function g
14@[direct_array_access; inline]
15fn g(mut v [16]u64, a u8, b u8, c u8, d u8, x u64, y u64) {
16 v[a] = v[a] + v[b] + x
17 v[d] = bits.rotate_left_64((v[d] ^ v[a]), nr1)
18 v[c] = v[c] + v[d]
19 v[b] = bits.rotate_left_64((v[b] ^ v[c]), nr2)
20 v[a] = v[a] + v[b] + y
21 v[d] = bits.rotate_left_64((v[d] ^ v[a]), nr3)
22 v[c] = v[c] + v[d]
23 v[b] = bits.rotate_left_64((v[b] ^ v[c]), nr4)
24}
25
26// one complete mixing round with the function g
27@[direct_array_access; inline]
28fn (d Digest) mixing_round(mut v [16]u64, s [16]u8) {
29 g(mut v, 0, 4, 8, 12, d.m[s[0]], d.m[s[1]])
30 g(mut v, 1, 5, 9, 13, d.m[s[2]], d.m[s[3]])
31 g(mut v, 2, 6, 10, 14, d.m[s[4]], d.m[s[5]])
32 g(mut v, 3, 7, 11, 15, d.m[s[6]], d.m[s[7]])
33
34 g(mut v, 0, 5, 10, 15, d.m[s[8]], d.m[s[9]])
35 g(mut v, 1, 6, 11, 12, d.m[s[10]], d.m[s[11]])
36 g(mut v, 2, 7, 8, 13, d.m[s[12]], d.m[s[13]])
37 g(mut v, 3, 4, 9, 14, d.m[s[14]], d.m[s[15]])
38}
39
40// compression function f
41@[direct_array_access]
42fn (mut d Digest) f(f bool) {
43 // initialize the working vector
44 mut v := [16]u64{}
45 for i in 0 .. 8 {
46 v[i] = d.h[i]
47 v[i + 8] = iv[i]
48 }
49
50 v[12] ^= d.t.lo
51 v[13] ^= d.t.hi
52
53 if f {
54 v[14] = ~v[14]
55 }
56
57 // go 12 rounds of cryptographic mixing
58 d.mixing_round(mut v, sigma[0])
59 d.mixing_round(mut v, sigma[1])
60 d.mixing_round(mut v, sigma[2])
61 d.mixing_round(mut v, sigma[3])
62 d.mixing_round(mut v, sigma[4])
63 d.mixing_round(mut v, sigma[5])
64 d.mixing_round(mut v, sigma[6])
65 d.mixing_round(mut v, sigma[7])
66 d.mixing_round(mut v, sigma[8])
67 d.mixing_round(mut v, sigma[9])
68 d.mixing_round(mut v, sigma[0])
69 d.mixing_round(mut v, sigma[1])
70
71 // combine internal hash state with both halves of the working vector
72
73 d.h[0] = d.h[0] ^ v[0] ^ v[8]
74 d.h[1] = d.h[1] ^ v[1] ^ v[9]
75 d.h[2] = d.h[2] ^ v[2] ^ v[10]
76 d.h[3] = d.h[3] ^ v[3] ^ v[11]
77 d.h[4] = d.h[4] ^ v[4] ^ v[12]
78 d.h[5] = d.h[5] ^ v[5] ^ v[13]
79 d.h[6] = d.h[6] ^ v[6] ^ v[14]
80 d.h[7] = d.h[7] ^ v[7] ^ v[15]
81}
82