Botan  2.7.0
Crypto and TLS for C++11
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 C0, C1, C2, C3;
24  uint32x4_t ABCD, ABCD_SAVED;
25  uint32_t E0, E0_SAVED, E1;
26 
27  // Load initial values
28  C0 = vdupq_n_u32(0x5A827999);
29  C1 = vdupq_n_u32(0x6ED9EBA1);
30  C2 = vdupq_n_u32(0x8F1BBCDC);
31  C3 = vdupq_n_u32(0xCA62C1D6);
32 
33  ABCD = vld1q_u32(&digest[0]);
34  E0 = digest[4];
35 
36  // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670
37  const uint32_t* input32 = reinterpret_cast<const uint32_t*>(reinterpret_cast<const void*>(input8));
38 
39  while (blocks)
40  {
41  uint32x4_t MSG0, MSG1, MSG2, MSG3;
42  uint32x4_t TMP0, TMP1;
43 
44  // Save current hash
45  ABCD_SAVED = ABCD;
46  E0_SAVED = E0;
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 }
#define BOTAN_FUNC_ISA(isa)
Definition: compiler.h:75
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88