Botan 3.7.1
Crypto and TLS for C&
noekeon_simd.cpp
Go to the documentation of this file.
1/*
2* Noekeon in SIMD
3* (C) 2010 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/internal/noekeon.h>
9
10#include <botan/internal/simd_32.h>
11
12namespace Botan {
13
14namespace {
15
16/*
17* Noekeon's Theta Operation
18*/
19inline void theta(SIMD_4x32& A0,
20 SIMD_4x32& A1,
21 SIMD_4x32& A2,
22 SIMD_4x32& A3,
23 const SIMD_4x32& K0,
24 const SIMD_4x32& K1,
25 const SIMD_4x32& K2,
26 const SIMD_4x32& K3) {
27 SIMD_4x32 T = A0 ^ A2;
28 T ^= T.rotl<8>() ^ T.rotr<8>();
29 A1 ^= T;
30 A3 ^= T;
31
32 A0 ^= K0;
33 A1 ^= K1;
34 A2 ^= K2;
35 A3 ^= K3;
36
37 T = A1 ^ A3;
38 T ^= T.rotl<8>() ^ T.rotr<8>();
39 A0 ^= T;
40 A2 ^= T;
41}
42
43/*
44* Noekeon's Gamma S-Box Layer
45*/
46inline void gamma(SIMD_4x32& A0, SIMD_4x32& A1, SIMD_4x32& A2, SIMD_4x32& A3) {
47 A1 ^= ~(A2 | A3);
48 A0 ^= A2 & A1;
49
50 SIMD_4x32 T = A3;
51 A3 = A0;
52 A0 = T;
53
54 A2 ^= A0 ^ A1 ^ A3;
55
56 A1 ^= ~(A2 | A3);
57 A0 ^= A2 & A1;
58}
59
60} // namespace
61
62/*
63* Noekeon Encryption
64*/
65void Noekeon::simd_encrypt_4(const uint8_t in[], uint8_t out[]) const {
66 const SIMD_4x32 K0 = SIMD_4x32::splat(m_EK[0]);
67 const SIMD_4x32 K1 = SIMD_4x32::splat(m_EK[1]);
68 const SIMD_4x32 K2 = SIMD_4x32::splat(m_EK[2]);
69 const SIMD_4x32 K3 = SIMD_4x32::splat(m_EK[3]);
70
71 SIMD_4x32 A0 = SIMD_4x32::load_be(in);
72 SIMD_4x32 A1 = SIMD_4x32::load_be(in + 16);
73 SIMD_4x32 A2 = SIMD_4x32::load_be(in + 32);
74 SIMD_4x32 A3 = SIMD_4x32::load_be(in + 48);
75
76 SIMD_4x32::transpose(A0, A1, A2, A3);
77
78 for(size_t i = 0; i != 16; ++i) {
79 A0 ^= SIMD_4x32::splat(RC[i]);
80
81 theta(A0, A1, A2, A3, K0, K1, K2, K3);
82
83 A1 = A1.rotl<1>();
84 A2 = A2.rotl<5>();
85 A3 = A3.rotl<2>();
86
87 gamma(A0, A1, A2, A3);
88
89 A1 = A1.rotr<1>();
90 A2 = A2.rotr<5>();
91 A3 = A3.rotr<2>();
92 }
93
94 A0 ^= SIMD_4x32::splat(RC[16]);
95 theta(A0, A1, A2, A3, K0, K1, K2, K3);
96
97 SIMD_4x32::transpose(A0, A1, A2, A3);
98
99 A0.store_be(out);
100 A1.store_be(out + 16);
101 A2.store_be(out + 32);
102 A3.store_be(out + 48);
103}
104
105/*
106* Noekeon Encryption
107*/
108void Noekeon::simd_decrypt_4(const uint8_t in[], uint8_t out[]) const {
109 const SIMD_4x32 K0 = SIMD_4x32::splat(m_DK[0]);
110 const SIMD_4x32 K1 = SIMD_4x32::splat(m_DK[1]);
111 const SIMD_4x32 K2 = SIMD_4x32::splat(m_DK[2]);
112 const SIMD_4x32 K3 = SIMD_4x32::splat(m_DK[3]);
113
114 SIMD_4x32 A0 = SIMD_4x32::load_be(in);
115 SIMD_4x32 A1 = SIMD_4x32::load_be(in + 16);
116 SIMD_4x32 A2 = SIMD_4x32::load_be(in + 32);
117 SIMD_4x32 A3 = SIMD_4x32::load_be(in + 48);
118
119 SIMD_4x32::transpose(A0, A1, A2, A3);
120
121 for(size_t i = 0; i != 16; ++i) {
122 theta(A0, A1, A2, A3, K0, K1, K2, K3);
123
124 A0 ^= SIMD_4x32::splat(RC[16 - i]);
125
126 A1 = A1.rotl<1>();
127 A2 = A2.rotl<5>();
128 A3 = A3.rotl<2>();
129
130 gamma(A0, A1, A2, A3);
131
132 A1 = A1.rotr<1>();
133 A2 = A2.rotr<5>();
134 A3 = A3.rotr<2>();
135 }
136
137 theta(A0, A1, A2, A3, K0, K1, K2, K3);
138 A0 ^= SIMD_4x32::splat(RC[0]);
139
140 SIMD_4x32::transpose(A0, A1, A2, A3);
141
142 A0.store_be(out);
143 A1.store_be(out + 16);
144 A2.store_be(out + 32);
145 A3.store_be(out + 48);
146}
147
148} // namespace Botan
static SIMD_4x32 load_be(const void *in) noexcept
Definition simd_32.h:175
static void transpose(SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3) noexcept
Definition simd_32.h:554
static SIMD_4x32 splat(uint32_t B) noexcept
Definition simd_32.h:132
FE_25519 T
Definition ge.cpp:34
uint8x16_t uint8x16_t K2
Definition aes_armv8.cpp:32