Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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