Botan  2.8.0
Crypto and TLS for C++11
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 
11 namespace 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_32 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_32 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 */
56 void Noekeon::simd_encrypt_4(const uint8_t in[], uint8_t out[]) const
57  {
58  const SIMD_32 K0 = SIMD_32::splat(m_EK[0]);
59  const SIMD_32 K1 = SIMD_32::splat(m_EK[1]);
60  const SIMD_32 K2 = SIMD_32::splat(m_EK[2]);
61  const SIMD_32 K3 = SIMD_32::splat(m_EK[3]);
62 
63  SIMD_32 A0 = SIMD_32::load_be(in );
64  SIMD_32 A1 = SIMD_32::load_be(in + 16);
65  SIMD_32 A2 = SIMD_32::load_be(in + 32);
66  SIMD_32 A3 = SIMD_32::load_be(in + 48);
67 
68  SIMD_32::transpose(A0, A1, A2, A3);
69 
70  for(size_t i = 0; i != 16; ++i)
71  {
72  A0 ^= SIMD_32::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_32::splat(RC[16]);
88  NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3);
89 
90  SIMD_32::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 */
101 void Noekeon::simd_decrypt_4(const uint8_t in[], uint8_t out[]) const
102  {
103  const SIMD_32 K0 = SIMD_32::splat(m_DK[0]);
104  const SIMD_32 K1 = SIMD_32::splat(m_DK[1]);
105  const SIMD_32 K2 = SIMD_32::splat(m_DK[2]);
106  const SIMD_32 K3 = SIMD_32::splat(m_DK[3]);
107 
108  SIMD_32 A0 = SIMD_32::load_be(in );
109  SIMD_32 A1 = SIMD_32::load_be(in + 16);
110  SIMD_32 A2 = SIMD_32::load_be(in + 32);
111  SIMD_32 A3 = SIMD_32::load_be(in + 48);
112 
113  SIMD_32::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_32::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_32::splat(RC[0]);
134 
135  SIMD_32::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 void transpose(SIMD_4x32 &B0, SIMD_4x32 &B1, SIMD_4x32 &B2, SIMD_4x32 &B3)
Definition: simd_32.h:564
#define NOK_SIMD_GAMMA(A0, A1, A2, A3)
static SIMD_4x32 load_be(const void *in)
Definition: simd_32.h:161
Definition: alg_id.cpp:13
static SIMD_4x32 splat(uint32_t B)
Definition: simd_32.h:117
#define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3)
SIMD_4x32 SIMD_32
Definition: simd_32.h:650