Security Scol plugin
gfpcrypt.h
Go to the documentation of this file.
1// gfpcrypt.h - originally written and placed in the public domain by Wei Dai
2// RFC6979 deterministic signatures added by Douglas Roark
3// ECGDSA added by Jeffrey Walton
4
7
8#ifndef CRYPTOPP_GFPCRYPT_H
9#define CRYPTOPP_GFPCRYPT_H
10
11#include "config.h"
12
13#if CRYPTOPP_MSC_VERSION
14# pragma warning(push)
15# pragma warning(disable: 4189 4231 4275)
16#endif
17
18#include "cryptlib.h"
19#include "pubkey.h"
20#include "integer.h"
21#include "modexppc.h"
22#include "algparam.h"
23#include "smartptr.h"
24#include "sha.h"
25#include "asn.h"
26#include "hmac.h"
27#include "misc.h"
28
29NAMESPACE_BEGIN(CryptoPP)
30
31CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
32
34class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
35{
37
38public:
40
44 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
45
52 void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
53 {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
54
58 void Initialize(const Integer &p, const Integer &g)
59 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
60
65 void Initialize(const Integer &p, const Integer &q, const Integer &g)
66 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
67
68 // ASN1Object interface
70 void DEREncode(BufferedTransformation &bt) const;
71
79 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
80
91 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
92
95 void AssignFrom(const NameValuePairs &source);
96
97 // DL_GroupParameters
98 const Integer & GetSubgroupOrder() const {return m_q;}
99 Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
100 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
101 bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
102
105 bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
106
116 void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
117
124 unsigned int GetEncodedElementSize(bool reversible) const;
125
133 Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
134
139 Integer ConvertElementToInteger(const Element &element) const
140 {return element;}
141
144 Integer GetMaxExponent() const;
145
148 OID GetAlgorithmID() const;
149
152 virtual const Integer & GetModulus() const =0;
153
157 virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
158
162 {m_q = q; ParametersChanged();}
163
164 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
165
166protected:
167 Integer ComputeGroupOrder(const Integer &modulus) const
168 {return modulus-(GetFieldType() == 1 ? 1 : -1);}
169
170 // GF(p) = 1, GF(p^2) = 2
171 virtual int GetFieldType() const =0;
172 virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
173
174private:
175 Integer m_q;
176};
177
181template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element> >
182class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
183{
185
186public:
187 typedef typename GROUP_PRECOMP::Element Element;
188
190
191 // GeneratibleCryptoMaterial interface
192 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
193 {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
194
195 void AssignFrom(const NameValuePairs &source)
196 {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
197
198 // DL_GroupParameters
199 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
201
202 // IntegerGroupParameters
205 const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
206
209 const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
210
211 void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together
212 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
213
214 // non-inherited
216 {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
218 {return !operator==(rhs);}
219};
220
222
224class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
225{
226public:
227 virtual ~DL_GroupParameters_GFP() {}
228
235 bool IsIdentity(const Integer &element) const {return element == Integer::One();}
236
248 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
249
260 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
261 {
262 return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
263 }
264
265 // used by MQV
266 Element MultiplyElements(const Element &a, const Element &b) const;
267 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
268
269protected:
270 int GetFieldType() const {return 1;}
271};
272
275{
276public:
278
280
281protected:
282 unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
283};
284
292{
293public:
295
296 virtual ~DL_GroupParameters_ElGamal() {}
297
299 {
300 return GetSubgroupOrder()-1;
301 }
302};
303
307template <class T>
309{
310public:
311 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
312
313 virtual ~DL_Algorithm_GDSA() {}
314
315 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
316 {
317 const Integer &q = params.GetSubgroupOrder();
318 r %= q;
319 Integer kInv = k.InverseMod(q);
320 s = (kInv * (x*r + e)) % q;
321 CRYPTOPP_ASSERT(!!r && !!s);
322 }
323
324 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
325 {
326 const Integer &q = params.GetSubgroupOrder();
327 if (r>=q || r<1 || s>=q || s<1)
328 return false;
329
330 Integer w = s.InverseMod(q);
331 Integer u1 = (e * w) % q;
332 Integer u2 = (r * w) % q;
333 // verify r == (g^u1 * y^u2 mod p) mod q
334 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
335 }
336};
337
345template <class T, class H>
347{
348public:
349 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
350
351 virtual ~DL_Algorithm_DSA_RFC6979() {}
352
353 bool IsProbabilistic() const
354 {return false;}
355 bool IsDeterministic() const
356 {return true;}
357
358 // Deterministic K
359 Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
360 {
361 static const byte zero = 0, one = 1;
362 const size_t qlen = q.BitCount();
363 const size_t rlen = BitsToBytes(qlen);
364
365 // Step (a) - formatted E(m)
366 SecByteBlock BH(e.MinEncodedSize());
367 e.Encode(BH, BH.size());
368 BH = bits2octets(BH, q);
369
370 // Step (a) - private key to byte array
371 SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize()));
372 x.Encode(BX, BX.size());
373
374 // Step (b)
375 SecByteBlock V(H::DIGESTSIZE);
376 std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one);
377
378 // Step (c)
379 SecByteBlock K(H::DIGESTSIZE);
380 std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero);
381
382 // Step (d)
383 m_hmac.SetKey(K, K.size());
384 m_hmac.Update(V, V.size());
385 m_hmac.Update(&zero, 1);
386 m_hmac.Update(BX, BX.size());
387 m_hmac.Update(BH, BH.size());
388 m_hmac.TruncatedFinal(K, K.size());
389
390 // Step (e)
391 m_hmac.SetKey(K, K.size());
392 m_hmac.Update(V, V.size());
393 m_hmac.TruncatedFinal(V, V.size());
394
395 // Step (f)
396 m_hmac.SetKey(K, K.size());
397 m_hmac.Update(V, V.size());
398 m_hmac.Update(&one, 1);
399 m_hmac.Update(BX, BX.size());
400 m_hmac.Update(BH, BH.size());
401 m_hmac.TruncatedFinal(K, K.size());
402
403 // Step (g)
404 m_hmac.SetKey(K, K.size());
405 m_hmac.Update(V, V.size());
406 m_hmac.TruncatedFinal(V, V.size());
407
408 Integer k;
409 SecByteBlock temp(rlen);
410 for (;;)
411 {
412 // We want qlen bits, but we support only hash functions with an output length
413 // multiple of 8; hence, we will gather rlen bits, i.e., rolen octets.
414 size_t toff = 0;
415 while (toff < rlen)
416 {
417 m_hmac.Update(V, V.size());
418 m_hmac.TruncatedFinal(V, V.size());
419
420 size_t cc = STDMIN(V.size(), temp.size() - toff);
421 memcpy_s(temp+toff, temp.size() - toff, V, cc);
422 toff += cc;
423 }
424
425 k = bits2int(temp, qlen);
426 if (k > 0 && k < q)
427 break;
428
429 // k is not in the proper range; update K and V, and loop.
430 m_hmac.Update(V, V.size());
431 m_hmac.Update(&zero, 1);
432 m_hmac.TruncatedFinal(K, K.size());
433
434 m_hmac.SetKey(K, K.size());
435 m_hmac.Update(V, V.size());
436 m_hmac.TruncatedFinal(V, V.size());
437 }
438
439 return k;
440 }
441
442protected:
443
444 Integer bits2int(const SecByteBlock& bits, size_t qlen) const
445 {
446 Integer ret(bits, bits.size());
447 size_t blen = bits.size()*8;
448
449 if (blen > qlen)
450 ret >>= blen - qlen;
451
452 return ret;
453 }
454
455 // RFC 6979 support function. Takes an integer and converts it into bytes that
456 // are the same length as an elliptic curve's order.
457 SecByteBlock int2octets(const Integer& val, size_t rlen) const
458 {
459 SecByteBlock block(val.MinEncodedSize());
460 val.Encode(block, val.MinEncodedSize());
461
462 if (block.size() == rlen)
463 return block;
464
465 // The least significant bytes are the ones we need to preserve.
466 SecByteBlock t(rlen);
467 if (block.size() > rlen)
468 {
469 size_t offset = block.size() - rlen;
470 std::memcpy(t, block + offset, rlen);
471 }
472 else // block.size() < rlen
473 {
474 size_t offset = rlen - block.size();
475 memset(t, '\x00', offset);
476 std::memcpy(t + offset, block, rlen - offset);
477 }
478
479 return t;
480 }
481
482 // Turn a stream of bits into a set of bytes with the same length as an elliptic
483 // curve's order.
484 SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const
485 {
486 Integer b2 = bits2int(in, q.BitCount());
487 Integer b1 = b2 - q;
488 return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount());
489 }
490
491private:
492 mutable H m_hash;
493 mutable HMAC<H> m_hmac;
494};
495
504template <class T>
506{
507public:
508 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";}
509
510 virtual ~DL_Algorithm_GDSA_ISO15946() {}
511
512 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
513 {
514 const Integer &q = params.GetSubgroupOrder();
515 // r = x(k * G) mod q
516 r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q;
517 // s = (k * r - h(m)) * d_A mod q
518 s = (k * r - e) * x % q;
519 CRYPTOPP_ASSERT(!!r && !!s);
520 }
521
522 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
523 {
524 const Integer &q = params.GetSubgroupOrder();
525 if (r>=q || r<1 || s>=q || s<1)
526 return false;
527
528 const Integer& rInv = r.InverseMod(q);
529 const Integer u1 = (rInv * e) % q;
530 const Integer u2 = (rInv * s) % q;
531 // verify x(G^u1 + P_A^u2) mod q
532 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
533 }
534};
535
536CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
537CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA1>;
538CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA224>;
539CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA256>;
540CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA384>;
541CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA512>;
542
546template <class T>
548{
549public:
550 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";}
551
552 virtual ~DL_Algorithm_NR() {}
553
554 void Sign(const DL_GroupParameters<T> &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
555 {
556 const Integer &q = params.GetSubgroupOrder();
557 r = (r + e) % q;
558 s = (k - x*r) % q;
559 CRYPTOPP_ASSERT(!!r);
560 }
561
562 bool Verify(const DL_GroupParameters<T> &params, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
563 {
564 const Integer &q = params.GetSubgroupOrder();
565 if (r>=q || r<1 || s>=q)
566 return false;
567
568 // check r == (m_g^s * m_y^r + m) mod m_q
569 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
570 }
571};
572
576template <class GP>
578{
579public:
580 virtual ~DL_PublicKey_GFP() {}
581
586 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
587
592 void Initialize(const Integer &p, const Integer &g, const Integer &y)
593 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
594
600 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
601 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
602
603 // X509PublicKey
605 {this->SetPublicElement(Integer(bt));}
607 {this->GetPublicElement().DEREncode(bt);}
608};
609
612template <class GP>
614{
615public:
616 virtual ~DL_PrivateKey_GFP();
617
624 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
625 {this->GenerateRandomWithKeySize(rng, modulusBits);}
626
634 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
635 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
636
645 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
646 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
647
652 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
653
658 void Initialize(const Integer &p, const Integer &g, const Integer &x)
659 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
660
666 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
667 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
668};
669
670// Out-of-line dtor due to AIX and GCC, http://github.com/weidai11/cryptopp/issues/499
671template <class GP>
673
681
689
702
707template <class H>
708struct GDSA : public DL_SS<
709 DL_SignatureKeys_GFP,
710 DL_Algorithm_GDSA<Integer>,
711 DL_SignatureMessageEncodingMethod_DSA,
712 H>
713{
714};
715
719template <class H>
720struct NR : public DL_SS<
721 DL_SignatureKeys_GFP,
722 DL_Algorithm_NR<Integer>,
723 DL_SignatureMessageEncodingMethod_NR,
724 H>
725{
726};
727
733{
734public:
735 virtual ~DL_GroupParameters_DSA() {}
736
752 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
753
769 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
770
774 static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
775 {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
776
778 enum {
780 MIN_PRIME_LENGTH = 1024,
782 MAX_PRIME_LENGTH = 3072,
784 PRIME_LENGTH_MULTIPLE = 1024
785 };
786};
787
788template <class H>
789class DSA2;
790
799
823template <class H>
824class DSA2 : public DL_SS<
825 DL_Keys_DSA,
826 DL_Algorithm_GDSA<Integer>,
827 DL_SignatureMessageEncodingMethod_DSA,
828 H,
829 DSA2<H> >
830{
831public:
832 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
833};
834
839template <class H>
840struct DSA_RFC6979 : public DL_SS<
841 DL_SignatureKeys_GFP,
842 DL_Algorithm_DSA_RFC6979<Integer, H>,
843 DL_SignatureMessageEncodingMethod_DSA,
844 H,
845 DSA_RFC6979<H> >
846{
847 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();}
848};
849
852
853CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
854CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
856
870template <class MAC, bool DHAES_MODE, bool LABEL_OCTETS=false>
872{
873public:
874 virtual ~DL_EncryptionAlgorithm_Xor() {}
875
876 bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
877 size_t GetSymmetricKeyLength(size_t plaintextLength) const
878 {return plaintextLength + static_cast<size_t>(MAC::DEFAULT_KEYLENGTH);}
879 size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
880 {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
881 size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
882 {return SaturatingSubtract(ciphertextLength, static_cast<size_t>(MAC::DIGESTSIZE));}
883 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters) const
884 {
885 CRYPTOPP_UNUSED(rng);
886 const byte *cipherKey = NULLPTR, *macKey = NULLPTR;
887 if (DHAES_MODE)
888 {
889 macKey = key;
890 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
891 }
892 else
893 {
894 cipherKey = key;
895 macKey = key + plaintextLength;
896 }
897
898 ConstByteArrayParameter encodingParameters;
899 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
900
901 if (plaintextLength) // Coverity finding
902 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
903
904 MAC mac(macKey);
905 mac.Update(ciphertext, plaintextLength);
906 mac.Update(encodingParameters.begin(), encodingParameters.size());
907 if (DHAES_MODE)
908 {
909 byte L[8];
910 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
911 mac.Update(L, 8);
912 }
913 mac.Final(ciphertext + plaintextLength);
914 }
915 DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters) const
916 {
917 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
918 const byte *cipherKey, *macKey;
919 if (DHAES_MODE)
920 {
921 macKey = key;
922 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
923 }
924 else
925 {
926 cipherKey = key;
927 macKey = key + plaintextLength;
928 }
929
930 ConstByteArrayParameter encodingParameters;
931 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
932
933 MAC mac(macKey);
934 mac.Update(ciphertext, plaintextLength);
935 mac.Update(encodingParameters.begin(), encodingParameters.size());
936 if (DHAES_MODE)
937 {
938 byte L[8];
939 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
940 mac.Update(L, 8);
941 }
942 if (!mac.Verify(ciphertext + plaintextLength))
943 return DecodingResult();
944
945 if (plaintextLength) // Coverity finding
946 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
947
948 return DecodingResult(plaintextLength);
949 }
950};
951
957template <class T, bool DHAES_MODE, class KDF>
959{
960public:
962
963 bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
964 void Derive(const DL_GroupParameters<T> &params, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &parameters) const
965 {
966 SecByteBlock agreedSecret;
967 if (DHAES_MODE)
968 {
969 agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
970 params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
971 params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
972 }
973 else
974 {
975 agreedSecret.New(params.GetEncodedElementSize(false));
976 params.EncodeElement(false, agreedElement, agreedSecret);
977 }
978
979 ConstByteArrayParameter derivationParameters;
980 parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
981 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
982 }
983};
984
1018template <class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true, bool LABEL_OCTETS=false>
1019struct DLIES
1020 : public DL_ES<
1021 DL_CryptoKeys_GFP,
1022 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
1023 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<HASH> >,
1024 DL_EncryptionAlgorithm_Xor<HMAC<HASH>, DHAES_MODE, LABEL_OCTETS>,
1025 DLIES<> >
1026{
1027 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
1028};
1029
1030NAMESPACE_END
1031
1032#if CRYPTOPP_MSC_VERSION
1033# pragma warning(pop)
1034#endif
1035
1036#endif
Classes for working with NameValuePairs.
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition algparam.h:508
Classes and functions for working with ANS.1 objects.
Encode and decode ASN.1 objects with additional information.
Definition asn.h:684
virtual void DEREncode(BufferedTransformation &bt) const =0
Encode this object into a BufferedTransformation.
virtual void BERDecode(BufferedTransformation &bt)=0
Decode this object from a BufferedTransformation.
Interface for buffered transformations.
Definition cryptlib.h:1652
Used to pass byte array input as part of a NameValuePairs object.
Definition algparam.h:25
const byte * begin() const
Pointer to the first byte in the memory block.
Definition algparam.h:84
size_t size() const
Length of the memory block.
Definition algparam.h:88
DSA signature algorithm based on RFC 6979.
Definition gfpcrypt.h:347
Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
Generate k.
Definition gfpcrypt.h:359
bool IsDeterministic() const
Signature scheme flag.
Definition gfpcrypt.h:355
German Digital Signature Algorithm.
Definition gfpcrypt.h:506
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition gfpcrypt.h:512
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition gfpcrypt.h:522
GDSA algorithm.
Definition gfpcrypt.h:309
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition gfpcrypt.h:324
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition gfpcrypt.h:315
NR algorithm.
Definition gfpcrypt.h:548
bool Verify(const DL_GroupParameters< T > &params, const DL_PublicKey< T > &publicKey, const Integer &e, const Integer &r, const Integer &s) const
Verify a message using a public key.
Definition gfpcrypt.h:562
void Sign(const DL_GroupParameters< T > &params, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
Sign a message using a private key.
Definition gfpcrypt.h:554
Discrete Log (DL) encryption scheme.
Definition pubkey.h:2362
Interface for Elgamal-like signature algorithms.
Definition pubkey.h:1407
P1363 based XOR Encryption Method.
Definition gfpcrypt.h:872
DL_FixedBasePrecomputation interface.
Definition eprecomp.h:61
DSA group parameters.
Definition gfpcrypt.h:733
static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
Check the prime length for errors.
Definition gfpcrypt.h:774
Integer GetMaxExponent() const
Retrieves the maximum exponent for the group.
Definition gfpcrypt.h:298
GF(p) group parameters that default to safe primes.
Definition gfpcrypt.h:275
GF(p) group parameters.
Definition gfpcrypt.h:225
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition gfpcrypt.h:260
bool IsIdentity(const Integer &element) const
Determines if an element is an identity.
Definition gfpcrypt.h:235
Integer-based GroupParameters specialization.
Definition gfpcrypt.h:35
void Initialize(const Integer &p, const Integer &g)
Initialize a group parameters over integers.
Definition gfpcrypt.h:58
Integer GetGroupOrder() const
Retrieves the order of the group.
Definition gfpcrypt.h:99
virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)=0
Set group parameters.
void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
Create a group parameters over integers.
Definition gfpcrypt.h:52
void SetSubgroupOrder(const Integer &q)
Set subgroup order.
Definition gfpcrypt.h:161
Integer ConvertElementToInteger(const Element &element) const
Converts an element to an Integer.
Definition gfpcrypt.h:139
virtual const Integer & GetModulus() const =0
Retrieve the modulus for the group.
void Initialize(const DL_GroupParameters_IntegerBased &params)
Initialize a group parameters over integers.
Definition gfpcrypt.h:43
bool FastSubgroupCheckAvailable() const
Determine if subgroup membership check is fast.
Definition gfpcrypt.h:105
void Initialize(const Integer &p, const Integer &q, const Integer &g)
Initialize a group parameters over integers.
Definition gfpcrypt.h:65
const Integer & GetSubgroupOrder() const
Retrieves the subgroup order.
Definition gfpcrypt.h:98
Integer-based GroupParameters default implementation.
Definition gfpcrypt.h:183
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition gfpcrypt.h:195
const DL_FixedBasePrecomputation< Element > & GetBasePrecomputation() const
Retrieves the group precomputation.
Definition gfpcrypt.h:199
DL_FixedBasePrecomputation< Element > & AccessBasePrecomputation()
Retrieves the group precomputation.
Definition gfpcrypt.h:200
const Integer & GetGenerator() const
Retrieves a reference to the group generator.
Definition gfpcrypt.h:209
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition gfpcrypt.h:192
const Integer & GetModulus() const
Retrieve the modulus for the group.
Definition gfpcrypt.h:205
Interface for Discrete Log (DL) group parameters.
Definition pubkey.h:782
virtual const Element & GetSubgroupGenerator() const
Retrieves the subgroup generator.
Definition pubkey.h:859
virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0
Encodes the element.
virtual unsigned int GetEncodedElementSize(bool reversible) const =0
Retrieves the encoded element's size.
virtual const Integer & GetSubgroupOrder() const =0
Retrieves the subgroup order.
virtual Element ExponentiateBase(const Integer &exponent) const
Exponentiates the base.
Definition pubkey.h:869
virtual Integer ConvertElementToInteger(const Element &element) const =0
Converts an element to an Integer.
Base implementation of Discrete Log (DL) group parameters.
Definition pubkey.h:1014
const DL_GroupPrecomputation< Element > & GetGroupPrecomputation() const
Retrieves the group precomputation.
Definition pubkey.h:1024
P1363 based Key Derivation Method.
Definition gfpcrypt.h:959
Interface for key derivation algorithms used in DL cryptosystems.
Definition pubkey.h:1493
Discrete Log (DL) private key in GF(p) groups.
Definition gfpcrypt.h:614
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
Create a private key.
Definition gfpcrypt.h:645
void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
Create a private key.
Definition gfpcrypt.h:634
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
Create a private key.
Definition gfpcrypt.h:624
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition gfpcrypt.h:666
void Initialize(const Integer &p, const Integer &g, const Integer &x)
Initialize a private key over GF(p)
Definition gfpcrypt.h:658
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &x)
Initialize a private key over GF(p)
Definition gfpcrypt.h:651
Discrete Log (DL) private key base implementation.
Definition pubkey.h:1239
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params)
Generate a random key or crypto parameters.
Definition pubkey.h:1276
void SetPrivateExponent(const Integer &x)
Sets the private exponent.
Definition pubkey.h:1301
Discrete Log (DL) public key in GF(p) groups.
Definition gfpcrypt.h:578
void Initialize(const DL_GroupParameters_IntegerBased &params, const Integer &y)
Initialize a public key over GF(p)
Definition gfpcrypt.h:585
void Initialize(const Integer &p, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition gfpcrypt.h:592
void DEREncodePublicKey(BufferedTransformation &bt) const
Encode subjectPublicKey part of subjectPublicKeyInfo.
Definition gfpcrypt.h:606
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
Decode subjectPublicKey part of subjectPublicKeyInfo.
Definition gfpcrypt.h:604
void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
Initialize a public key over GF(p)
Definition gfpcrypt.h:600
Interface for Discrete Log (DL) public keys.
Definition pubkey.h:1059
virtual const Element & GetPublicElement() const
Retrieves the public element.
Definition pubkey.h:1089
virtual void SetPublicElement(const Element &y)
Sets the public element.
Definition pubkey.h:1093
virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const
Exponentiates an element.
Definition pubkey.h:1110
Discrete Log (DL) public key base implementation.
Definition pubkey.h:1336
Discrete Log (DL) signature scheme.
Definition pubkey.h:2342
Interface for symmetric encryption algorithms used in DL cryptosystems.
Definition pubkey.h:1505
DSA signature scheme.
Definition gfpcrypt.h:830
Interface for deterministic signers.
Definition pubkey.h:1460
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
Generate a random key or crypto parameters.
Definition cryptlib.cpp:840
HMAC.
Definition hmac.h:53
Multiple precision integer with arithmetic operations.
Definition integer.h:50
size_t MinEncodedSize(Signedness sign=UNSIGNED) const
Minimum number of bytes to encode this integer.
Definition integer.cpp:3412
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition integer.cpp:3364
static const Integer &CRYPTOPP_API One()
Integer representing 1.
Definition integer.cpp:4920
bool IsNegative() const
Determines if the Integer is negative.
Definition integer.h:341
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition integer.cpp:3427
Integer InverseMod(const Integer &n) const
Calculate multiplicative inverse.
Definition integer.cpp:4473
Interface for retrieving values given their names.
Definition cryptlib.h:322
bool GetValue(const char *name, T &value) const
Get a named value.
Definition cryptlib.h:379
Object Identifier.
Definition asn.h:265
Interface for random number generators.
Definition cryptlib.h:1435
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition secblock.h:836
void New(size_type newSize)
Change size without preserving contents.
Definition secblock.h:1126
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
Library configuration file.
Abstract base classes that provide a uniform interface to this library.
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition cryptlib.h:147
DSA2< SHA1 > DSA
DSA with SHA-1, typedef'd for backwards compatibility.
Definition gfpcrypt.h:851
Classes for HMAC message authentication codes.
Multiple precision integer with arithmetic operations.
Utility functions for the Crypto++ library.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULLPTR)
Access a block of memory.
Definition misc.h:2739
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition misc.h:1093
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition misc.h:666
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
Definition misc.h:525
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition misc.h:655
size_t BitsToBytes(size_t bitCount)
Returns the number of 8-bit bytes or octets required for the specified number of bits.
Definition misc.h:938
This file contains helper classes/functions for implementing public key algorithms.
Classes for SHA-1 and SHA-2 family of message digests.
Classes for automatic resource management.
Discrete Log (DL) encryption/decryption keys in GF(p) groups.
Definition gfpcrypt.h:684
DSA keys.
Definition gfpcrypt.h:795
Discrete Log (DL) signing/verification keys in GF(p) groups.
Definition gfpcrypt.h:676
Discrete Log Integrated Encryption Scheme.
Definition gfpcrypt.h:1026
DSA deterministic signature scheme.
Definition gfpcrypt.h:846
Returns a decoding results.
Definition cryptlib.h:278
Converts an enumeration to a type suitable for use as a template parameter.
Definition cryptlib.h:136
DSA signature scheme.
Definition gfpcrypt.h:713
NR signature scheme.
Definition gfpcrypt.h:725