Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

pubkey.cpp

00001 // pubkey.cpp - written and placed in the public domain by Wei Dai
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, unsigned int outputLength, const byte *input, unsigned int inputLength, const byte *derivationParams, unsigned int 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, unsigned int representativeBitLength) const
00028 {
00029         SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength));
00030         ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength);
00031         return memcmp(representative, computedRepresentative, computedRepresentative.size()) == 0;
00032 }
00033 
00034 bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative(
00035         HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
00036         byte *representative, unsigned int 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, unsigned int recoverableMessageLength) const
00045 {
00046         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00047         const MessageEncodingInterface &mei = GetMessageEncodingInterface();
00048         unsigned int maxRecoverableLength = mei.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize());
00049 
00050         if (maxRecoverableLength == 0)
00051                 {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");}
00052         if (recoverableMessageLength > maxRecoverableLength)
00053                 throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm");
00054 
00055         ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength);
00056         mei.ProcessRecoverableMessage(
00057                 ma.AccessHash(), 
00058                 recoverableMessage, recoverableMessageLength,
00059                 NULL, 0, ma.m_semisignature);
00060 }
00061 
00062 unsigned int TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const
00063 {
00064         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00065         SecByteBlock representative(MessageRepresentativeLength());
00066         GetMessageEncodingInterface().ComputeMessageRepresentative(rng, 
00067                 ma.m_recoverableMessage, ma.m_recoverableMessage.size(), 
00068                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty,
00069                 representative, MessageRepresentativeBitLength());
00070         ma.m_empty = true;
00071 
00072         Integer r(representative, representative.size());
00073         unsigned int signatureLength = SignatureLength();
00074         GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength);
00075         return signatureLength;
00076 }
00077 
00078 void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, unsigned int signatureLength) const
00079 {
00080         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00081         ma.m_representative.New(MessageRepresentativeLength());
00082         Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength));
00083         if (x.BitCount() > MessageRepresentativeBitLength())
00084                 x = Integer::Zero();    // don't return false here to prevent timing attack
00085         x.Encode(ma.m_representative, ma.m_representative.size());
00086 }
00087 
00088 bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const
00089 {
00090         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00091         bool result = GetMessageEncodingInterface().VerifyMessageRepresentative(
00092                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength());
00093         ma.m_empty = true;
00094         return result;
00095 }
00096 
00097 DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const
00098 {
00099         PK_MessageAccumulatorBase &ma = static_cast<PK_MessageAccumulatorBase &>(messageAccumulator);
00100         DecodingResult result = GetMessageEncodingInterface().RecoverMessageFromRepresentative(
00101                 ma.AccessHash(), GetHashIdentifier(), ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage);
00102         ma.m_empty = true;
00103         return result;
00104 }
00105 
00106 DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
00107 {
00108         SecByteBlock paddedBlock(PaddedBlockByteLength());
00109         Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, FixedCiphertextLength()));
00110         if (x.ByteCount() > paddedBlock.size())
00111                 x = Integer::Zero();    // don't return false here to prevent timing attack
00112         x.Encode(paddedBlock, paddedBlock.size());
00113         return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
00114 }
00115 
00116 void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
00117 {
00118         if (plaintextLength > FixedMaxPlaintextLength())
00119                 throw InvalidArgument(AlgorithmName() + ": message too long for this public key");
00120 
00121         SecByteBlock paddedBlock(PaddedBlockByteLength());
00122         GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
00123         GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
00124 }
00125 
00126 NAMESPACE_END
00127 
00128 #endif

Generated on Fri Sep 9 19:01:22 2005 for Crypto++ by  doxygen 1.4.4