00001
00002
00003 #include "pch.h"
00004 #include "config.h"
00005
00006 #ifndef CRYPTOPP_IMPORTS
00007
00008 #include "pubkey.h"
00009 #include "integer.h"
00010 #include "filters.h"
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013
00014 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)
00015 {
00016 ArraySink *sink;
00017 HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength));
00018 word32 counter = counterStart;
00019 while (sink->AvailableSize() > 0)
00020 {
00021 filter.Put(input, inputLength);
00022 filter.PutWord32(counter++);
00023 filter.Put(derivationParams, derivationParamsLength);
00024 filter.MessageEnd();
00025 }
00026 }
00027
00028 bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative(
00029 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00030 byte *representative, size_t representativeBitLength) const
00031 {
00032 SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength));
00033 ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength);
00034 return VerifyBufsEqual(representative, computedRepresentative, computedRepresentative.size());
00035 }
00036
00037 bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative(
00038 HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00039 byte *representative, size_t representativeBitLength) const
00040 {
00041 SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize()));
00042 DecodingResult result = RecoverMessageFromRepresentative(
00043 hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage);
00044 return result.isValidCoding && result.messageLength == 0;
00045 }
00046
00047 void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const
00048 {
00049 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00050 HashIdentifier id = GetHashIdentifier();
00051 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
00052
00053 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
00054 throw PK_SignatureScheme::KeyTooShort();
00055
00056 size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize());
00057
00058 if (maxRecoverableLength == 0)
00059 {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");}
00060 if (recoverableMessageLength > maxRecoverableLength)
00061 throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm");
00062
00063 ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
00064 encoding.ProcessRecoverableMessage(
00065 ma.AccessHash(),
00066 recoverableMessage, recoverableMessageLength,
00067 NULL, 0, ma.m_semisignature);
00068 }
00069
00070 size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
00071 {
00072 CRYPTOPP_UNUSED(restart);
00073
00074 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00075 HashIdentifier id = GetHashIdentifier();
00076 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
00077
00078 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
00079 throw PK_SignatureScheme::KeyTooShort();
00080
00081 SecByteBlock representative(MessageRepresentativeLength());
00082 encoding.ComputeMessageRepresentative(rng,
00083 ma.m_recoverableMessage, ma.m_recoverableMessage.size(),
00084 ma.AccessHash(), id, ma.m_empty,
00085 representative, MessageRepresentativeBitLength());
00086 ma.m_empty = true;
00087
00088 Integer r(representative, representative.size());
00089 size_t signatureLength = SignatureLength();
00090 GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength);
00091 return signatureLength;
00092 }
00093
00094 void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const
00095 {
00096 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00097 HashIdentifier id = GetHashIdentifier();
00098 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
00099
00100 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
00101 throw PK_SignatureScheme::KeyTooShort();
00102
00103 ma.m_representative.New(MessageRepresentativeLength());
00104 Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength));
00105 if (x.BitCount() > MessageRepresentativeBitLength())
00106 x = Integer::Zero();
00107 x.Encode(ma.m_representative, ma.m_representative.size());
00108 }
00109
00110 bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
00111 {
00112 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00113 HashIdentifier id = GetHashIdentifier();
00114 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
00115
00116 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
00117 throw PK_SignatureScheme::KeyTooShort();
00118
00119 bool result = encoding.VerifyMessageRepresentative(
00120 ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength());
00121 ma.m_empty = true;
00122 return result;
00123 }
00124
00125 DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
00126 {
00127 PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00128 HashIdentifier id = GetHashIdentifier();
00129 const MessageEncodingInterface &encoding = GetMessageEncodingInterface();
00130
00131 if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize()))
00132 throw PK_SignatureScheme::KeyTooShort();
00133
00134 DecodingResult result = encoding.RecoverMessageFromRepresentative(
00135 ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage);
00136 ma.m_empty = true;
00137 return result;
00138 }
00139
00140 DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const
00141 {
00142 if (ciphertextLength != FixedCiphertextLength())
00143 throw InvalidArgument(AlgorithmName() + ": ciphertext length of " + IntToString(ciphertextLength) + " doesn't match the required length of " + IntToString(FixedCiphertextLength()) + " for this key");
00144
00145 SecByteBlock paddedBlock(PaddedBlockByteLength());
00146 Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, ciphertextLength));
00147 if (x.ByteCount() > paddedBlock.size())
00148 x = Integer::Zero();
00149 x.Encode(paddedBlock, paddedBlock.size());
00150 return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
00151 }
00152
00153 void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const
00154 {
00155 if (plaintextLength > FixedMaxPlaintextLength())
00156 {
00157 if (FixedMaxPlaintextLength() < 1)
00158 throw InvalidArgument(AlgorithmName() + ": this key is too short to encrypt any messages");
00159 else
00160 throw InvalidArgument(AlgorithmName() + ": message length of " + IntToString(plaintextLength) + " exceeds the maximum of " + IntToString(FixedMaxPlaintextLength()) + " for this public key");
00161 }
00162
00163 SecByteBlock paddedBlock(PaddedBlockByteLength());
00164 GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
00165 GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
00166 }
00167
00168 NAMESPACE_END
00169
00170 #endif