Skip to content

Commit 83f7a94

Browse files
gdkrmrstaticfloat
authored andcommitted
fast sha2
1 parent bf8d66a commit 83f7a94

File tree

2 files changed

+125
-124
lines changed

2 files changed

+125
-124
lines changed

src/constants.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const SHA1_initial_hash_value = UInt32[
1313

1414

1515
# Hash constant words K for SHA-256:
16-
const K256 = UInt32[
16+
const K256 = (
1717
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
1818
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
1919
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
@@ -30,7 +30,7 @@ const K256 = UInt32[
3030
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
3131
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
3232
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
33-
]
33+
)
3434

3535
# Initial hash value H for SHA-224:
3636
const SHA2_224_initial_hash_value = UInt32[
@@ -45,7 +45,7 @@ const SHA2_256_initial_hash_value = UInt32[
4545
]
4646

4747
# Hash constant words K for SHA-384 and SHA-512:
48-
const K512 = UInt64[
48+
const K512 = (
4949
0x428a2f98d728ae22, 0x7137449123ef65cd,
5050
0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
5151
0x3956c25bf348b538, 0x59f111f1b605d019,
@@ -86,7 +86,7 @@ const K512 = UInt64[
8686
0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
8787
0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
8888
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
89-
]
89+
)
9090

9191
# Initial hash value H for SHA-384
9292
const SHA2_384_initial_hash_value = UInt64[

src/sha2.jl

Lines changed: 121 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,135 @@
1-
function transform!(context::T) where {T<:Union{SHA2_224_CTX,SHA2_256_CTX}}
2-
pbuf = buffer_pointer(context)
3-
# Initialize registers with the previous intermediate values (our state)
4-
a = context.state[1]
5-
b = context.state[2]
6-
c = context.state[3]
7-
d = context.state[4]
8-
e = context.state[5]
9-
f = context.state[6]
10-
g = context.state[7]
11-
h = context.state[8]
12-
13-
# Run initial rounds
14-
for j = 1:16
15-
@inbounds begin
16-
# We bitswap every input byte
17-
v = bswap(unsafe_load(pbuf, j))
18-
unsafe_store!(pbuf, v, j)
19-
20-
# Apply the SHA-256 compression function to update a..h
21-
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + v
22-
T2 = Sigma0_256(a) + Maj(a, b, c)
23-
h = g
24-
g = f
25-
f = e
26-
e = UInt32(d + T1)
27-
d = c
28-
c = b
29-
b = a
30-
a = UInt32(T1 + T2)
31-
end
1+
macro R1_16(j, T)
2+
3+
ww = (:a, :b, :c, :d, :e, :f, :g, :h)
4+
5+
a = ww[((81 - j) % 8) + 1]
6+
b = ww[((82 - j) % 8) + 1]
7+
c = ww[((83 - j) % 8) + 1]
8+
d = ww[((84 - j) % 8) + 1]
9+
e = ww[((85 - j) % 8) + 1]
10+
f = ww[((86 - j) % 8) + 1]
11+
g = ww[((87 - j) % 8) + 1]
12+
h = ww[((88 - j) % 8) + 1]
13+
14+
if T == 512
15+
Sigma0 = :Sigma0_512
16+
Sigma1 = :Sigma1_512
17+
K = :K512
18+
elseif T == 256
19+
Sigma0 = :Sigma0_256
20+
Sigma1 = :Sigma1_256
21+
K = :K256
3222
end
3323

34-
for j = 17:64
35-
@inbounds begin
36-
# Implicit message block expansion:
37-
s0 = unsafe_load(pbuf, mod1(j + 1, 16))
38-
s0 = sigma0_256(s0)
39-
s1 = unsafe_load(pbuf, mod1(j + 14, 16))
40-
s1 = sigma1_256(s1)
41-
42-
# Apply the SHA-256 compression function to update a..h
43-
v = unsafe_load(pbuf, mod1(j, 16)) + s1 + unsafe_load(pbuf, mod1(j + 9, 16)) + s0
44-
unsafe_store!(pbuf, v, mod1(j, 16))
45-
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + v
46-
T2 = Sigma0_256(a) + Maj(a, b, c)
47-
h = g
48-
g = f
49-
f = e
50-
e = UInt32(d + T1)
51-
d = c
52-
c = b
53-
b = a
54-
a = UInt32(T1 + T2)
55-
end
24+
return esc(quote
25+
# We byteswap every input byte
26+
v = bswap(unsafe_load(pbuf, $j))
27+
unsafe_store!(pbuf, v, $j)
28+
29+
# Apply the SHA-256 compression function to update a..h
30+
T1 = $h + $Sigma1($e) + Ch($e, $f, $g) + $K[$j] + v
31+
$h = $Sigma0($a) + Maj($a, $b, $c)
32+
$d += T1
33+
$h += T1
34+
end)
35+
end
36+
37+
macro R17_80(j, T)
38+
39+
ww = (:a, :b, :c, :d, :e, :f, :g, :h)
40+
41+
a = ww[((81 - j) % 8) + 1]
42+
b = ww[((82 - j) % 8) + 1]
43+
c = ww[((83 - j) % 8) + 1]
44+
d = ww[((84 - j) % 8) + 1]
45+
e = ww[((85 - j) % 8) + 1]
46+
f = ww[((86 - j) % 8) + 1]
47+
g = ww[((87 - j) % 8) + 1]
48+
h = ww[((88 - j) % 8) + 1]
49+
50+
if T == 512
51+
Sigma0 = :Sigma0_512
52+
Sigma1 = :Sigma1_512
53+
sigma0 = :sigma0_512
54+
sigma1 = :sigma1_512
55+
K = :K512
56+
elseif T == 256
57+
Sigma0 = :Sigma0_256
58+
Sigma1 = :Sigma1_256
59+
sigma0 = :sigma0_256
60+
sigma1 = :sigma1_256
61+
K = :K256
5662
end
5763

58-
# Compute the current intermediate hash value
59-
context.state[1] += a
60-
context.state[2] += b
61-
context.state[3] += c
62-
context.state[4] += d
63-
context.state[5] += e
64-
context.state[6] += f
65-
context.state[7] += g
66-
context.state[8] += h
64+
return esc(quote
65+
s0 = unsafe_load(pbuf, mod1($j + 1, 16))
66+
s0 = $sigma0(s0)
67+
s1 = unsafe_load(pbuf, mod1($j + 14, 16))
68+
s1 = $sigma1(s1)
69+
70+
# Apply the SHA-256 compression function to update a..h
71+
v = unsafe_load(pbuf, mod1($j, 16)) + s1 + unsafe_load(pbuf, mod1($j + 9, 16)) + s0
72+
unsafe_store!(pbuf, v, mod1($j, 16))
73+
T1 = $h + $Sigma1($e) + Ch($e, $f, $g) + $K[$j] + v
74+
$h = $Sigma0($a) + Maj($a, $b, $c)
75+
$d += T1
76+
$h += T1
77+
end)
6778
end
6879

80+
macro R_init(T)
81+
expr = :()
82+
for i in 1:16
83+
expr = :($expr; @R1_16($i, $T))
84+
end
85+
return esc(expr)
86+
end
6987

70-
function transform!(context::Union{SHA2_384_CTX,SHA2_512_CTX})
71-
pbuf = buffer_pointer(context)
72-
# Initialize registers with the prev. intermediate value
73-
a = context.state[1]
74-
b = context.state[2]
75-
c = context.state[3]
76-
d = context.state[4]
77-
e = context.state[5]
78-
f = context.state[6]
79-
g = context.state[7]
80-
h = context.state[8]
88+
macro R_end(T)
8189

82-
for j = 1:16
83-
@inbounds begin
84-
v = bswap(unsafe_load(pbuf, j))
85-
unsafe_store!(pbuf, v, j)
86-
87-
# Apply the SHA-512 compression function to update a..h
88-
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + v
89-
T2 = Sigma0_512(a) + Maj(a, b, c)
90-
h = g
91-
g = f
92-
f = e
93-
e = d + T1
94-
d = c
95-
c = b
96-
b = a
97-
a = T1 + T2
98-
end
90+
if T == 256
91+
n_rounds = 64
92+
elseif T == 512
93+
n_rounds = 80
94+
end
95+
96+
expr = :()
97+
for i in 17:n_rounds
98+
expr = :($expr; @R17_80($i, $T))
99+
end
100+
101+
return esc(expr)
102+
end
103+
104+
@generated function transform!(context::Union{SHA2_224_CTX, SHA2_256_CTX,
105+
SHA2_384_CTX, SHA2_512_CTX})
106+
if context <: Union{SHA2_224_CTX,SHA2_256_CTX}
107+
T = 256
108+
elseif context <: Union{SHA2_384_CTX,SHA2_512_CTX}
109+
T = 512
99110
end
100111

101-
for j = 17:80
112+
return quote
113+
pbuf = buffer_pointer(context)
114+
# Initialize registers with the previous intermediate values (our state)
115+
a, b, c, d, e, f, g, h = context.state
116+
117+
# Initial Rounds
118+
@R_init($T)
119+
120+
# Other Rounds
121+
@R_end($T)
122+
123+
# Compute the current intermediate hash value
102124
@inbounds begin
103-
# Implicit message block expansion:
104-
s0 = unsafe_load(pbuf, mod1(j + 1, 16))
105-
s0 = sigma0_512(s0)
106-
s1 = unsafe_load(pbuf, mod1(j + 14, 16))
107-
s1 = sigma1_512(s1)
108-
109-
# Apply the SHA-512 compression function to update a..h
110-
v = unsafe_load(pbuf, mod1(j, 16)) + s1 + unsafe_load(pbuf, mod1(j + 9, 16)) + s0
111-
unsafe_store!(pbuf, v, mod1(j, 16))
112-
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + v
113-
T2 = Sigma0_512(a) + Maj(a, b, c)
114-
h = g
115-
g = f
116-
f = e
117-
e = d + T1
118-
d = c
119-
c = b
120-
b = a
121-
a = T1 + T2
125+
context.state[1] += a
126+
context.state[2] += b
127+
context.state[3] += c
128+
context.state[4] += d
129+
context.state[5] += e
130+
context.state[6] += f
131+
context.state[7] += g
132+
context.state[8] += h
122133
end
123134
end
124-
125-
# Compute the current intermediate hash value
126-
context.state[1] += a
127-
context.state[2] += b
128-
context.state[3] += c
129-
context.state[4] += d
130-
context.state[5] += e
131-
context.state[6] += f
132-
context.state[7] += g
133-
context.state[8] += h
134135
end

0 commit comments

Comments
 (0)