Coverage Report

Created: 2020-02-14 15:38

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