Crypto++  8.8
Free C++ class library of cryptographic schemes
basecode.cpp
1 // basecode.cpp - originally written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 #ifndef CRYPTOPP_IMPORTS
7 
8 #include "basecode.h"
9 #include "fltrimpl.h"
10 #include <ctype.h>
11 
12 NAMESPACE_BEGIN(CryptoPP)
13 
15 {
16  parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
17 
18  parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
19  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
20  throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
21 
22  byte padding;
23  bool pad;
24  if (parameters.GetValue(Name::PaddingByte(), padding))
25  pad = parameters.GetValueWithDefault(Name::Pad(), true);
26  else
27  pad = false;
28  m_padding = pad ? padding : -1;
29 
30  m_bytePos = m_bitPos = 0;
31 
32  int i = 8;
33  while (i%m_bitsPerChar != 0)
34  i += 8;
35  m_outputBlockSize = i/m_bitsPerChar;
36 
37  m_outBuf.New(m_outputBlockSize);
38 }
39 
40 size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
41 {
42  FILTER_BEGIN;
43  while (m_inputPosition < length)
44  {
45  if (m_bytePos == 0)
46  std::memset(m_outBuf, 0, m_outputBlockSize);
47 
48  {
49  unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
50  while (true)
51  {
52  CRYPTOPP_ASSERT(m_bitsPerChar-m_bitPos >= 0);
53  unsigned int bitsLeftInTarget = (unsigned int)(m_bitsPerChar-m_bitPos);
54  m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
55  if (bitsLeftInSource >= bitsLeftInTarget)
56  {
57  m_bitPos = 0;
58  ++m_bytePos;
59  bitsLeftInSource -= bitsLeftInTarget;
60  if (bitsLeftInSource == 0)
61  break;
62  b <<= bitsLeftInTarget;
63  b &= 0xff;
64  }
65  else
66  {
67  m_bitPos += bitsLeftInSource;
68  break;
69  }
70  }
71  }
72 
73  CRYPTOPP_ASSERT(m_bytePos <= m_outputBlockSize);
74  if (m_bytePos == m_outputBlockSize)
75  {
76  int i;
77  for (i=0; i<m_bytePos; i++)
78  {
79  CRYPTOPP_ASSERT(m_outBuf[i] < (1 << m_bitsPerChar));
80  m_outBuf[i] = m_alphabet[m_outBuf[i]];
81  }
82  FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
83 
84  m_bytePos = m_bitPos = 0;
85  }
86  }
87  if (messageEnd)
88  {
89  if (m_bitPos > 0)
90  ++m_bytePos;
91 
92  int i;
93  for (i=0; i<m_bytePos; i++)
94  m_outBuf[i] = m_alphabet[m_outBuf[i]];
95 
96  if (m_padding != -1 && m_bytePos > 0)
97  {
98  std::memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
99  m_bytePos = m_outputBlockSize;
100  }
101  FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
102  m_bytePos = m_bitPos = 0;
103  }
104  FILTER_END_NO_MESSAGE_END;
105 }
106 
108 {
109  parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
110 
111  parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
112  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
113  throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
114 
115  m_bytePos = m_bitPos = 0;
116 
117  int i = m_bitsPerChar;
118  while (i%8 != 0)
119  i += m_bitsPerChar;
120  m_outputBlockSize = i/8;
121 
122  m_outBuf.New(m_outputBlockSize);
123 }
124 
125 size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
126 {
127  FILTER_BEGIN;
128  while (m_inputPosition < length)
129  {
130  unsigned int value;
131  value = m_lookup[begin[m_inputPosition++]];
132  if (value >= 256)
133  continue;
134 
135  if (m_bytePos == 0 && m_bitPos == 0)
136  std::memset(m_outBuf, 0, m_outputBlockSize);
137 
138  {
139  int newBitPos = m_bitPos + m_bitsPerChar;
140  if (newBitPos <= 8)
141  m_outBuf[m_bytePos] |= value << (8-newBitPos);
142  else
143  {
144  m_outBuf[m_bytePos] |= value >> (newBitPos-8);
145  m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
146  }
147 
148  m_bitPos = newBitPos;
149  while (m_bitPos >= 8)
150  {
151  m_bitPos -= 8;
152  ++m_bytePos;
153  }
154  }
155 
156  if (m_bytePos == m_outputBlockSize)
157  {
158  FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
159  m_bytePos = m_bitPos = 0;
160  }
161  }
162  if (messageEnd)
163  {
164  FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
165  m_bytePos = m_bitPos = 0;
166  }
167  FILTER_END_NO_MESSAGE_END;
168 }
169 
170 void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
171 {
172  std::fill(lookup, lookup+256, -1);
173 
174  for (unsigned int i=0; i<base; i++)
175  {
176  // Debug asserts for 'lookup[alphabet[i]] == -1' removed because the self tests
177  // have unusual tests that try to break the encoders and decoders. Tests include
178  // a string of the same characters. I.,e., a string of stars like '********...'.
179  if (caseInsensitive && isalpha(alphabet[i]))
180  {
181  lookup[toupper(alphabet[i])] = i;
182  lookup[tolower(alphabet[i])] = i;
183  }
184  else
185  {
186  lookup[alphabet[i]] = i;
187  }
188  }
189 }
190 
191 void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
192 {
193  m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
194  ConstByteArrayParameter separator, terminator;
195  if (m_groupSize)
196  parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
197  else
198  parameters.GetValue(Name::Separator(), separator);
199  parameters.GetValue(Name::Terminator(), terminator);
200 
201  m_separator.Assign(separator.begin(), separator.size());
202  m_terminator.Assign(terminator.begin(), terminator.size());
203  m_counter = 0;
204 }
205 
206 size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
207 {
208  FILTER_BEGIN;
209  if (m_groupSize)
210  {
211  while (m_inputPosition < length)
212  {
213  if (m_counter == m_groupSize)
214  {
215  FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
216  m_counter = 0;
217  }
218 
219  size_t len;
220  FILTER_OUTPUT2(2, (len = STDMIN(length-m_inputPosition, m_groupSize-m_counter)),
221  begin+m_inputPosition, len, 0);
222  m_inputPosition += len;
223  m_counter += len;
224  }
225  }
226  else
227  FILTER_OUTPUT(3, begin, length, 0);
228 
229  if (messageEnd)
230  {
231  FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
232  m_counter = 0;
233  }
234  FILTER_END_NO_MESSAGE_END
235 }
236 
237 NAMESPACE_END
238 
239 #endif
Base classes for working with encoders and decoders.
static void InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
Initializes BaseN lookup array.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:25
size_t size() const
Length of the memory block.
Definition: algparam.h:88
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
An invalid argument was detected.
Definition: cryptlib.h:208
Interface for retrieving values given their names.
Definition: cryptlib.h:327
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
Definition: cryptlib.h:397
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:384
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:429
CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:488
void GetRequiredParameter(const char *className, const char *name, T &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:473
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:898
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
Library configuration file.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:657
Crypto++ library namespace.
const char * PaddingByte()
byte
Definition: argnames.h:73
const char * EncodingLookupArray()
const byte *
Definition: argnames.h:75
const char * GroupSize()
int
Definition: argnames.h:71
const char * Terminator()
ConstByteArrayParameter.
Definition: argnames.h:69
const char * Pad()
bool
Definition: argnames.h:72
const char * DecodingLookupArray()
const byte *
Definition: argnames.h:76
const char * Separator()
ConstByteArrayParameter.
Definition: argnames.h:68
const char * Log2Base()
int
Definition: argnames.h:74
Precompiled header file.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68