/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 | | } |