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

Generated on Wed Jul 21 19:15:31 2004 for Crypto++ by doxygen 1.3.7-20040704