size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) { FILTER_BEGIN; m_ciphertextQueue.Put(inString, length); if (messageEnd) { { size_t ciphertextLength; if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); SecByteBlock ciphertext(ciphertextLength); m_ciphertextQueue.Get(ciphertext, ciphertextLength); m_plaintext.resize(maxPlaintextLength); m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); if (!m_result.isValidCoding) throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); } FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); } FILTER_END_NO_MESSAGE_END; }
PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n) { #if !defined(NDEBUG) int x; CRYPTOPP_UNUSED(x); assert(SafeConvert(n,x)); #endif if (!reg.size()) return *this; int i; word u; word carry=0; word *r=reg; if (n==1) // special case code for most frequent case { i = (int)reg.size(); while (i--) { u = *r; *r = (u << 1) | carry; carry = u >> (WORD_BITS-1); r++; } if (carry) { reg.Grow(reg.size()+1); reg[reg.size()-1] = carry; } return *this; }
/* * This routine is called to encode a symbol. The symbol is passed * in the SYMBOL structure as a low count, a high count, and a range, * instead of the more conventional probability ranges. The encoding * process takes two steps. First, the values of high and low are * updated to take into account the range restriction created by the * new symbol. Then, as many bits as possible are shifted out to * the output stream. Finally, high and low are stable again and * the routine returns. */ void encode_symbol( FILE *stream, SYMBOL *s ) { unsigned long long range; range = (unsigned long long) ( high-low ) + 1; high = SafeConvert(div128(mult128(range, s->high_count), s->scale).lo + low - 1); low = SafeConvert(div128(mult128(range, s->low_count), s->scale).lo + low); /* * This loop turns out new bits until high and low are far enough * apart to have stabilized. */ for ( ; ; ) { /* * If this test passes, it means that the MSDigits match, and can * be sent to the output stream. */ if ( ( high & LAST_BIT ) == ( low & LAST_BIT ) ) { output_bit( stream, high & LAST_BIT ); while ( underflow_bits > 0 ) { output_bit( stream, ~high & LAST_BIT ); underflow_bits--; } } /* * If this test passes, the numbers are in danger of underflow, because * the MSDigits don't match, and the 2nd digits are just one apart. */ else if ( ( low & NEXT_TO_LAST_BIT ) && !( high & NEXT_TO_LAST_BIT )) { underflow_bits += 1; low &= NEXT_TO_LAST_BIT_MINUS_ONE; high |= NEXT_TO_LAST_BIT; } else return ; low <<= 1; high <<= 1; high |= 1; } }
lword FileStore::Skip(lword skipMax) { if (!m_stream) return 0; lword oldPos = m_stream->tellg(); std::istream::off_type offset; if (!SafeConvert(skipMax, offset)) throw InvalidArgument("FileStore: maximum seek offset exceeded"); m_stream->seekg(offset, std::ios::cur); return (lword)m_stream->tellg() - oldPos; }
/* * Just figuring out what the present symbol is doesn't remove * it from the input bit stream. After the character has been * decoded, this routine has to be called to remove it from the * input stream. */ void remove_symbol_from_stream( FILE *stream, SYMBOL *s ) { unsigned long long range; range = (unsigned long long) ( high-low ) + 1; high = SafeConvert(div128(mult128(range, s->high_count), s->scale).lo + low - 1); low = SafeConvert(div128(mult128(range, s->low_count), s->scale).lo + low); /* * Next, any possible bits are shipped out. */ for ( ; ; ) { /* * If the MSDigits match, the bits will be shifted out. */ if ( ( high & LAST_BIT ) == ( low & LAST_BIT ) ) { } /* * Else, if underflow is threatining, shift out the 2nd MSDigit. */ else if ((low & NEXT_TO_LAST_BIT) == NEXT_TO_LAST_BIT && (high & NEXT_TO_LAST_BIT) == 0 ) { code ^= NEXT_TO_LAST_BIT; low &= NEXT_TO_LAST_BIT_MINUS_ONE; high |= NEXT_TO_LAST_BIT; } /* * Otherwise, nothing can be shifted out, so I return. */ else return; low <<= 1; high <<= 1; high |= 1; code <<= 1; code += input_bit( stream ); } }
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) { FILTER_BEGIN; m_plaintextQueue.Put(inString, length); if (messageEnd) { { size_t plaintextLength; if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); SecByteBlock plaintext(plaintextLength); m_plaintextQueue.Get(plaintext, plaintextLength); m_ciphertext.resize(ciphertextLength); m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); } FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); } FILTER_END_NO_MESSAGE_END; }
bool PrimeSieve::NextCandidate(Integer &c) { bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next); assert(safe); if (m_next == m_sieve.size()) { m_first += long(m_sieve.size())*m_step; if (m_first > m_last) return false; else { m_next = 0; DoSieve(); return NextCandidate(c); } } else { c = m_first + long(m_next)*m_step; ++m_next; return true; } }
size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) { CRYPTOPP_UNUSED(blocking); if (!m_stream) throw Err("FileSink: output stream not opened"); while (length > 0) { std::streamsize size; if (!SafeConvert(length, size)) size = ((std::numeric_limits<std::streamsize>::max)()); m_stream->write((const char *)inString, size); inString += size; length -= (size_t)size; } if (messageEnd) m_stream->flush(); if (!m_stream->good()) throw WriteErr(); return 0; }