Botan 3.6.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
14/*
15* Noekeon's Theta Operation
16*/
17inline void theta(SIMD_4x32& A0,
18 SIMD_4x32& A1,
19 SIMD_4x32& A2,
20 SIMD_4x32& A3,
21 const SIMD_4x32& K0,
22 const SIMD_4x32& K1,
23 const SIMD_4x32& K2,
24 const SIMD_4x32& K3) {
25 SIMD_4x32 T = A0 ^ A2;
26 T ^= T.rotl<8>() ^ T.rotr<8>();
27 A1 ^= T;
28 A3 ^= T;
29
30 A0 ^= K0;
31 A1 ^= K1;
32 A2 ^= K2;
33 A3 ^= K3;
34
35 T = A1 ^ A3;
36 T ^= T.rotl<8>() ^ T.rotr<8>();
37 A0 ^= T;
38 A2 ^= T;
39}
40
41/*
42* Noekeon's Gamma S-Box Layer
43*/
44inline void gamma(SIMD_4x32& A0, SIMD_4x32& A1, SIMD_4x32& A2, SIMD_4x32& A3) {
45 A1 ^= ~(A2 | A3);
46 A0 ^= A2 & A1;
47
48 SIMD_4x32 T = A3;
49 A3 = A0;
50 A0 = T;
51
52 A2 ^= A0 ^ A1 ^ A3;
53
54 A1 ^= ~(A2 | A3);
55 A0 ^= A2 & A1;
56}
57
58/*
59* Noekeon Encryption
60*/
61void Noekeon::simd_encrypt_4(const uint8_t in[], uint8_t out[]) const {
62 const SIMD_4x32 K0 = SIMD_4x32::splat(m_EK[0]);
63 const SIMD_4x32 K1 = SIMD_4x32::splat(m_EK[1]);
64 const SIMD_4x32 K2 = SIMD_4x32::splat(m_EK[2]);
65 const SIMD_4x32 K3 = SIMD_4x32::splat(m_EK[3]);
66
67 SIMD_4x32 A0 = SIMD_4x32::load_be(in);
68 SIMD_4x32 A1 = SIMD_4x32::load_be(in + 16);
69 SIMD_4x32 A2 = SIMD_4x32::load_be(in + 32);
70 SIMD_4x32 A3 = SIMD_4x32::load_be(in + 48);
71
72 SIMD_4x32::transpose(A0, A1, A2, A3);
73
74 for(size_t i = 0; i != 16; ++i) {
75 A0 ^= SIMD_4x32::splat(RC[i]);
76
77 theta(A0, A1, A2, A3, K0, K1, K2, K3);
78
79 A1 = A1.rotl<1>();
80 A2 = A2.rotl<5>();
81 A3 = A3.rotl<2>();
82
83 gamma(A0, A1, A2, A3);
84
85 A1 = A1.rotr<1>();
86 A2 = A2.rotr<5>();
87 A3 = A3.rotr<2>();
88 }
89
90 A0 ^= SIMD_4x32::splat(RC[16]);
91 theta(A0, A1, A2, A3, K0, K1, K2, K3);
92
93 SIMD_4x32::transpose(A0, A1, A2, A3);
94
95 A0.store_be(out);
96 A1.store_be(out + 16);
97 A2.store_be(out + 32);
98 A3.store_be(out + 48);
99}
100
101/*
102* Noekeon Encryption
103*/
104void Noekeon::simd_decrypt_4(const uint8_t in[], uint8_t out[]) const {
105 const SIMD_4x32 K0 = SIMD_4x32::splat(m_DK[0]);
106 const SIMD_4x32 K1 = SIMD_4x32::splat(m_DK[1]);
107 const SIMD_4x32 K2 = SIMD_4x32::splat(m_DK[2]);
108 const SIMD_4x32 K3 = SIMD_4x32::splat(m_DK[3]);
109
110 SIMD_4x32 A0 = SIMD_4x32::load_be(in);
111 SIMD_4x32 A1 = SIMD_4x32::load_be(in + 16);
112 SIMD_4x32 A2 = SIMD_4x32::load_be(in + 32);
113 SIMD_4x32 A3 = SIMD_4x32::load_be(in + 48);
114
115 SIMD_4x32::transpose(A0, A1, A2, A3);
116
117 for(size_t i = 0; i != 16; ++i) {
118 theta(A0, A1, A2, A3, K0, K1, K2, K3);
119
120 A0 ^= SIMD_4x32::splat(RC[16 - i]);
121
122 A1 = A1.rotl<1>();
123 A2 = A2.rotl<5>();
124 A3 = A3.rotl<2>();
125
126 gamma(A0, A1, A2, A3);
127
128 A1 = A1.rotr<1>();
129 A2 = A2.rotr<5>();
130 A3 = A3.rotr<2>();
131 }
132
133 theta(A0, A1, A2, A3, K0, K1, K2, K3);
134 A0 ^= SIMD_4x32::splat(RC[0]);
135
136 SIMD_4x32::transpose(A0, A1, A2, A3);
137
138 A0.store_be(out);
139 A1.store_be(out + 16);
140 A2.store_be(out + 32);
141 A3.store_be(out + 48);
142}
143
144} // 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
void theta(SIMD_4x32 &A0, SIMD_4x32 &A1, SIMD_4x32 &A2, SIMD_4x32 &A3, const SIMD_4x32 &K0, const SIMD_4x32 &K1, const SIMD_4x32 &K2, const SIMD_4x32 &K3)
void gamma(SIMD_4x32 &A0, SIMD_4x32 &A1, SIMD_4x32 &A2, SIMD_4x32 &A3)