00001 #ifndef CRYPTOPP_PUBKEY_H
00002 #define CRYPTOPP_PUBKEY_H
00003
00004 #include "integer.h"
00005 #include "filters.h"
00006 #include <memory>
00007 #include <assert.h>
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011 Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
00012 Integer DSA_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen);
00013
00014
00015
00017 class TrapdoorFunction
00018 {
00019 public:
00020 virtual ~TrapdoorFunction() {}
00021
00022 virtual Integer ApplyFunction(const Integer &x) const =0;
00023 virtual Integer PreimageBound() const =0;
00024 virtual Integer ImageBound() const =0;
00025 virtual Integer MaxPreimage() const {return --PreimageBound();}
00026 virtual Integer MaxImage() const {return --ImageBound();}
00027 };
00028
00030 class InvertibleTrapdoorFunction : virtual public TrapdoorFunction
00031 {
00032 public:
00033 virtual Integer CalculateInverse(const Integer &x) const =0;
00034 };
00035
00037 class PaddingScheme
00038 {
00039 public:
00040 virtual ~PaddingScheme() {}
00041
00042 virtual unsigned int MaxUnpaddedLength(unsigned int paddedLength) const =0;
00043
00044 virtual void Pad(RandomNumberGenerator &rng, const byte *raw, unsigned int inputLength, byte *padded, unsigned int paddedLength) const =0;
00045
00046 virtual unsigned int Unpad(const byte *padded, unsigned int paddedLength, byte *raw) const =0;
00047 };
00048
00049
00050
00052 template <class H>
00053 class P1363_MGF1
00054 {
00055 public:
00056 static void GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength);
00057 };
00058
00059 template <class H>
00060 void P1363_MGF1<H>::GenerateAndMask(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength)
00061 {
00062 H h;
00063 ArrayXorSink *sink;
00064 HashFilter filter(h, sink = new ArrayXorSink(output, outputLength));
00065 word32 counter = 0;
00066 while (sink->AvailableSize() > 0)
00067 {
00068 filter.Put(input, inputLength);
00069 filter.PutWord32(counter++);
00070 filter.MessageEnd();
00071 }
00072 }
00073
00074
00075
00077 template <class H>
00078 class P1363_KDF2
00079 {
00080 public:
00081 static void DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength);
00082 };
00083
00084 template <class H>
00085 void P1363_KDF2<H>::DeriveKey(byte *output, unsigned int outputLength, const byte *input, unsigned int inputLength)
00086 {
00087 H h;
00088 ArraySink *sink;
00089 HashFilter filter(h, sink = new ArraySink(output, outputLength));
00090 word32 counter = 1;
00091 while (sink->AvailableSize() > 0)
00092 {
00093 filter.Put(input, inputLength);
00094 filter.PutWord32(counter++);
00095 filter.MessageEnd();
00096 }
00097 }
00098
00099
00100
00102 template <class F>
00103 class PublicKeyBaseTemplate
00104 {
00105 public:
00106 PublicKeyBaseTemplate(const F &f) : f(f) {}
00107 PublicKeyBaseTemplate(BufferedTransformation &bt) : f(bt) {}
00108 void DEREncode(BufferedTransformation &bt) const {f.DEREncode(bt);}
00109
00110 const F & GetTrapdoorFunction() const {return f;}
00111
00112 protected:
00113
00114 PublicKeyBaseTemplate() : f(*(F*)0) {assert(false);}
00115 virtual unsigned int PaddedBlockBitLength() const =0;
00116 unsigned int PaddedBlockByteLength() const {return bitsToBytes(PaddedBlockBitLength());}
00117
00118 F f;
00119 };
00120
00121
00122
00124 template <class P, class F>
00125 class CryptoSystemBaseTemplate : virtual public PK_FixedLengthCryptoSystem, virtual public PublicKeyBaseTemplate<F>
00126 {
00127 public:
00128 unsigned int MaxPlainTextLength() const {return pad.MaxUnpaddedLength(PaddedBlockBitLength());}
00129 unsigned int CipherTextLength() const {return f.MaxImage().ByteCount();}
00130
00131 P pad;
00132
00133 protected:
00134 CryptoSystemBaseTemplate() {}
00135 unsigned int PaddedBlockBitLength() const {return f.PreimageBound().BitCount()-1;}
00136 };
00137
00139 template <class P, class F>
00140 class DecryptorTemplate : public PK_FixedLengthDecryptor, public CryptoSystemBaseTemplate<P, F>
00141 {
00142 public:
00143 ~DecryptorTemplate() {}
00144 unsigned int Decrypt(const byte *cipherText, byte *plainText);
00145
00146 protected:
00147 DecryptorTemplate() {}
00148 };
00149
00151 template <class P, class T>
00152 class EncryptorTemplate : public PK_FixedLengthEncryptor, public CryptoSystemBaseTemplate<P, T>
00153 {
00154 public:
00155 ~EncryptorTemplate() {}
00156 void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText);
00157
00158 protected:
00159 EncryptorTemplate() {}
00160 };
00161
00162
00163
00165 class DigestSignatureSystem
00166 {
00167 public:
00168 virtual ~DigestSignatureSystem() {};
00169 virtual unsigned int MaxDigestLength() const =0;
00170 virtual unsigned int DigestSignatureLength() const =0;
00171 };
00172
00174 class DigestSigner : public virtual DigestSignatureSystem
00175 {
00176 public:
00177 virtual void SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLen, byte *signature) const =0;
00178 };
00179
00181 class DigestVerifier : public virtual DigestSignatureSystem
00182 {
00183 public:
00184 virtual bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const =0;
00185 };
00186
00188 template <class P, class T>
00189 class DigestSignatureSystemBaseTemplate : virtual public DigestSignatureSystem, virtual public PublicKeyBaseTemplate<T>
00190 {
00191 public:
00192 unsigned int MaxDigestLength() const {return pad.MaxUnpaddedLength(PaddedBlockBitLength());}
00193 unsigned int DigestSignatureLength() const {return f.MaxPreimage().ByteCount();}
00194
00195 P pad;
00196
00197 protected:
00198 DigestSignatureSystemBaseTemplate() {}
00199 unsigned int PaddedBlockBitLength() const {return f.ImageBound().BitCount()-1;}
00200 };
00201
00203 template <class P, class T>
00204 class DigestSignerTemplate : public DigestSigner, public DigestSignatureSystemBaseTemplate<P, T>
00205 {
00206 public:
00207 ~DigestSignerTemplate() {}
00208 void SignDigest(RandomNumberGenerator &rng, const byte *message, unsigned int messageLength, byte *signature) const;
00209
00210 protected:
00211 DigestSignerTemplate() {}
00212 };
00213
00215 template <class P, class T>
00216 class DigestVerifierTemplate : public DigestVerifier, public DigestSignatureSystemBaseTemplate<P, T>
00217 {
00218 public:
00219 ~DigestVerifierTemplate() {}
00220 bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *sig) const;
00221
00222 protected:
00223 DigestVerifierTemplate() {}
00224 };
00225
00226
00227
00229 template <class S, class H>
00230 class SignatureSystemBaseTemplate : virtual public PK_SignatureSystem, virtual public S
00231 {
00232 public:
00233 unsigned int SignatureLength() const {return DigestSignatureLength();}
00234 HashModule * NewMessageAccumulator() const {return new H;}
00235
00236 protected:
00237 SignatureSystemBaseTemplate() : S(*(S*)0) {}
00238 };
00239
00241 template <class S, class H>
00242 class SignerTemplate : virtual public PK_Signer, public SignatureSystemBaseTemplate<S, H>
00243 {
00244 public:
00245 ~SignerTemplate() {}
00246 void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const;
00247
00248 protected:
00249 SignerTemplate() : S(*(S*)0) {}
00250 };
00251
00253 template <class S, class H>
00254 class VerifierTemplate : virtual public PK_Verifier, public SignatureSystemBaseTemplate<S, H>
00255 {
00256 public:
00257 ~VerifierTemplate() {}
00258 bool Verify(HashModule *messageAccumulator, const byte *sig) const;
00259
00260 protected:
00261 VerifierTemplate() : S(*(S*)0) {}
00262 };
00263
00264 template <class S, class H>
00265 void SignerTemplate<S,H>::Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const
00266 {
00267 std::auto_ptr<HashModule> ma(messageAccumulator);
00268 if (ma->DigestSize() > MaxDigestLength())
00269 throw KeyTooShort();
00270 SecByteBlock digest(ma->DigestSize());
00271 ma->Final(digest);
00272 SignDigest(rng, digest, digest.size, signature);
00273 }
00274
00275 template <class S, class H>
00276 bool VerifierTemplate<S,H>::Verify(HashModule *messageAccumulator, const byte *sig) const
00277 {
00278 std::auto_ptr<HashModule> ma(messageAccumulator);
00279 SecByteBlock digest(ma->DigestSize());
00280 ma->Final(digest);
00281 return VerifyDigest(digest, digest.size, sig);
00282 }
00283
00284
00285
00287 class SignatureEncodingMethodWithRecovery : public HashModule
00288 {
00289 public:
00290 void Final(byte *digest) {}
00291 virtual void Encode(RandomNumberGenerator &rng, byte *representative) =0;
00292 virtual bool Verify(const byte *representative) =0;
00293 virtual unsigned int Decode(byte *message) =0;
00294 virtual unsigned int MaximumRecoverableLength() const =0;
00295 };
00296
00298 template <class F, class H>
00299 class SignatureSystemWithRecoveryBaseTemplate : virtual public PK_SignatureSystemWithRecovery, virtual public PublicKeyBaseTemplate<F>
00300 {
00301 public:
00302 unsigned int SignatureLength() const {return f.MaxPreimage().ByteCount();}
00303 HashModule * NewMessageAccumulator() const {return new H(PaddedBlockBitLength());}
00304 unsigned int MaximumRecoverableLength() const {return H::MaximumRecoverableLength(PaddedBlockBitLength());}
00305 bool AllowLeftoverMessage() const {return H::AllowLeftoverMessage();}
00306
00307 protected:
00308 unsigned int PaddedBlockBitLength() const {return f.ImageBound().BitCount()-1;}
00309 };
00310
00312 template <class F, class H>
00313 class SignerWithRecoveryTemplate : virtual public PK_SignerWithRecovery, public SignatureSystemWithRecoveryBaseTemplate<F, H>
00314 {
00315 public:
00316 void Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const;
00317 };
00318
00320 template <class F, class H>
00321 class VerifierWithRecoveryTemplate : virtual public PK_VerifierWithRecovery, public SignatureSystemWithRecoveryBaseTemplate<F, H>
00322 {
00323 public:
00324 bool Verify(HashModule *messageAccumulator, const byte *sig) const;
00325 HashModule * NewLeftoverMessageAccumulator(const byte *signature) const;
00326 unsigned int PartialRecover(HashModule *leftoverMessageAccumulator, byte *recoveredMessage) const;
00327 unsigned int Recover(const byte *signature, byte *recoveredMessage) const;
00328 };
00329
00330 template <class F, class H>
00331 void SignerWithRecoveryTemplate<F,H>::Sign(RandomNumberGenerator &rng, HashModule *messageAccumulator, byte *signature) const
00332 {
00333 std::auto_ptr<H> ma(static_cast<H*>(messageAccumulator));
00334 if (ma->MaximumRecoverableLength() == 0)
00335 throw KeyTooShort();
00336 SecByteBlock representative(PaddedBlockByteLength());
00337 ma->Encode(rng, representative);
00338 f.CalculateInverse(Integer(representative, representative.size)).Encode(signature, SignatureLength());
00339 }
00340
00341 template <class F, class H>
00342 bool VerifierWithRecoveryTemplate<F,H>::Verify(HashModule *messageAccumulator, const byte *signature) const
00343 {
00344 std::auto_ptr<H> ma(static_cast<H*>(messageAccumulator));
00345 SecByteBlock representative(PaddedBlockByteLength());
00346 f.ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size);
00347 return ma->Verify(representative);
00348 }
00349
00350 template <class F, class H>
00351 HashModule * VerifierWithRecoveryTemplate<F,H>::NewLeftoverMessageAccumulator(const byte *signature) const
00352 {
00353 SecByteBlock representative(PaddedBlockByteLength());
00354 f.ApplyFunction(Integer(signature, SignatureLength())).Encode(representative, representative.size);
00355 return new H(representative, PaddedBlockBitLength());
00356 }
00357
00358 template <class F, class H>
00359 unsigned int VerifierWithRecoveryTemplate<F,H>::PartialRecover(HashModule *messageAccumulator, byte *recoveredMessage) const
00360 {
00361 std::auto_ptr<H> ma(static_cast<H*>(messageAccumulator));
00362 return ma->Decode(recoveredMessage);
00363 }
00364
00365 template <class F, class H>
00366 unsigned int VerifierWithRecoveryTemplate<F,H>::Recover(const byte *signature, byte *recoveredMessage) const
00367 {
00368 return PartialRecover(NewLeftoverMessageAccumulator(signature), recoveredMessage);
00369 }
00370
00371 NAMESPACE_END
00372
00373 #endif