Crypto++ 8.7
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
8NAMESPACE_BEGIN(CryptoPP)
9
10#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
11void ThreeWay_TestInstantiations()
12{
15}
16#endif
17
18namespace
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
24static 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
68void 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
87void 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
114void 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
143NAMESPACE_END
Classes for the 3-Way block cipher.
Interface for retrieving values given their names.
Definition: cryptlib.h:322
Access a block of memory.
Definition: misc.h:2807
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:62
Utility functions for the Crypto++ library.
byte ByteReverse(byte value)
Reverses bytes in a 8-bit value.
Definition: misc.h:2022
Crypto++ library namespace.
Precompiled header file.
Access a block of memory.
Definition: misc.h:2844