Botan 3.13.0
Crypto and TLS for C&
shacal2_arvm8.cpp
Go to the documentation of this file.
1/*
2* (C) 2020 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/shacal2.h>
8
9#include <botan/internal/isa_extn.h>
10#include <arm_neon.h>
11
12namespace Botan {
13
14/*
15Only encryption is supported since the inverse round function would
16require a different instruction
17*/
18BOTAN_FN_ISA_SHA2
19void SHACAL2::armv8_encrypt_blocks(const uint8_t input[], uint8_t output[], size_t blocks) const {
20 while(blocks >= 2) {
21 uint32x4_t B0_0 = vreinterpretq_u32_u8(vld1q_u8(input + 0));
22 uint32x4_t B0_1 = vreinterpretq_u32_u8(vld1q_u8(input + 16));
23 uint32x4_t B1_0 = vreinterpretq_u32_u8(vld1q_u8(input + 32));
24 uint32x4_t B1_1 = vreinterpretq_u32_u8(vld1q_u8(input + 48));
25
26 B0_0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0_0)));
27 B0_1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0_1)));
28 B1_0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1_0)));
29 B1_1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1_1)));
30
31 for(size_t i = 0; i != 8; ++i) {
32 const auto RK0 = vld1q_u32(&m_RK[8 * i]);
33 const auto RK1 = vld1q_u32(&m_RK[8 * i + 4]);
34
35 const auto T0_0 = vsha256hq_u32(B0_0, B0_1, RK0);
36 const auto T0_1 = vsha256h2q_u32(B0_1, B0_0, RK0);
37 const auto T1_0 = vsha256hq_u32(B1_0, B1_1, RK0);
38 const auto T1_1 = vsha256h2q_u32(B1_1, B1_0, RK0);
39
40 B0_0 = vsha256hq_u32(T0_0, T0_1, RK1);
41 B0_1 = vsha256h2q_u32(T0_1, T0_0, RK1);
42 B1_0 = vsha256hq_u32(T1_0, T1_1, RK1);
43 B1_1 = vsha256h2q_u32(T1_1, T1_0, RK1);
44 }
45
46 B0_0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0_0)));
47 B0_1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0_1)));
48 B1_0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1_0)));
49 B1_1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1_1)));
50
51 vst1q_u8(output + 0, vreinterpretq_u8_u32(B0_0));
52 vst1q_u8(output + 16, vreinterpretq_u8_u32(B0_1));
53 vst1q_u8(output + 32, vreinterpretq_u8_u32(B1_0));
54 vst1q_u8(output + 48, vreinterpretq_u8_u32(B1_1));
55
56 blocks -= 2;
57 input += 64;
58 output += 64;
59 }
60
61 while(blocks > 0) {
62 uint32x4_t B0 = vreinterpretq_u32_u8(vld1q_u8(input + 0));
63 uint32x4_t B1 = vreinterpretq_u32_u8(vld1q_u8(input + 16));
64
65 B0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0)));
66 B1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1)));
67
68 for(size_t i = 0; i != 8; ++i) {
69 const auto RK0 = vld1q_u32(&m_RK[8 * i]);
70 const auto RK1 = vld1q_u32(&m_RK[8 * i + 4]);
71
72 const auto T0 = vsha256hq_u32(B0, B1, RK0);
73 const auto T1 = vsha256h2q_u32(B1, B0, RK0);
74
75 B0 = vsha256hq_u32(T0, T1, RK1);
76 B1 = vsha256h2q_u32(T1, T0, RK1);
77 }
78
79 B0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B0)));
80 B1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(B1)));
81
82 vst1q_u8(output + 0, vreinterpretq_u8_u32(B0));
83 vst1q_u8(output + 16, vreinterpretq_u8_u32(B1));
84
85 blocks--;
86 input += 32;
87 output += 32;
88 }
89}
90
91} // namespace Botan