Crypto++  5.6.5 Free C++ class library of cryptographic schemes
3way.cpp
1 // 3way.cpp - modifed by Wei Dai from Joan Daemen's 3way.c
2 // The original code and all modifications are in the public domain.
3
4 #include "pch.h"
5 #include "3way.h"
6 #include "misc.h"
7
8 NAMESPACE_BEGIN(CryptoPP)
9
10 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
11 void ThreeWay_TestInstantiations()
12 {
15 }
16 #endif
17
18 namespace
19 {
20  const word32 START_E = 0x0b0b; // round constant of first encryption round
21  const word32 START_D = 0xb1b1; // round constant of first decryption round
22 }
23
24 static inline word32 reverseBits(word32 a)
25 {
26  a = ((a & 0xAAAAAAAA) >> 1) | ((a & 0x55555555) << 1);
27  a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2);
28  return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4);
29 }
30
31 #define mu(a0, a1, a2) \
32 { \
33  a1 = reverseBits(a1); \
34  word32 t = reverseBits(a0); \
35  a0 = reverseBits(a2); \
36  a2 = t; \
37 }
38
39 #define pi_gamma_pi(a0, a1, a2) \
40 { \
41  word32 b0, b2; \
42  b2 = rotlConstant<1>(a2); \
43  b0 = rotlConstant<22>(a0); \
44  a0 = rotlConstant<1>(b0 ^ (a1|(~b2))); \
45  a2 = rotlConstant<22>(b2 ^ (b0|(~a1))); \
46  a1 ^= (b2|(~b0)); \
47 }
48
49 // thanks to Paulo Barreto for this optimized theta()
50 #define theta(a0, a1, a2) \
51 { \
52  word32 b0, b1, c; \
53  c = a0 ^ a1 ^ a2; \
54  c = rotlConstant<16>(c) ^ rotlConstant<8>(c); \
55  b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24); \
56  b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24); \
57  a0 ^= c ^ b0; \
58  a1 ^= c ^ b1; \
59  a2 ^= c ^ (b0 >> 16) ^ (b1 << 16); \
60 }
61
62 #define rho(a0, a1, a2) \
63 { \
64  theta(a0, a1, a2); \
65  pi_gamma_pi(a0, a1, a2); \
66 }
67
68 void ThreeWay::Base::UncheckedSetKey(const byte *uk, unsigned int length, const NameValuePairs &params)
69 {
70  AssertValidKeyLength(length);
71
72  m_rounds = GetRoundsAndThrowIfInvalid(params, this);
73
74  for (unsigned int i=0; i<3; i++)
75  m_k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24);
76
77  if (!IsForwardTransformation())
78  {
79  theta(m_k[0], m_k[1], m_k[2]);
80  mu(m_k[0], m_k[1], m_k[2]);
81  m_k[0] = ByteReverse(m_k[0]);
82  m_k[1] = ByteReverse(m_k[1]);
83  m_k[2] = ByteReverse(m_k[2]);
84  }
85 }
86
87 void ThreeWay::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
88 {
90
91  word32 a0, a1, a2;
92  Block::Get(inBlock)(a0)(a1)(a2);
93
94  word32 rc = START_E;
95
96  for(unsigned i=0; i<m_rounds; i++)
97  {
98  a0 ^= m_k[0] ^ (rc<<16);
99  a1 ^= m_k[1];
100  a2 ^= m_k[2] ^ rc;
101  rho(a0, a1, a2);
102
103  rc <<= 1;
104  if (rc&0x10000) rc ^= 0x11011;
105  }
106  a0 ^= m_k[0] ^ (rc<<16);
107  a1 ^= m_k[1];
108  a2 ^= m_k[2] ^ rc;
109  theta(a0, a1, a2);
110
111  Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
112 }
113
114 void ThreeWay::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
115 {
117
118  word32 a0, a1, a2;
119  Block::Get(inBlock)(a0)(a1)(a2);
120
121  word32 rc = START_D;
122
123  mu(a0, a1, a2);
124  for(unsigned i=0; i<m_rounds; i++)
125  {
126  a0 ^= m_k[0] ^ (rc<<16);
127  a1 ^= m_k[1];
128  a2 ^= m_k[2] ^ rc;
129  rho(a0, a1, a2);
130
131  rc <<= 1;
132  if (rc&0x10000) rc ^= 0x11011;
133  }
134  a0 ^= m_k[0] ^ (rc<<16);
135  a1 ^= m_k[1];
136  a2 ^= m_k[2] ^ rc;
137  theta(a0, a1, a2);
138  mu(a0, a1, a2);
139
140  Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
141 }
142
143 NAMESPACE_END
Utility functions for the Crypto++ library.
Access a block of memory.
Definition: misc.h:2397
Classes for the 3-Way block cipher.
Access a block of memory.
Definition: misc.h:2360
Crypto++ library namespace.
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:1833
Interface for retrieving values given their names.
Definition: cryptlib.h:291