/* * Modification History * * 2002-August-5 Jason Rohrer * Made a virtual destructor. */ #ifndef CRYPTOPP_PUBKEY_H #define CRYPTOPP_PUBKEY_H #include "integer.h" #include "filters.h" #include #include NAMESPACE_BEGIN(CryptoPP) Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen); Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen); // ******************************************************** //! base class for a trapdoor function class TrapdoorFunction { public: virtual ~TrapdoorFunction() {} virtual Integer ApplyFunction(const Integer &x) const =0; virtual Integer PreimageBound() const =0; virtual Integer ImageBound() const =0; virtual Integer MaxPreimage() const {return --PreimageBound();} virtual Integer MaxImage() const {return --ImageBound();} }; //! invertible trapdoor function class InvertibleTrapdoorFunction : virtual public TrapdoorFunction { public: virtual Integer CalculateInverse(const Integer &x) const =0; }; //! Base Class class PaddingScheme { public: virtual ~PaddingScheme() {} virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0; virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const =0; // returns length of raw virtual unsigned int Unpad(const byte *padded, unsigned int paddedLength, byte *raw) const =0; }; // ******************************************************** //! . template class P1363_MGF1 { public: static void GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength); }; template void P1363_MGF1::GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength) { H h; ArrayXorSink *sink; HashFilter filter(h, sink = new ArrayXorSink(output, outputLength)); word32 counter = 0; while (sink->AvailableSize() > 0) { filter.Put(input, inputLength); filter.PutWord32(counter++); filter.MessageEnd(); } } // ******************************************************** //! . template class P1363_KDF2 { public: static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength); }; template void P1363_KDF2::DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength) { H h; ArraySink *sink; HashFilter filter(h, sink = new ArraySink(output, outputLength)); word32 counter = 1; while (sink->AvailableSize() > 0) { filter.Put(input, inputLength); filter.PutWord32(counter++); filter.MessageEnd(); } } // ******************************************************** //! . template class PublicKeyBaseTemplate { public: PublicKeyBaseTemplate(const F &f) : f(f) {} PublicKeyBaseTemplate(BufferedTransformation &bt) : f(bt) {} virtual ~PublicKeyBaseTemplate() {} void DEREncode(BufferedTransformation &bt) const {f.DEREncode(bt);} const F & GetTrapdoorFunction() const {return f;} protected: // a hack to avoid having to write constructors for non-concrete derived classes PublicKeyBaseTemplate() : f(*(F*)0) {assert(false);} // should never be called virtual unsigned int PaddedBlockBitLength() const =0; unsigned int PaddedBlockByteLength() const {return bitsToBytes(PaddedBlockBitLength());} F f; }; // ******************************************************** //! . template class CryptoSystemBaseTemplate : virtual public PK_FixedLengthCryptoSystem, virtual public PublicKeyBaseTemplate { public: unsigned int MaxPlainTextLength() const {return pad.MaxUnpaddedLength(PaddedBlockBitLength());} unsigned int CipherTextLength() const {return f.MaxImage().ByteCount();} P pad; protected: CryptoSystemBaseTemplate() {} unsigned int PaddedBlockBitLength() const {return f.PreimageBound().BitCount()-1;} }; //! . template class DecryptorTemplate : public PK_FixedLengthDecryptor, public CryptoSystemBaseTemplate { public: ~DecryptorTemplate() {} unsigned int Decrypt(const byte *cipherText, byte *plainText); protected: DecryptorTemplate() {} }; //! . template class EncryptorTemplate : public PK_FixedLengthEncryptor, public CryptoSystemBaseTemplate { public: ~EncryptorTemplate() {} void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText); protected: EncryptorTemplate() {} }; // ******************************************************** //! . class DigestSignatureSystem { public: virtual ~DigestSignatureSystem() {}; virtual unsigned int MaxDigestLength() const =0; virtual unsigned int DigestSignatureLength() const =0; }; //! . class DigestSigner : public virtual DigestSignatureSystem { public: virtual void SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLen, byte *signature) const =0; }; //! . class DigestVerifier : public virtual DigestSignatureSystem { public: virtual bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const =0; }; //! . template class DigestSignatureSystemBaseTemplate : virtual public DigestSignatureSystem, virtual public PublicKeyBaseTemplate { public: unsigned int MaxDigestLength() const {return pad.MaxUnpaddedLength(PaddedBlockBitLength());} unsigned int DigestSignatureLength() const {return f.MaxPreimage().ByteCount();} P pad; protected: DigestSignatureSystemBaseTemplate() {} unsigned int PaddedBlockBitLength() const {return f.ImageBound().BitCount()-1;} }; //! . template class DigestSignerTemplate : public DigestSigner, public DigestSignatureSystemBaseTemplate { public: ~DigestSignerTemplate() {} void SignDigest(RandomNumberGenerator &rng, const byte *message, unsigned int messageLength, byte *signature) const; protected: DigestSignerTemplate() {} }; //! . template class DigestVerifierTemplate : public DigestVerifier, public DigestSignatureSystemBaseTemplate { public: ~DigestVerifierTemplate() {} bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const; protected: DigestVerifierTemplate() {} }; // ******************************************************** //! . template class SignatureSystemBaseTemplate : virtual public PK_SignatureSystem, virtual public S { public: unsigned int SignatureLength() const {return DigestSignatureLength();} HashModule * NewMessageAccumulator() const {return new H;} protected: SignatureSystemBaseTemplate() : S(*(S*)0) {} }; //! . template class SignerTemplate : virtual public PK_Signer, public SignatureSystemBaseTemplate { public: ~SignerTemplate() {} void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const; protected: SignerTemplate() : S(*(S*)0) {} }; //! . template class VerifierTemplate : virtual public PK_Verifier, public SignatureSystemBaseTemplate { public: ~VerifierTemplate() {} bool Verify(HashModule *messageAccumulator, const byte *sig) const; protected: VerifierTemplate() : S(*(S*)0) {} }; template void SignerTemplate::Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const { std::auto_ptr ma(messageAccumulator); if (ma->DigestSize() > MaxDigestLength()) throw KeyTooShort(); SecByteBlock digest(ma->DigestSize()); ma->Final(digest); SignDigest(rng, digest, digest.size, signature); } template bool VerifierTemplate::Verify(HashModule *messageAccumulator, const byte *sig) const { std::auto_ptr ma(messageAccumulator); SecByteBlock digest(ma->DigestSize()); ma->Final(digest); return VerifyDigest(digest, digest.size, sig); } // ******************************************************** //! . class SignatureEncodingMethodWithRecovery : public HashModule { public: void Final(byte *digest) {} virtual void Encode(RandomNumberGenerator &rng, byte *representative) =0; virtual bool Verify(const byte *representative) =0; virtual unsigned int Decode(byte *message) =0; virtual unsigned int MaximumRecoverableLength() const =0; }; //! . template class SignatureSystemWithRecoveryBaseTemplate : virtual public PK_SignatureSystemWithRecovery, virtual public PublicKeyBaseTemplate { public: unsigned int SignatureLength() const {return f.MaxPreimage().ByteCount();} HashModule * NewMessageAccumulator() const {return new H(PaddedBlockBitLength());} unsigned int MaximumRecoverableLength() const {return H::MaximumRecoverableLength(PaddedBlockBitLength());} bool AllowLeftoverMessage() const {return H::AllowLeftoverMessage();} protected: unsigned int PaddedBlockBitLength() const {return f.ImageBound().BitCount()-1;} }; //! . template class SignerWithRecoveryTemplate : virtual public PK_SignerWithRecovery, public SignatureSystemWithRecoveryBaseTemplate { public: void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const; }; //! . template class VerifierWithRecoveryTemplate : virtual public PK_VerifierWithRecovery, public SignatureSystemWithRecoveryBaseTemplate { public: bool Verify(HashModule *messageAccumulator, const byte *sig) const; HashModule * NewLeftoverMessageAccumulator(const byte *signature) const; unsigned int PartialRecover(HashModule *leftoverMessageAccumulator, byte *recoveredMessage) const; unsigned int Recover(const byte *signature, byte *recoveredMessage) const; }; template void SignerWithRecoveryTemplate::Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const { std::auto_ptr ma(static_cast(messageAccumulator)); if (ma->MaximumRecoverableLength() == 0) throw KeyTooShort(); SecByteBlock representative(PaddedBlockByteLength()); ma->Encode(rng, representative); f.CalculateInverse(Integer(representative, representative.size)).Encode(signature, SignatureLength()); } template bool VerifierWithRecoveryTemplate::Verify(HashModule *messageAccumulator, const byte *signature) const { std::auto_ptr ma(static_cast(messageAccumulator)); SecByteBlock representative(PaddedBlockByteLength()); f.ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size); return ma->Verify(representative); } template HashModule * VerifierWithRecoveryTemplate::NewLeftoverMessageAccumulator(const byte *signature) const { SecByteBlock representative(PaddedBlockByteLength()); f.ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size); return new H(representative, PaddedBlockBitLength()); } template unsigned int VerifierWithRecoveryTemplate::PartialRecover(HashModule *messageAccumulator, byte *recoveredMessage) const { std::auto_ptr ma(static_cast(messageAccumulator)); return ma->Decode(recoveredMessage); } template unsigned int VerifierWithRecoveryTemplate::Recover(const byte *signature, byte *recoveredMessage) const { return PartialRecover(NewLeftoverMessageAccumulator(signature), recoveredMessage); } NAMESPACE_END #endif