Botan 3.4.0
Crypto and TLS for C&
sha1_armv8.cpp
Go to the documentation of this file.
1/*
2* SHA-1 using CPU instructions in ARMv8
3*
4* Contributed by Jeffrey Walton. Based on public domain code by
5* Johannes Schneiders, Skip Hovsmith and Barry O'Rourke.
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#include <botan/internal/sha1.h>
11#include <arm_neon.h>
12
13namespace Botan {
14
15/*
16* SHA-1 using CPU instructions in ARMv8
17*/
18//static
19BOTAN_FUNC_ISA("+crypto+sha2")
20void SHA_1::sha1_armv8_compress_n(digest_type& digest, std::span<const uint8_t> input8, size_t blocks) {
21 uint32x4_t ABCD;
22 uint32_t E0;
23
24 // Load magic constants
25 const uint32x4_t C0 = vdupq_n_u32(0x5A827999);
26 const uint32x4_t C1 = vdupq_n_u32(0x6ED9EBA1);
27 const uint32x4_t C2 = vdupq_n_u32(0x8F1BBCDC);
28 const uint32x4_t C3 = vdupq_n_u32(0xCA62C1D6);
29
30 ABCD = vld1q_u32(&digest[0]);
31 E0 = digest[4];
32
33 // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670
34 const uint32_t* input32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const void*>(input8.data()));
35
36 while(blocks) {
37 // Save current hash
38 const uint32x4_t ABCD_SAVED = ABCD;
39 const uint32_t E0_SAVED = E0;
40
41 uint32x4_t MSG0, MSG1, MSG2, MSG3;
42 uint32x4_t TMP0, TMP1;
43 uint32_t E1;
44
45 MSG0 = vld1q_u32(input32 + 0);
46 MSG1 = vld1q_u32(input32 + 4);
47 MSG2 = vld1q_u32(input32 + 8);
48 MSG3 = vld1q_u32(input32 + 12);
49
50 MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0)));
51 MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1)));
52 MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2)));
53 MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3)));
54
55 TMP0 = vaddq_u32(MSG0, C0);
56 TMP1 = vaddq_u32(MSG1, C0);
57
58 // Rounds 0-3
59 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
60 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
61 TMP0 = vaddq_u32(MSG2, C0);
62 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
63
64 // Rounds 4-7
65 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
66 ABCD = vsha1cq_u32(ABCD, E1, TMP1);
67 TMP1 = vaddq_u32(MSG3, C0);
68 MSG0 = vsha1su1q_u32(MSG0, MSG3);
69 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
70
71 // Rounds 8-11
72 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
73 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
74 TMP0 = vaddq_u32(MSG0, C0);
75 MSG1 = vsha1su1q_u32(MSG1, MSG0);
76 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
77
78 // Rounds 12-15
79 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
80 ABCD = vsha1cq_u32(ABCD, E1, TMP1);
81 TMP1 = vaddq_u32(MSG1, C1);
82 MSG2 = vsha1su1q_u32(MSG2, MSG1);
83 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
84
85 // Rounds 16-19
86 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
87 ABCD = vsha1cq_u32(ABCD, E0, TMP0);
88 TMP0 = vaddq_u32(MSG2, C1);
89 MSG3 = vsha1su1q_u32(MSG3, MSG2);
90 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
91
92 // Rounds 20-23
93 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
94 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
95 TMP1 = vaddq_u32(MSG3, C1);
96 MSG0 = vsha1su1q_u32(MSG0, MSG3);
97 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
98
99 // Rounds 24-27
100 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
101 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
102 TMP0 = vaddq_u32(MSG0, C1);
103 MSG1 = vsha1su1q_u32(MSG1, MSG0);
104 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
105
106 // Rounds 28-31
107 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
108 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
109 TMP1 = vaddq_u32(MSG1, C1);
110 MSG2 = vsha1su1q_u32(MSG2, MSG1);
111 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
112
113 // Rounds 32-35
114 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
115 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
116 TMP0 = vaddq_u32(MSG2, C2);
117 MSG3 = vsha1su1q_u32(MSG3, MSG2);
118 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
119
120 // Rounds 36-39
121 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
122 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
123 TMP1 = vaddq_u32(MSG3, C2);
124 MSG0 = vsha1su1q_u32(MSG0, MSG3);
125 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
126
127 // Rounds 40-43
128 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
129 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
130 TMP0 = vaddq_u32(MSG0, C2);
131 MSG1 = vsha1su1q_u32(MSG1, MSG0);
132 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
133
134 // Rounds 44-47
135 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
136 ABCD = vsha1mq_u32(ABCD, E1, TMP1);
137 TMP1 = vaddq_u32(MSG1, C2);
138 MSG2 = vsha1su1q_u32(MSG2, MSG1);
139 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
140
141 // Rounds 48-51
142 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
143 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
144 TMP0 = vaddq_u32(MSG2, C2);
145 MSG3 = vsha1su1q_u32(MSG3, MSG2);
146 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
147
148 // Rounds 52-55
149 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
150 ABCD = vsha1mq_u32(ABCD, E1, TMP1);
151 TMP1 = vaddq_u32(MSG3, C3);
152 MSG0 = vsha1su1q_u32(MSG0, MSG3);
153 MSG1 = vsha1su0q_u32(MSG1, MSG2, MSG3);
154
155 // Rounds 56-59
156 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
157 ABCD = vsha1mq_u32(ABCD, E0, TMP0);
158 TMP0 = vaddq_u32(MSG0, C3);
159 MSG1 = vsha1su1q_u32(MSG1, MSG0);
160 MSG2 = vsha1su0q_u32(MSG2, MSG3, MSG0);
161
162 // Rounds 60-63
163 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
164 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
165 TMP1 = vaddq_u32(MSG1, C3);
166 MSG2 = vsha1su1q_u32(MSG2, MSG1);
167 MSG3 = vsha1su0q_u32(MSG3, MSG0, MSG1);
168
169 // Rounds 64-67
170 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
171 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
172 TMP0 = vaddq_u32(MSG2, C3);
173 MSG3 = vsha1su1q_u32(MSG3, MSG2);
174 MSG0 = vsha1su0q_u32(MSG0, MSG1, MSG2);
175
176 // Rounds 68-71
177 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
178 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
179 TMP1 = vaddq_u32(MSG3, C3);
180 MSG0 = vsha1su1q_u32(MSG0, MSG3);
181
182 // Rounds 72-75
183 E1 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
184 ABCD = vsha1pq_u32(ABCD, E0, TMP0);
185
186 // Rounds 76-79
187 E0 = vsha1h_u32(vgetq_lane_u32(ABCD, 0));
188 ABCD = vsha1pq_u32(ABCD, E1, TMP1);
189
190 // Add state back
191 E0 += E0_SAVED;
192 ABCD = vaddq_u32(ABCD_SAVED, ABCD);
193
194 input32 += 64 / 4;
195 blocks--;
196 }
197
198 // Save digest
199 vst1q_u32(&digest[0], ABCD);
200 digest[4] = E0;
201}
202
203} // namespace Botan
secure_vector< uint32_t > digest_type
Definition sha1.h:20
#define BOTAN_FUNC_ISA(isa)
Definition compiler.h:92