v2 / vlib / crypto / sha1 / sha1block_generic.v
117 lines · 114 sloc · 2.78 KB · aa4c06c5a8b80cdd963fb3bd222f6a9876766c45
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. 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// This is the generic version with no architecture optimizations.
5// In its own file so that an architecture
6// optimized version can be substituted
7module sha1
8
9import math.bits
10
11const _k0 = u32(0x5A827999)
12const _k1 = u32(0x6ED9EBA1)
13const _k2 = u32(0x8F1BBCDC)
14const _k3 = u32(0xCA62C1D6)
15
16@[direct_array_access]
17fn block_generic(mut dig Digest, p_ []u8) {
18 unsafe {
19 mut p := p_
20 mut w := []u32{len: (16)}
21 mut h0 := dig.h[0]
22 mut h1 := dig.h[1]
23 mut h2 := dig.h[2]
24 mut h3 := dig.h[3]
25 mut h4 := dig.h[4]
26 for p.len >= chunk {
27 // Can interlace the computation of w with the
28 // rounds below if needed for speed.
29 for i in 0 .. 16 {
30 j := i * 4
31 w[i] = u32(p[j]) << 24 | u32(p[j + 1]) << 16 | u32(p[j + 2]) << 8 | u32(p[j + 3])
32 }
33 mut a := h0
34 mut b := h1
35 mut c := h2
36 mut d := h3
37 mut e := h4
38 // Each of the four 20-iteration rounds
39 // differs only in the computation of f and
40 // the choice of K (_k0, _k1, etc).
41 mut i := 0
42 for i < 16 {
43 f := b & c | (~b) & d
44 t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k0)
45 e = d
46 d = c
47 c = bits.rotate_left_32(b, 30)
48 b = a
49 a = t
50 i++
51 }
52 for i < 20 {
53 tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
54 w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
55 f := b & c | (~b) & d
56 t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k0)
57 e = d
58 d = c
59 c = bits.rotate_left_32(b, 30)
60 b = a
61 a = t
62 i++
63 }
64 for i < 40 {
65 tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
66 w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
67 f := b ^ c ^ d
68 t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k1)
69 e = d
70 d = c
71 c = bits.rotate_left_32(b, 30)
72 b = a
73 a = t
74 i++
75 }
76 for i < 60 {
77 tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
78 w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
79 f := ((b | c) & d) | (b & c)
80 t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k2)
81 e = d
82 d = c
83 c = bits.rotate_left_32(b, 30)
84 b = a
85 a = t
86 i++
87 }
88 for i < 80 {
89 tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
90 w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
91 f := b ^ c ^ d
92 t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k3)
93 e = d
94 d = c
95 c = bits.rotate_left_32(b, 30)
96 b = a
97 a = t
98 i++
99 }
100 h0 += a
101 h1 += b
102 h2 += c
103 h3 += d
104 h4 += e
105 if chunk >= p.len {
106 p = []
107 } else {
108 p = p[chunk..]
109 }
110 }
111 dig.h[0] = h0
112 dig.h[1] = h1
113 dig.h[2] = h2
114 dig.h[3] = h3
115 dig.h[4] = h4
116 }
117}
118