Crypto++  8.8
Free C++ class library of cryptographic schemes
3way.cpp
1 // 3way.cpp - modified 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
Classes for the 3-Way block cipher.
Interface for retrieving values given their names.
Definition: cryptlib.h:327
Access a block of memory.
Definition: misc.h:3016
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
Utility functions for the Crypto++ library.
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:2231
Crypto++ library namespace.
Precompiled header file.
Access a block of memory.
Definition: misc.h:3053