Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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