Crypto++ 8.5 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 {
13 ThreeWay::Encryption x1;
14 ThreeWay::Decryption x2;
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 {
89 typedef BlockGetAndPut<word32, BigEndian> Block;
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 {
116 typedef BlockGetAndPut<word32, LittleEndian> Block;
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
3way.h
Classes for the 3-Way block cipher.
pch.h
Precompiled header file.
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
misc.h
Utility functions for the Crypto++ library.
PutBlock
Access a block of memory.
Definition: misc.h:2549
BlockGetAndPut
Access a block of memory.
Definition: misc.h:2586
BlockCipherFinal< ENCRYPTION, Enc >
ByteReverse
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:2001
CryptoPP
Crypto++ library namespace.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:321