Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

eccrypto.h

Go to the documentation of this file.
00001 #ifndef CRYPTOPP_ECCRYPTO_H
00002 #define CRYPTOPP_ECCRTPTO_H
00003 
00027 #include "pubkey.h"
00028 #include "integer.h"
00029 #include "asn.h"
00030 #include "hmac.h"
00031 #include "sha.h"
00032 
00033 NAMESPACE_BEGIN(CryptoPP)
00034 
00038 enum ECSignatureScheme
00039 {
00040         ECNR,   
00041         ECDSA   
00042 };
00043 
00044 template <class T> class EcPrecomputation;
00045 
00047 
00050 template <class EC>
00051 class ECParameters : virtual public PK_Precomputation
00052 {
00053 public:
00054         typedef typename EC::Point Point;
00055 
00056         ECParameters() : m_compress(false), m_encodeAsOID(false) {}
00057         ECParameters(const OID &oid)
00058                 : m_compress(false), m_encodeAsOID(false) {LoadRecommendedParameters(oid);}
00059         ECParameters(const EC &ec, const Point &G, const Integer &n)
00060                 : m_ec(ec), m_G(G), m_Gpc(*m_ec, G), m_n(n), m_cofactorPresent(false), m_compress(false), m_encodeAsOID(false) {}
00061         ECParameters(const EC &ec, const Point &G, const Integer &n, const Integer &k)
00062                 : m_ec(ec), m_G(G), m_Gpc(*m_ec, G), m_n(n), m_cofactorPresent(true), m_compress(false), m_encodeAsOID(false), m_k(k) {}
00063         ECParameters(BufferedTransformation &bt)
00064                 : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);}
00065 
00066         // enumerate OIDs for recommended parameters, use OID() to get first one
00067         static OID GetNextRecommendedParametersOID(const OID &oid);
00068         void LoadRecommendedParameters(const OID &oid);
00069 
00070         void BERDecode(BufferedTransformation &bt);
00071         void DEREncode(BufferedTransformation &bt) const;
00072 
00073         bool ValidateParameters(RandomNumberGenerator &rng) const;
00074 
00075         void Precompute(unsigned int precomputationStorage=16);
00076         void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
00077         void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
00078 
00079         void SetPointCompression(bool compress) {m_compress = compress;}
00080         bool GetPointCompression() const {return m_compress;}
00081 
00082         void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;}
00083         bool GetEncodeAsOID() const {return m_encodeAsOID;}
00084 
00085         const EC& GetCurve() const {return *m_ec;}
00086         const Point& GetBasePoint() const {return m_G;}
00087         const Integer& GetBasePointOrder() const {return m_n;}
00088         const bool CofactorPresent() const {return m_cofactorPresent;}
00089         const Integer& GetCofactor() const {return m_k;}
00090 
00091 protected:
00092         unsigned int EncodedPointSize() const {return m_ec->EncodedPointSize(m_compress);}
00093         void EncodePoint(byte *encodedPoint, const Point &P) const {m_ec->EncodePoint(encodedPoint, P, m_compress);}
00094         unsigned int FieldElementLength() const {return m_ec->GetField().MaxElementByteLength();}
00095         unsigned int ExponentLength() const {return m_n.ByteCount();}
00096         unsigned int ExponentBitLength() const {return m_n.BitCount();}
00097 
00098         OID m_oid;                      // set if parameters loaded from a recommended curve
00099         value_ptr<EC> m_ec;     // field and curve
00100         Point m_G;                      // base
00101         EcPrecomputation<EC> m_Gpc;     // precomputed table for base
00102         Integer m_n;            // order of base point
00103         bool m_cofactorPresent, m_compress, m_encodeAsOID;
00104         Integer m_k;            // cofactor
00105 };
00106 
00107 #define EC_PARAMETERS_CONSTRUCTORS(Self, Base)                                                          \
00108         Self(const ECParameters<EC> &params)                                                                    \
00109                 : Base(params) {}                                                                                                       \
00110         Self(const OID &oid)                                                                                                    \
00111                 : Base(oid) {}                                                                                                          \
00112         Self(const EC &ec, const Point &G, const Integer &n, const Integer &k)  \
00113                 : Base(ec, G, n, k) {}                                                                                          \
00114         Self(BufferedTransformation &bt)                                                                                \
00115                 : Base(bt) {}
00116 
00118 template <class EC>
00119 class ECDHC : public ECParameters<EC>, public PK_WithPrecomputation<PK_SimpleKeyAgreementDomain>
00120 {
00121 public:
00122         typedef typename EC::Point Point;
00123 
00124         EC_PARAMETERS_CONSTRUCTORS(ECDHC, ECParameters<EC>)
00125 
00126         bool ValidateDomainParameters(RandomNumberGenerator &rng) const
00127                 {return ValidateParameters(rng);}
00128         unsigned int AgreedValueLength() const {return FieldElementLength();}
00129         unsigned int PrivateKeyLength() const {return ExponentLength();}
00130         unsigned int PublicKeyLength() const {return EncodedPointSize();}
00131 
00132         void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
00133         bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const;
00134 };
00135 
00137 template <class EC>
00138 class ECMQVC : public ECParameters<EC>, public PK_WithPrecomputation<PK_AuthenticatedKeyAgreementDomain>
00139 {
00140 public:
00141         typedef typename EC::Point Point;
00142         
00143         EC_PARAMETERS_CONSTRUCTORS(ECMQVC, ECParameters<EC>)
00144 
00145         bool ValidateDomainParameters(RandomNumberGenerator &rng) const
00146                 {return ValidateParameters(rng);}
00147         unsigned int AgreedValueLength() const {return FieldElementLength();}
00148 
00149         unsigned int StaticPrivateKeyLength() const {return ExponentLength();}
00150         unsigned int StaticPublicKeyLength() const {return EncodedPointSize();}
00151         void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
00152 
00153         unsigned int EphemeralPrivateKeyLength() const {return ExponentLength()+EncodedPointSize();}
00154         unsigned int EphemeralPublicKeyLength() const {return EncodedPointSize();}
00155         void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
00156 
00157         bool Agree(byte *agreedValue,
00158                 const byte *staticPrivateKey, const byte *ephemeralPrivateKey, 
00159                 const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
00160                 bool validateStaticOtherPublicKey=true) const;
00161 };
00162 
00164 template <class EC>
00165 class ECPublicKey : public ECParameters<EC>, virtual public PK_Precomputation
00166 {
00167 public:
00168         typedef typename EC::Point Point;
00169         
00170         ECPublicKey(const ECParameters<EC> &params, const Point &Q)
00171                 : ECParameters<EC>(params), m_Q(Q), m_Qpc(GetCurve(), m_Q) {}
00172         ECPublicKey(const OID &oidParams, const Point &Q)
00173                 : ECParameters<EC>(oidParams), m_Q(Q), m_Qpc(GetCurve(), m_Q) {}
00174         ECPublicKey(const EC &ec, const Point &G, const Integer &n, const Point &Q)
00175                 : ECParameters<EC>(ec, G, n), m_Q(Q), m_Qpc(ec, m_Q) {}
00176         // construct from a SubjectPublicKeyInfo sequence
00177         ECPublicKey(BufferedTransformation &bt);
00178 
00179         // encode to a SubjectPublicKeyInfo sequence
00180         void DEREncode(BufferedTransformation &bt) const;
00181 
00182         void Precompute(unsigned int precomputationStorage=16);
00183         void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
00184         void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
00185 
00186         const Point& GetPublicPoint() const {return m_Q;}
00187 
00188 protected:
00189         ECPublicKey() {}
00190         Integer EncodeDigest(ECSignatureScheme ss, const byte *digest, unsigned int digestLen) const;
00191 
00192         Point m_Q;
00193         EcPrecomputation<EC> m_Qpc;
00194 };
00195 
00196 #define EC_PUBLIC_KEY_CONSTRUCTORS(Self, Base)                                                          \
00197         Self(const ECPublicKey<EC> &key)                                                                                \
00198                 : Base(key) {}                                                                                                          \
00199         Self(const ECParameters<EC> &params, const Point &Q)                                    \
00200                 : Base(params, Q) {}                                                                                            \
00201         Self(const OID &oid, const Point &Q)                                                                    \
00202                 : Base(oid, Q) {}                                                                                                       \
00203         Self(const EC &ec, const Point &G, const Integer &n, const Point &Q)    \
00204                 : Base(ec, G, n, Q) {}                                                                                          \
00205         Self(BufferedTransformation &bt)                                                                                \
00206                 : Base(bt) {}
00207                 
00209 template <class EC>
00210 class ECPrivateKey : public ECPublicKey<EC>
00211 {
00212 public:
00213         typedef typename EC::Point Point;
00214 
00215         ECPrivateKey(const ECParameters<EC> &params, const Point &Q, const Integer &d)
00216                 : ECPublicKey<EC>(params, Q), m_d(d) {}
00217         ECPrivateKey(const OID &oid, const Point &Q, const Integer &d)
00218                 : ECPublicKey<EC>(oid, Q), m_d(d) {}
00219         ECPrivateKey(const EC &ec, const Point &G, const Integer &n, const Point &Q, const Integer &d)
00220                 : ECPublicKey<EC>(ec, G, n, Q), m_d(d) {}
00221         // generate a random private key
00222         ECPrivateKey(RandomNumberGenerator &rng, const ECParameters<EC> &params)
00223                 : ECPublicKey<EC>(params, Point()) {Randomize(rng);}
00224         ECPrivateKey(RandomNumberGenerator &rng, const OID &oid)
00225                 : ECPublicKey<EC>(oid, Point()) {Randomize(rng);}
00226         ECPrivateKey(RandomNumberGenerator &rng, const EC &ec, const Point &G, const Integer &n)
00227                 : ECPublicKey<EC>(ec, G, n, Point()) {Randomize(rng);}
00228         // decode private key
00229         ECPrivateKey(BufferedTransformation &bt);
00230 
00231         void DEREncode(BufferedTransformation &bt) const;
00232 
00233         const Integer& GetPrivateExponent() const {return m_d;}
00234 
00235 protected:
00236         typedef typename EC::FieldElement FieldElement;
00237         void Randomize(RandomNumberGenerator &rng);
00238         void RawDecode(BERSequenceDecoder &bt, bool needParameters);
00239 
00240         Integer m_d;
00241 };
00242 
00243 #define EC_PRIVATE_KEY_CONSTRUCTORS(Self, Base)                                                         \
00244         Self(const ECPrivateKey<EC> &key)                                                                               \
00245                 : Base(key) {}                                                                                                          \
00246         Self(const ECParameters<EC> &params, const Point &Q, const Integer &d)  \
00247                 : Base(params, Q, d) {}                                                                                         \
00248         Self(const OID& oid, const Point &Q, const Integer &d)                                  \
00249                 : Base(oid, Q, d) {}                                                                                            \
00250         Self(const EC &ec, const Point &G, const Integer &n, const Point &Q, const Integer &d)  \
00251                 : Base(ec, G, n, Q, d) {}                                                                                       \
00252         Self(RandomNumberGenerator &rng, const ECParameters<EC> &params)                \
00253                 : Base(rng, params) {}                                                                                          \
00254         Self(RandomNumberGenerator &rng, const OID& oid)                                                \
00255                 : Base(rng, oid) {}                                                                                                     \
00256         Self(RandomNumberGenerator &rng, const EC &ec, const Point &G, const Integer &n)        \
00257                 : Base(rng, ec, G, n) {}                                                                                        \
00258         Self(BufferedTransformation &bt)                                                                                \
00259                 : Base(bt) {}
00260 
00262 template <class EC, ECSignatureScheme SS = ECNR>
00263 class ECDigestVerifier : public ECPublicKey<EC>, public PK_WithPrecomputation<DigestVerifier>
00264 {
00265 public:
00266         typedef typename EC::Point Point;
00267 
00268         EC_PUBLIC_KEY_CONSTRUCTORS(ECDigestVerifier, ECPublicKey<EC>)
00269         
00270         bool VerifyDigest(const byte *digest, unsigned int digestLen, const byte *signature) const;
00271 
00272         unsigned int MaxDigestLength() const {return 0xffff;}
00273         unsigned int DigestSignatureLength() const {return 2*ExponentLength();}
00274 
00275         // exposed for validation testing
00276         bool RawVerify(const Integer &e, const Integer &n, const Integer &s) const;
00277 };
00278 
00280 template <class EC, ECSignatureScheme SS = ECNR>
00281 class ECDigestSigner : public ECPrivateKey<EC>, public PK_WithPrecomputation<DigestSigner>
00282 {
00283 public:
00284         typedef typename EC::Point Point;
00285 
00286         EC_PRIVATE_KEY_CONSTRUCTORS(ECDigestSigner, ECPrivateKey<EC>)
00287 
00288         void SignDigest(RandomNumberGenerator &, const byte *digest, unsigned int digestLen, byte *signature) const;
00289 
00290         unsigned int MaxDigestLength() const {return 0xffff;}
00291         unsigned int DigestSignatureLength() const {return 2*ExponentLength();}
00292 
00294         void RawSign(const Integer &k, const Integer &e, Integer &n, Integer &s) const;
00295 };
00296 
00298 template <class EC, class H, ECSignatureScheme SS = ECNR>
00299 class ECSigner : public SignerTemplate<ECDigestSigner<EC, SS>, H>, public PK_WithPrecomputation<PK_Signer>
00300 {
00301         typedef ECDigestSigner<EC, SS> Base;
00302 public:
00303         typedef typename EC::Point Point;
00304 
00305         EC_PRIVATE_KEY_CONSTRUCTORS(ECSigner, Base)
00306 };
00307 
00309 template <class EC, class H, ECSignatureScheme SS = ECNR>
00310 class ECVerifier : public VerifierTemplate<ECDigestVerifier<EC, SS>, H>, public PK_WithPrecomputation<PK_Verifier>
00311 {
00312         typedef ECDigestVerifier<EC, SS> Base;
00313 public:
00314         typedef typename EC::Point Point;
00315         
00316         EC_PUBLIC_KEY_CONSTRUCTORS(ECVerifier, Base)
00317 };
00318 
00320 template <class EC, class MAC = HMAC<SHA>, class KDF = P1363_KDF2<SHA> >
00321 class ECEncryptor : public ECPublicKey<EC>, public PK_WithPrecomputation<PK_Encryptor>
00322 {
00323 public:
00324         typedef typename EC::Point Point;
00325         
00326         EC_PUBLIC_KEY_CONSTRUCTORS(ECEncryptor, ECPublicKey<EC>)
00327 
00328         unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const
00329                 {return cipherTextLength < CipherTextLength(0) ? 0 : cipherTextLength - CipherTextLength(0);}
00330         unsigned int CipherTextLength(unsigned int plainTextLength) const
00331                 {return plainTextLength + MAC::DIGESTSIZE + EncodedPointSize();}
00332 
00333         void Encrypt(RandomNumberGenerator &rng, const byte *plainText, unsigned int plainTextLength, byte *cipherText)
00334         {
00335                 Integer x(rng, 1, m_n-1);
00336                 Point Q = m_Gpc.Multiply(x);
00337 
00338                 EncodePoint(cipherText, Q);
00339                 cipherText += EncodedPointSize();
00340 
00341                 SecByteBlock agreedSecret(FieldElementLength());
00342                 Point Q1 = m_Qpc.Multiply(x);
00343                 Q1.x.Encode(agreedSecret, agreedSecret.size);
00344 
00345                 SecByteBlock derivedKey(plainTextLength + MAC::DEFAULT_KEYLENGTH);
00346                 KDF::DeriveKey(derivedKey, derivedKey.size, agreedSecret, agreedSecret.size);
00347                 xorbuf(cipherText, plainText, derivedKey, plainTextLength);
00348 
00349                 MAC mac(derivedKey + plainTextLength);
00350                 mac.CalculateDigest(cipherText + plainTextLength, cipherText, plainTextLength);
00351         }
00352 };
00353 
00355 template <class EC, class MAC = HMAC<SHA>, class KDF = P1363_KDF2<SHA> >
00356 class ECDecryptor : public ECPrivateKey<EC>, public PK_Decryptor
00357 {
00358 public:
00359         typedef typename EC::Point Point;
00360         
00361         EC_PRIVATE_KEY_CONSTRUCTORS(ECDecryptor, ECPrivateKey<EC>)
00362 
00363         unsigned int MaxPlainTextLength(unsigned int cipherTextLength) const
00364                 {return cipherTextLength < CipherTextLength(0) ? 0 : cipherTextLength - CipherTextLength(0);}
00365         unsigned int CipherTextLength(unsigned int plainTextLength) const
00366                 {return plainTextLength + MAC::DIGESTSIZE + EncodedPointSize();}
00367 
00368         unsigned int Decrypt(const byte *cipherText, unsigned int cipherTextLength, byte *plainText)
00369         {
00370                 Point Q;
00371                 if (!GetCurve().DecodePoint(Q, cipherText, EncodedPointSize()) || !GetCurve().VerifyPoint(Q) || Q.identity)
00372                         return 0;
00373                 cipherText += EncodedPointSize();
00374 
00375                 const Integer e[2] = {m_n, m_d};
00376                 Point R[2];
00377                 GetCurve().SimultaneousMultiply(R, Q, e, 2);
00378 
00379                 if (!R[0].identity || R[1].identity)
00380                         return 0;
00381 
00382                 SecByteBlock agreedSecret(FieldElementLength());
00383                 R[1].x.Encode(agreedSecret, agreedSecret.size);
00384 
00385                 unsigned int plainTextLength = MaxPlainTextLength(cipherTextLength);
00386                 SecByteBlock derivedKey(plainTextLength + MAC::DEFAULT_KEYLENGTH);
00387                 KDF::DeriveKey(derivedKey, derivedKey.size, agreedSecret, agreedSecret.size);
00388                 
00389                 MAC mac(derivedKey + plainTextLength);
00390                 if (!mac.VerifyDigest(cipherText + plainTextLength, cipherText, plainTextLength))
00391                         return 0;
00392 
00393                 xorbuf(plainText, cipherText, derivedKey, plainTextLength);
00394                 return plainTextLength;
00395         }
00396 };
00397 
00398 NAMESPACE_END
00399 
00400 #endif

Generated at Mon Jan 15 01:16:31 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000