pubkey.cpp
// pubkey.cpp - written and placed in the public domain by Wei Dai
#include "pch.h"
#include "config.h"
#ifndef CRYPTOPP_IMPORTS
#include "pubkey.h"
#include "integer.h"
#include "filters.h"
NAMESPACE_BEGIN(CryptoPP)
void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart)
{
ArraySink *sink;
HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength));
word32 counter = counterStart;
while (sink->AvailableSize() > 0)
{
filter.Put(input, inputLength);
filter.PutWord32(counter++);
filter.Put(derivationParams, derivationParamsLength);
filter.MessageEnd();
}
}
bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative(
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, size_t representativeBitLength) const
{
SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength));
ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength);
return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size());
}
bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative(
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
byte *representative, size_t representativeBitLength) const
{
SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize()));
DecodingResult result = RecoverMessageFromRepresentative(
hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage);
return result.isValidCoding && result.messageLength == 0;
}
void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
{
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
HashIdentifier id = GetHashIdentifier();
const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
throw PK_SignatureScheme::KeyTooShort();
size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize());
if (maxRecoverableLength == 0)
{throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");}
if (recoverableMessageLength > maxRecoverableLength)
throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm");
ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
encoding.ProcessRecoverableMessage(
ma.AccessHash(),
recoverableMessage, recoverableMessageLength,
NULL, 0, ma.m_semisignature);
}
size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
{
CRYPTOPP_UNUSED(restart);
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
HashIdentifier id = GetHashIdentifier();
const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
throw PK_SignatureScheme::KeyTooShort();
SecByteBlock representative(MessageRepresentativeLength());
encoding.ComputeMessageRepresentative(rng,
ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
ma.AccessHash(), id, ma.m_empty,
representative, MessageRepresentativeBitLength());
ma.m_empty = true;
Integer r(representative, representative.size());
size_t signatureLength = SignatureLength();
GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength);
return signatureLength;
}
void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
{
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
HashIdentifier id = GetHashIdentifier();
const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
throw PK_SignatureScheme::KeyTooShort();
ma.m_representative.New(MessageRepresentativeLength());
Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength));
if (x.BitCount() > MessageRepresentativeBitLength())
x = Integer::Zero(); // don't return false here to prevent timing attack
x.Encode(ma.m_representative, ma.m_representative.size());
}
bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
{
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
HashIdentifier id = GetHashIdentifier();
const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
throw PK_SignatureScheme::KeyTooShort();
bool result = encoding.VerifyMessageRepresentative(
ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength());
ma.m_empty = true;
return result;
}
DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
{
PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
HashIdentifier id = GetHashIdentifier();
const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
throw PK_SignatureScheme::KeyTooShort();
DecodingResult result = encoding.RecoverMessageFromRepresentative(
ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage);
ma.m_empty = true;
return result;
}
DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
{
if (ciphertextLength != FixedCiphertextLength())
throw InvalidArgument(AlgorithmName() + ": ciphertext length of " + IntToString(ciphertextLength) + " doesn't match the required length of " + IntToString(FixedCiphertextLength()) + " for this key");
SecByteBlock paddedBlock(PaddedBlockByteLength());
Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, ciphertextLength));
if (x.ByteCount() > paddedBlock.size())
x = Integer::Zero(); // don't return false here to prevent timing attack
x.Encode(paddedBlock, paddedBlock.size());
return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
}
void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
{
if (plaintextLength > FixedMaxPlaintextLength())
{
if (FixedMaxPlaintextLength() < 1)
throw InvalidArgument(AlgorithmName() + ": this key is too short to encrypt any messages");
else
throw InvalidArgument(AlgorithmName() + ": message length of " + IntToString(plaintextLength) + " exceeds the maximum of " + IntToString(FixedMaxPlaintextLength()) + " for this public key");
}
SecByteBlock paddedBlock(PaddedBlockByteLength());
GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
}
NAMESPACE_END
#endif
Algorithm::AlgorithmName
virtual std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: cryptlib.h:518
NotImplemented
A method was called which was not implemented.
Definition: cryptlib.h:203
TF_VerifierBase::VerifyAndRestart
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
Definition: pubkey.cpp:110
ArrayXorSink
Xor input to a memory buffer.
Definition: filters.h:1051
HashTransformation
Interface for hash functions and data processing part of MACs.
Definition: cryptlib.h:922
SecByteBlock
SecBlock<byte> typedef.
Definition: secblock.h:731
pubkey.h
This file contains helper classes/functions for implementing public key algorithms.
PK_SignatureScheme::KeyTooShort
Exception throw when the private or public key is too short to sign or verify.
Definition: cryptlib.h:2462
TF_VerifierBase::InputSignature
void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
Input signature into a message accumulator.
Definition: pubkey.cpp:94
filters.h
Implementation of BufferedTransformation's attachment interface.
RandomNumberGenerator
Interface for random number generators.
Definition: cryptlib.h:1186
ArraySink::AvailableSize
size_t AvailableSize()
Provides the size remaining in the Sink.
Definition: filters.h:1033
BitsToBytes
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition: misc.h:740
DecodingResult::messageLength
size_t messageLength
Recovered message length if isValidCoding is true, undefined otherwise.
Definition: cryptlib.h:259
NullRNG
RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
Definition: cryptlib.cpp:406
TF_DecryptorBase::Decrypt
DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters=g_nullNameValuePairs) const
Decrypt a byte string.
Definition: pubkey.cpp:140
VerifyBufsEqual
bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
Definition: misc.cpp:96
ArraySink
Copy input to a memory buffer.
Definition: filters.h:1016
TF_SignerBase::InputRecoverableMessage
void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
Input a recoverable message to an accumulator.
Definition: pubkey.cpp:47
IntToString
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:530
PK_MessageAccumulator
Interface for accumulating messages to be signed or verified.
Definition: cryptlib.h:2524
DecodingResult
Returns a decoding results.
Definition: cryptlib.h:236
HashFilter
Filter wrapper for HashTransformation.
Definition: filters.h:508
SecBlock::New
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:647
TF_VerifierBase::RecoverAndRestart
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const
Recover a message from its signature.
Definition: pubkey.cpp:125
PK_MessageAccumulatorBase
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:458
SecBlock::size
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
HashTransformation::DigestSize
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
InvalidArgument
An invalid argument was detected.
Definition: cryptlib.h:182
SecBlock::Assign
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:544
Integer::Zero
static const Integer & Zero()
Integer representing 0.
Definition: integer.cpp:3011
TF_EncryptorBase::Encrypt
void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters=g_nullNameValuePairs) const
Encrypt a byte string.
Definition: pubkey.cpp:153
CryptoPP
Crypto++ library namespace.
config.h
Library configuration file.
DecodingResult::isValidCoding
bool isValidCoding
Flag to indicate the decoding is valid.
Definition: cryptlib.h:257
TF_SignerBase::SignAndRestart
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const
Sign and restart messageAccumulator.
Definition: pubkey.cpp:70
PK_SignatureMessageEncodingMethod
Interface for message encoding method for public key signature schemes.
Definition: pubkey.h:332
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:277
integer.h
Multiple precision integer with arithmetic operations.
Integer
Multiple precision integer with arithmetic operations.
Definition: integer.h:45