Fabcoin Core  0.16.2
P2P Digital Currency
chacha.cpp
Go to the documentation of this file.
1 // chacha.cpp - written and placed in the public domain by Jeffrey Walton.
2 // Copyright assigned to the Crypto++ project.
3 // Based on Wei Dai's Salsa20 and Bernstein's reference ChaCha
4 // family implementation at http://cr.yp.to/chacha.html.
5 
6 #include "pch.h"
7 #include "config.h"
8 #include "chacha.h"
9 #include "argnames.h"
10 #include "misc.h"
11 #include "cpu.h"
12 
14 
15 #define CHACHA_QUARTER_ROUND(a,b,c,d) \
16  a += b; d ^= a; d = rotlFixed<word32>(d,16); \
17  c += d; b ^= c; b = rotlFixed<word32>(b,12); \
18  a += b; d ^= a; d = rotlFixed<word32>(d, 8); \
19  c += d; b ^= c; b = rotlFixed<word32>(b, 7);
20 
21 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
22 void ChaCha_TestInstantiations()
23 {
27 }
28 #endif
29 
30 template <unsigned int R>
31 void ChaCha_Policy<R>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
32 {
33  CRYPTOPP_UNUSED(params);
34  CRYPTOPP_ASSERT(length == 16 || length == 32);
35 
36  // "expand 16-byte k" or "expand 32-byte k"
37  m_state[0] = 0x61707865;
38  m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e;
39  m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32;
40  m_state[3] = 0x6b206574;
41 
43  get1(m_state[4])(m_state[5])(m_state[6])(m_state[7]);
44 
45  GetBlock<word32, LittleEndian> get2(key + ((length == 32) ? 16 : 0));
46  get2(m_state[8])(m_state[9])(m_state[10])(m_state[11]);
47 }
48 
49 template <unsigned int R>
50 void ChaCha_Policy<R>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
51 {
52  CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(length);
53  CRYPTOPP_ASSERT(length==8);
54 
56  m_state[12] = m_state[13] = 0;
57  get(m_state[14])(m_state[15]);
58 }
59 
60 template<unsigned int R>
62 {
63  CRYPTOPP_UNUSED(iterationCount);
64  throw NotImplemented(std::string(ChaCha_Info<R>::StaticAlgorithmName()) + ": SeekToIteration is not yet implemented");
65 
66  // TODO: these were Salsa20, and Wei re-arranged the state array for SSE2 operations.
67  // If we can generate some out-of-band test vectors, then test and implement. Also
68  // see the test vectors in salsa.txt and the use of Seek test argument.
69  // m_state[8] = (word32)iterationCount;
70  // m_state[5] = (word32)SafeRightShift<32>(iterationCount);
71 }
72 
73 template<unsigned int R>
74 unsigned int ChaCha_Policy<R>::GetAlignment() const
75 {
76 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && 0
77  if (HasSSE2())
78  return 16;
79  else
80 #endif
81  return GetAlignmentOf<word32>();
82 }
83 
84 template<unsigned int R>
86 {
87 #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && 0
88  if (HasSSE2())
89  return 4*BYTES_PER_ITERATION;
90  else
91 #endif
92  return BYTES_PER_ITERATION;
93 }
94 
95 template<unsigned int R>
96 void ChaCha_Policy<R>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
97 {
98  word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
99 
100  while (iterationCount--)
101  {
102  x0 = m_state[0]; x1 = m_state[1]; x2 = m_state[2]; x3 = m_state[3];
103  x4 = m_state[4]; x5 = m_state[5]; x6 = m_state[6]; x7 = m_state[7];
104  x8 = m_state[8]; x9 = m_state[9]; x10 = m_state[10]; x11 = m_state[11];
105  x12 = m_state[12]; x13 = m_state[13]; x14 = m_state[14]; x15 = m_state[15];
106 
107  for (int i = static_cast<int>(ROUNDS); i > 0; i -= 2)
108  {
109  CHACHA_QUARTER_ROUND(x0, x4, x8, x12);
110  CHACHA_QUARTER_ROUND(x1, x5, x9, x13);
111  CHACHA_QUARTER_ROUND(x2, x6, x10, x14);
112  CHACHA_QUARTER_ROUND(x3, x7, x11, x15);
113 
114  CHACHA_QUARTER_ROUND(x0, x5, x10, x15);
115  CHACHA_QUARTER_ROUND(x1, x6, x11, x12);
116  CHACHA_QUARTER_ROUND(x2, x7, x8, x13);
117  CHACHA_QUARTER_ROUND(x3, x4, x9, x14);
118  }
119 
120  #undef CHACHA_OUTPUT
121  #define CHACHA_OUTPUT(x){\
122  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + m_state[0]);\
123  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x1 + m_state[1]);\
124  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x2 + m_state[2]);\
125  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x3 + m_state[3]);\
126  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + m_state[4]);\
127  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x5 + m_state[5]);\
128  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x6 + m_state[6]);\
129  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x7 + m_state[7]);\
130  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + m_state[8]);\
131  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x9 + m_state[9]);\
132  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x10 + m_state[10]);\
133  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x11 + m_state[11]);\
134  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + m_state[12]);\
135  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x13 + m_state[13]);\
136  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x14 + m_state[14]);\
137  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x15 + m_state[15]);}
138 
139 #ifndef CRYPTOPP_DOXYGEN_PROCESSING
140  CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(CHACHA_OUTPUT, BYTES_PER_ITERATION);
141 #endif
142 
143  ++m_state[12];
144  m_state[13] += static_cast<word32>(m_state[12] == 0);
145  }
146 }
147 
148 template class ChaCha_Policy<8>;
149 template class ChaCha_Policy<12>;
150 template class ChaCha_Policy<20>;
151 
153 
Standard names for retrieving values by name when working with NameValuePairs.
ChaCha stream cipher information.
Definition: chacha.h:26
uint8_t byte
Definition: Common.h:57
Utility functions for the Crypto++ library.
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
Library configuration file.
void SeekToIteration(lword iterationCount)
Seeks to a random position in the stream.
Definition: chacha.cpp:61
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
Operates the keystream.
Definition: chacha.cpp:96
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:235
void CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
Resynchronize the cipher.
Definition: chacha.cpp:50
A method was called which was not implemented.
Definition: cryptlib.h:205
ChaCha stream cipher implementation.
Definition: chacha.h:37
unsigned int GetOptimalBlockSize() const
Provides number of ideal bytes to process.
Definition: chacha.cpp:85
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
Functions for CPU features and intrinsics.
#define CHACHA_QUARTER_ROUND(a, b, c, d)
Definition: chacha.cpp:15
unsigned int GetAlignment() const
Provides data alignment requirements.
Definition: chacha.cpp:74
void CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
Key the cipher.
Definition: chacha.cpp:31
#define CRYPTOPP_UNUSED(x)
Definition: config.h:741
Access a block of memory.
Definition: misc.h:2153
#define NAMESPACE_END
Definition: config.h:201
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:90
word64 lword
Definition: config.h:245
SymmetricCipher implementation.
Definition: strciphr.h:584
unsigned int word32
Definition: config.h:231
Classes for ChaCha8, ChaCha12 and ChaCha20 stream ciphers.
#define CHACHA_OUTPUT(x)
Interface for retrieving values given their names.
Definition: cryptlib.h:279