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