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         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         unsigned int 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 unsigned int 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         unsigned int 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, unsigned int 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();    // don't return false here to prevent timing attack
    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, unsigned int ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
    00136 {
    00137         SecByteBlock paddedBlock(PaddedBlockByteLength());
    00138         Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, FixedCiphertextLength()));
    00139         if (x.ByteCount() > paddedBlock.size())
    00140                 x = Integer::Zero();    // don't return false here to prevent timing attack
    00141         x.Encode(paddedBlock, paddedBlock.size());
    00142         return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters);
    00143 }
    00144
    00145 void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, unsigned int plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
    00146 {
    00147         if (plaintextLength > FixedMaxPlaintextLength())
    00148                 throw InvalidArgument(AlgorithmName() + ": message too long for this public key");
    00149
    00150         SecByteBlock paddedBlock(PaddedBlockByteLength());
    00151         GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters);
    00152         GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength());
    00153 }
    00154
    00155 NAMESPACE_END
    00156
    00157 #endif