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 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 #ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
23  const word32 RC_MODULUS = 0x11011;
24 #endif
25 }
26 
27 static inline word32 reverseBits(word32 a)
28 {
29  a = ((a & 0xAAAAAAAA) >> 1) | ((a & 0x55555555) << 1);
30  a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2);
31  return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4);
32 }
33 
34 #define mu(a0, a1, a2) \
35 { \
36  a1 = reverseBits(a1); \
37  word32 t = reverseBits(a0); \
38  a0 = reverseBits(a2); \
39  a2 = t; \
40 }
41 
42 #define pi_gamma_pi(a0, a1, a2) \
43 { \
44  word32 b0, b2; \
45  b2 = rotlFixed(a2, 1U); \
46  b0 = rotlFixed(a0, 22U); \
47  a0 = rotlFixed(b0 ^ (a1|(~b2)), 1U); \
48  a2 = rotlFixed(b2 ^ (b0|(~a1)), 22U);\
49  a1 ^= (b2|(~b0)); \
50 }
51 
52 // thanks to Paulo Barreto for this optimized theta()
53 #define theta(a0, a1, a2) \
54 { \
55  word32 b0, b1, c; \
56  c = a0 ^ a1 ^ a2; \
57  c = rotlFixed(c, 16U) ^ rotlFixed(c, 8U); \
58  b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24); \
59  b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24); \
60  a0 ^= c ^ b0; \
61  a1 ^= c ^ b1; \
62  a2 ^= c ^ (b0 >> 16) ^ (b1 << 16); \
63 }
64 
65 #define rho(a0, a1, a2) \
66 { \
67  theta(a0, a1, a2); \
68  pi_gamma_pi(a0, a1, a2); \
69 }
70 
71 void ThreeWay::Base::UncheckedSetKey(const byte *uk, unsigned int length, const NameValuePairs &params)
72 {
73  AssertValidKeyLength(length);
74 
75  m_rounds = GetRoundsAndThrowIfInvalid(params, this);
76 
77  for (unsigned int i=0; i<3; i++)
78  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);
79 
80  if (!IsForwardTransformation())
81  {
82  theta(m_k[0], m_k[1], m_k[2]);
83  mu(m_k[0], m_k[1], m_k[2]);
84  m_k[0] = ByteReverse(m_k[0]);
85  m_k[1] = ByteReverse(m_k[1]);
86  m_k[2] = ByteReverse(m_k[2]);
87  }
88 }
89 
90 void ThreeWay::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
91 {
93 
94  word32 a0, a1, a2;
95  Block::Get(inBlock)(a0)(a1)(a2);
96 
97  word32 rc = START_E;
98 
99  for(unsigned i=0; i<m_rounds; i++)
100  {
101  a0 ^= m_k[0] ^ (rc<<16);
102  a1 ^= m_k[1];
103  a2 ^= m_k[2] ^ rc;
104  rho(a0, a1, a2);
105 
106  rc <<= 1;
107  if (rc&0x10000) rc ^= 0x11011;
108  }
109  a0 ^= m_k[0] ^ (rc<<16);
110  a1 ^= m_k[1];
111  a2 ^= m_k[2] ^ rc;
112  theta(a0, a1, a2);
113 
114  Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
115 }
116 
117 void ThreeWay::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
118 {
120 
121  word32 a0, a1, a2;
122  Block::Get(inBlock)(a0)(a1)(a2);
123 
124  word32 rc = START_D;
125 
126  mu(a0, a1, a2);
127  for(unsigned i=0; i<m_rounds; i++)
128  {
129  a0 ^= m_k[0] ^ (rc<<16);
130  a1 ^= m_k[1];
131  a2 ^= m_k[2] ^ rc;
132  rho(a0, a1, a2);
133 
134  rc <<= 1;
135  if (rc&0x10000) rc ^= 0x11011;
136  }
137  a0 ^= m_k[0] ^ (rc<<16);
138  a1 ^= m_k[1];
139  a2 ^= m_k[2] ^ rc;
140  theta(a0, a1, a2);
141  mu(a0, a1, a2);
142 
143  Block::Put(xorBlock, outBlock)(a0)(a1)(a2);
144 }
145 
146 NAMESPACE_END
Utility functions for the Crypto++ library.
Access a block of memory.
Definition: misc.h:2259
Classes for the 3-Way block cipher.
Access a block of memory.
Definition: misc.h:2221
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:1718
Interface for retrieving values given their names.
Definition: cryptlib.h:282