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, 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 memcmp(representative, computedRepresentative, computedRepresentative.size()) == 0;
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();    // 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, size_t 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, size_t 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

Generated on Sat Dec 23 02:07:09 2006 for Crypto++ by  doxygen 1.5.1-p1