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