File indexing completed on 2025-01-18 09:55:03
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef CRYPTOPP_GFPCRYPT_H
0009 #define CRYPTOPP_GFPCRYPT_H
0010
0011 #include "config.h"
0012
0013 #if CRYPTOPP_MSC_VERSION
0014 # pragma warning(push)
0015 # pragma warning(disable: 4189 4231 4275)
0016 #endif
0017
0018 #include "cryptlib.h"
0019 #include "pubkey.h"
0020 #include "integer.h"
0021 #include "modexppc.h"
0022 #include "algparam.h"
0023 #include "smartptr.h"
0024 #include "sha.h"
0025 #include "asn.h"
0026 #include "hmac.h"
0027 #include "misc.h"
0028
0029 NAMESPACE_BEGIN(CryptoPP)
0030
0031 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters<Integer>;
0032
0033
0034 class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial<DL_GroupParameters<Integer> >
0035 {
0036 typedef DL_GroupParameters_IntegerBased ThisClass;
0037
0038 public:
0039 virtual ~DL_GroupParameters_IntegerBased() {}
0040
0041
0042
0043 void Initialize(const DL_GroupParameters_IntegerBased ¶ms)
0044 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
0045
0046
0047
0048
0049
0050
0051
0052 void Initialize(RandomNumberGenerator &rng, unsigned int pbits)
0053 {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));}
0054
0055
0056
0057
0058 void Initialize(const Integer &p, const Integer &g)
0059 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
0060
0061
0062
0063
0064
0065 void Initialize(const Integer &p, const Integer &q, const Integer &g)
0066 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
0067
0068
0069 void BERDecode(BufferedTransformation &bt);
0070 void DEREncode(BufferedTransformation &bt) const;
0071
0072
0073
0074
0075
0076
0077
0078
0079 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
0092
0093
0094
0095 void AssignFrom(const NameValuePairs &source);
0096
0097
0098 const Integer & GetSubgroupOrder() const {return m_q;}
0099 Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
0100 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
0101 bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
0102
0103
0104
0105 bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
0117
0118
0119
0120
0121
0122
0123
0124 unsigned int GetEncodedElementSize(bool reversible) const;
0125
0126
0127
0128
0129
0130
0131
0132
0133 Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
0134
0135
0136
0137
0138
0139 Integer ConvertElementToInteger(const Element &element) const
0140 {return element;}
0141
0142
0143
0144 Integer GetMaxExponent() const;
0145
0146
0147
0148 OID GetAlgorithmID() const;
0149
0150
0151
0152 virtual const Integer & GetModulus() const =0;
0153
0154
0155
0156
0157 virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
0158
0159
0160
0161 void SetSubgroupOrder(const Integer &q)
0162 {m_q = q; ParametersChanged();}
0163
0164 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
0165
0166 protected:
0167 Integer ComputeGroupOrder(const Integer &modulus) const
0168 {return modulus-(GetFieldType() == 1 ? 1 : -1);}
0169
0170
0171 virtual int GetFieldType() const =0;
0172 virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const;
0173
0174 private:
0175 Integer m_q;
0176 };
0177
0178
0179
0180
0181 template <class GROUP_PRECOMP, class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<typename GROUP_PRECOMP::Element> >
0182 class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl<GROUP_PRECOMP, BASE_PRECOMP, DL_GroupParameters_IntegerBased>
0183 {
0184 typedef DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> ThisClass;
0185
0186 public:
0187 typedef typename GROUP_PRECOMP::Element Element;
0188
0189 virtual ~DL_GroupParameters_IntegerBasedImpl() {}
0190
0191
0192 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
0193 {return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();}
0194
0195 void AssignFrom(const NameValuePairs &source)
0196 {AssignFromHelper<DL_GroupParameters_IntegerBased>(this, source);}
0197
0198
0199 const DL_FixedBasePrecomputation<Element> & GetBasePrecomputation() const {return this->m_gpc;}
0200 DL_FixedBasePrecomputation<Element> & AccessBasePrecomputation() {return this->m_gpc;}
0201
0202
0203
0204
0205 const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();}
0206
0207
0208
0209 const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
0210
0211 void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g)
0212 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
0213
0214
0215 bool operator==(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
0216 {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
0217 bool operator!=(const DL_GroupParameters_IntegerBasedImpl<GROUP_PRECOMP, BASE_PRECOMP> &rhs) const
0218 {return !operator==(rhs);}
0219 };
0220
0221 CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>;
0222
0223
0224 class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl<ModExpPrecomputation>
0225 {
0226 public:
0227 virtual ~DL_GroupParameters_GFP() {}
0228
0229
0230
0231
0232
0233
0234
0235 bool IsIdentity(const Integer &element) const {return element == Integer::One();}
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const;
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
0261 {
0262 return GetValueHelper<DL_GroupParameters_IntegerBased>(this, name, valueType, pValue).Assignable();
0263 }
0264
0265
0266 Element MultiplyElements(const Element &a, const Element &b) const;
0267 Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const;
0268
0269 protected:
0270 int GetFieldType() const {return 1;}
0271 };
0272
0273
0274 class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP
0275 {
0276 public:
0277 typedef NoCofactorMultiplication DefaultCofactorOption;
0278
0279 virtual ~DL_GroupParameters_GFP_DefaultSafePrime() {}
0280
0281 protected:
0282 unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;}
0283 };
0284
0285
0286
0287
0288
0289
0290
0291 class CRYPTOPP_DLL DL_GroupParameters_ElGamal : public DL_GroupParameters_GFP_DefaultSafePrime
0292 {
0293 public:
0294 typedef NoCofactorMultiplication DefaultCofactorOption;
0295
0296 virtual ~DL_GroupParameters_ElGamal() {}
0297
0298 Integer GetMaxExponent() const
0299 {
0300 return GetSubgroupOrder()-1;
0301 }
0302 };
0303
0304
0305
0306
0307 template <class T>
0308 class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T>
0309 {
0310 public:
0311 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";}
0312
0313 virtual ~DL_Algorithm_GDSA() {}
0314
0315 void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
0316 {
0317 const Integer &q = params.GetSubgroupOrder();
0318 r %= q;
0319 Integer kInv = k.InverseMod(q);
0320 s = (kInv * (x*r + e)) % q;
0321 CRYPTOPP_ASSERT(!!r && !!s);
0322 }
0323
0324 bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
0325 {
0326 const Integer &q = params.GetSubgroupOrder();
0327 if (r>=q || r<1 || s>=q || s<1)
0328 return false;
0329
0330 Integer w = s.InverseMod(q);
0331 Integer u1 = (e * w) % q;
0332 Integer u2 = (r * w) % q;
0333
0334 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
0335 }
0336 };
0337
0338
0339
0340
0341
0342
0343
0344
0345 template <class T, class H>
0346 class DL_Algorithm_DSA_RFC6979 : public DL_Algorithm_GDSA<T>, public DeterministicSignatureAlgorithm
0347 {
0348 public:
0349 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
0350
0351 virtual ~DL_Algorithm_DSA_RFC6979() {}
0352
0353 bool IsProbabilistic() const
0354 {return false;}
0355 bool IsDeterministic() const
0356 {return true;}
0357
0358
0359 Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
0360 {
0361 static const byte zero = 0, one = 1;
0362 const size_t qlen = q.BitCount();
0363 const size_t rlen = BitsToBytes(qlen);
0364
0365
0366 SecByteBlock BH(e.MinEncodedSize());
0367 e.Encode(BH, BH.size());
0368 BH = bits2octets(BH, q);
0369
0370
0371 SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize()));
0372 x.Encode(BX, BX.size());
0373
0374
0375 SecByteBlock V(H::DIGESTSIZE);
0376 std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one);
0377
0378
0379 SecByteBlock K(H::DIGESTSIZE);
0380 std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero);
0381
0382
0383 m_hmac.SetKey(K, K.size());
0384 m_hmac.Update(V, V.size());
0385 m_hmac.Update(&zero, 1);
0386 m_hmac.Update(BX, BX.size());
0387 m_hmac.Update(BH, BH.size());
0388 m_hmac.TruncatedFinal(K, K.size());
0389
0390
0391 m_hmac.SetKey(K, K.size());
0392 m_hmac.Update(V, V.size());
0393 m_hmac.TruncatedFinal(V, V.size());
0394
0395
0396 m_hmac.SetKey(K, K.size());
0397 m_hmac.Update(V, V.size());
0398 m_hmac.Update(&one, 1);
0399 m_hmac.Update(BX, BX.size());
0400 m_hmac.Update(BH, BH.size());
0401 m_hmac.TruncatedFinal(K, K.size());
0402
0403
0404 m_hmac.SetKey(K, K.size());
0405 m_hmac.Update(V, V.size());
0406 m_hmac.TruncatedFinal(V, V.size());
0407
0408 Integer k;
0409 SecByteBlock temp(rlen);
0410 for (;;)
0411 {
0412
0413
0414 size_t toff = 0;
0415 while (toff < rlen)
0416 {
0417 m_hmac.Update(V, V.size());
0418 m_hmac.TruncatedFinal(V, V.size());
0419
0420 size_t cc = STDMIN(V.size(), temp.size() - toff);
0421 memcpy_s(temp+toff, temp.size() - toff, V, cc);
0422 toff += cc;
0423 }
0424
0425 k = bits2int(temp, qlen);
0426 if (k > 0 && k < q)
0427 break;
0428
0429
0430 m_hmac.Update(V, V.size());
0431 m_hmac.Update(&zero, 1);
0432 m_hmac.TruncatedFinal(K, K.size());
0433
0434 m_hmac.SetKey(K, K.size());
0435 m_hmac.Update(V, V.size());
0436 m_hmac.TruncatedFinal(V, V.size());
0437 }
0438
0439 return k;
0440 }
0441
0442 protected:
0443
0444 Integer bits2int(const SecByteBlock& bits, size_t qlen) const
0445 {
0446 Integer ret(bits, bits.size());
0447 size_t blen = bits.size()*8;
0448
0449 if (blen > qlen)
0450 ret >>= blen - qlen;
0451
0452 return ret;
0453 }
0454
0455
0456
0457 SecByteBlock int2octets(const Integer& val, size_t rlen) const
0458 {
0459 SecByteBlock block(val.MinEncodedSize());
0460 val.Encode(block, val.MinEncodedSize());
0461
0462 if (block.size() == rlen)
0463 return block;
0464
0465
0466 SecByteBlock t(rlen);
0467 if (block.size() > rlen)
0468 {
0469 size_t offset = block.size() - rlen;
0470 std::memcpy(t, block + offset, rlen);
0471 }
0472 else
0473 {
0474 size_t offset = rlen - block.size();
0475 std::memset(t, '\x00', offset);
0476 std::memcpy(t + offset, block, rlen - offset);
0477 }
0478
0479 return t;
0480 }
0481
0482
0483
0484 SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const
0485 {
0486 Integer b2 = bits2int(in, q.BitCount());
0487 Integer b1 = b2 - q;
0488 return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount());
0489 }
0490
0491 private:
0492 mutable H m_hash;
0493 mutable HMAC<H> m_hmac;
0494 };
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504 template <class T>
0505 class DL_Algorithm_GDSA_ISO15946 : public DL_ElgamalLikeSignatureAlgorithm<T>
0506 {
0507 public:
0508 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "GDSA-ISO15946";}
0509
0510 virtual ~DL_Algorithm_GDSA_ISO15946() {}
0511
0512 void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
0513 {
0514 const Integer &q = params.GetSubgroupOrder();
0515
0516 r = params.ConvertElementToInteger(params.ExponentiateBase(k)) % q;
0517
0518 s = (k * r - e) * x % q;
0519 CRYPTOPP_ASSERT(!!r && !!s);
0520 }
0521
0522 bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
0523 {
0524 const Integer &q = params.GetSubgroupOrder();
0525 if (r>=q || r<1 || s>=q || s<1)
0526 return false;
0527
0528 const Integer& rInv = r.InverseMod(q);
0529 const Integer u1 = (rInv * e) % q;
0530 const Integer u2 = (rInv * s) % q;
0531
0532 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
0533 }
0534 };
0535
0536 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
0537 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA1>;
0538 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA224>;
0539 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA256>;
0540 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA384>;
0541 CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA512>;
0542
0543
0544
0545
0546 template <class T>
0547 class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm<T>
0548 {
0549 public:
0550 CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "NR";}
0551
0552 virtual ~DL_Algorithm_NR() {}
0553
0554 void Sign(const DL_GroupParameters<T> ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const
0555 {
0556 const Integer &q = params.GetSubgroupOrder();
0557 r = (r + e) % q;
0558 s = (k - x*r) % q;
0559 CRYPTOPP_ASSERT(!!r);
0560 }
0561
0562 bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const
0563 {
0564 const Integer &q = params.GetSubgroupOrder();
0565 if (r>=q || r<1 || s>=q)
0566 return false;
0567
0568
0569 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
0570 }
0571 };
0572
0573
0574
0575
0576 template <class GP>
0577 class DL_PublicKey_GFP : public DL_PublicKeyImpl<GP>
0578 {
0579 public:
0580 virtual ~DL_PublicKey_GFP() {}
0581
0582
0583
0584
0585 void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y)
0586 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
0587
0588
0589
0590
0591
0592 void Initialize(const Integer &p, const Integer &g, const Integer &y)
0593 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
0594
0595
0596
0597
0598
0599
0600 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y)
0601 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
0602
0603
0604 void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
0605 {this->SetPublicElement(Integer(bt));}
0606 void DEREncodePublicKey(BufferedTransformation &bt) const
0607 {this->GetPublicElement().DEREncode(bt);}
0608 };
0609
0610
0611
0612 template <class GP>
0613 class DL_PrivateKey_GFP : public DL_PrivateKeyImpl<GP>
0614 {
0615 public:
0616 virtual ~DL_PrivateKey_GFP();
0617
0618
0619
0620
0621
0622
0623
0624 void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
0625 {this->GenerateRandomWithKeySize(rng, modulusBits);}
0626
0627
0628
0629
0630
0631
0632
0633
0634 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g)
0635 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));}
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645 void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g)
0646 {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));}
0647
0648
0649
0650
0651 void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x)
0652 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
0653
0654
0655
0656
0657
0658 void Initialize(const Integer &p, const Integer &g, const Integer &x)
0659 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
0660
0661
0662
0663
0664
0665
0666 void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x)
0667 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
0668 };
0669
0670
0671 template <class GP>
0672 DL_PrivateKey_GFP<GP>::~DL_PrivateKey_GFP() {}
0673
0674
0675 struct DL_SignatureKeys_GFP
0676 {
0677 typedef DL_GroupParameters_GFP GroupParameters;
0678 typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
0679 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
0680 };
0681
0682
0683 struct DL_CryptoKeys_GFP
0684 {
0685 typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters;
0686 typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
0687 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
0688 };
0689
0690
0691
0692
0693
0694
0695
0696 struct DL_CryptoKeys_ElGamal
0697 {
0698 typedef DL_GroupParameters_ElGamal GroupParameters;
0699 typedef DL_PublicKey_GFP<GroupParameters> PublicKey;
0700 typedef DL_PrivateKey_GFP<GroupParameters> PrivateKey;
0701 };
0702
0703
0704
0705
0706
0707 template <class H>
0708 struct GDSA : public DL_SS<
0709 DL_SignatureKeys_GFP,
0710 DL_Algorithm_GDSA<Integer>,
0711 DL_SignatureMessageEncodingMethod_DSA,
0712 H>
0713 {
0714 };
0715
0716
0717
0718
0719 template <class H>
0720 struct NR : public DL_SS<
0721 DL_SignatureKeys_GFP,
0722 DL_Algorithm_NR<Integer>,
0723 DL_SignatureMessageEncodingMethod_NR,
0724 H>
0725 {
0726 };
0727
0728
0729
0730
0731
0732 class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP
0733 {
0734 public:
0735 virtual ~DL_GroupParameters_DSA() {}
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752 bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769 void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
0770
0771
0772
0773
0774 static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits)
0775 {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
0776
0777
0778 enum {
0779
0780 MIN_PRIME_LENGTH = 1024,
0781
0782 MAX_PRIME_LENGTH = 3072,
0783
0784 PRIME_LENGTH_MULTIPLE = 1024
0785 };
0786 };
0787
0788 template <class H>
0789 class DSA2;
0790
0791
0792
0793
0794 struct DL_Keys_DSA
0795 {
0796 typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey;
0797 typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA1> > PrivateKey;
0798 };
0799
0800
0801
0802
0803
0804
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820
0821
0822
0823 template <class H>
0824 class DSA2 : public DL_SS<
0825 DL_Keys_DSA,
0826 DL_Algorithm_GDSA<Integer>,
0827 DL_SignatureMessageEncodingMethod_DSA,
0828 H,
0829 DSA2<H> >
0830 {
0831 public:
0832 static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
0833 };
0834
0835
0836
0837
0838
0839 template <class H>
0840 struct DSA_RFC6979 : public DL_SS<
0841 DL_SignatureKeys_GFP,
0842 DL_Algorithm_DSA_RFC6979<Integer, H>,
0843 DL_SignatureMessageEncodingMethod_DSA,
0844 H,
0845 DSA_RFC6979<H> >
0846 {
0847 static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();}
0848 };
0849
0850
0851 typedef DSA2<SHA1> DSA;
0852
0853 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP<DL_GroupParameters_DSA>;
0854 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP<DL_GroupParameters_DSA>;
0855 CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA2<SHA1> >;
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868
0869
0870 template <class MAC, bool DHAES_MODE, bool LABEL_OCTETS=false>
0871 class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm
0872 {
0873 public:
0874 virtual ~DL_EncryptionAlgorithm_Xor() {}
0875
0876 bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
0877 size_t GetSymmetricKeyLength(size_t plaintextLength) const
0878 {return plaintextLength + static_cast<size_t>(MAC::DEFAULT_KEYLENGTH);}
0879 size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
0880 {return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
0881 size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const
0882 {return SaturatingSubtract(ciphertextLength, static_cast<size_t>(MAC::DIGESTSIZE));}
0883 void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const
0884 {
0885 CRYPTOPP_UNUSED(rng);
0886 const byte *cipherKey = NULLPTR, *macKey = NULLPTR;
0887 if (DHAES_MODE)
0888 {
0889 macKey = key;
0890 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
0891 }
0892 else
0893 {
0894 cipherKey = key;
0895 macKey = key + plaintextLength;
0896 }
0897
0898 ConstByteArrayParameter encodingParameters;
0899 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
0900
0901 if (plaintextLength)
0902 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
0903
0904 MAC mac(macKey);
0905 mac.Update(ciphertext, plaintextLength);
0906 mac.Update(encodingParameters.begin(), encodingParameters.size());
0907 if (DHAES_MODE)
0908 {
0909 byte L[8];
0910 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
0911 mac.Update(L, 8);
0912 }
0913 mac.Final(ciphertext + plaintextLength);
0914 }
0915 DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const
0916 {
0917 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
0918 const byte *cipherKey, *macKey;
0919 if (DHAES_MODE)
0920 {
0921 macKey = key;
0922 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
0923 }
0924 else
0925 {
0926 cipherKey = key;
0927 macKey = key + plaintextLength;
0928 }
0929
0930 ConstByteArrayParameter encodingParameters;
0931 parameters.GetValue(Name::EncodingParameters(), encodingParameters);
0932
0933 MAC mac(macKey);
0934 mac.Update(ciphertext, plaintextLength);
0935 mac.Update(encodingParameters.begin(), encodingParameters.size());
0936 if (DHAES_MODE)
0937 {
0938 byte L[8];
0939 PutWord(false, BIG_ENDIAN_ORDER, L, (LABEL_OCTETS ? word64(encodingParameters.size()) : 8 * word64(encodingParameters.size())));
0940 mac.Update(L, 8);
0941 }
0942 if (!mac.Verify(ciphertext + plaintextLength))
0943 return DecodingResult();
0944
0945 if (plaintextLength)
0946 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
0947
0948 return DecodingResult(plaintextLength);
0949 }
0950 };
0951
0952
0953
0954
0955
0956
0957 template <class T, bool DHAES_MODE, class KDF>
0958 class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T>
0959 {
0960 public:
0961 virtual ~DL_KeyDerivationAlgorithm_P1363() {}
0962
0963 bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;}
0964 void Derive(const DL_GroupParameters<T> ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const
0965 {
0966 SecByteBlock agreedSecret;
0967 if (DHAES_MODE)
0968 {
0969 agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
0970 params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
0971 params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
0972 }
0973 else
0974 {
0975 agreedSecret.New(params.GetEncodedElementSize(false));
0976 params.EncodeElement(false, agreedElement, agreedSecret);
0977 }
0978
0979 ConstByteArrayParameter derivationParameters;
0980 parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters);
0981 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
0982 }
0983 };
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018 template <class HASH = SHA1, class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true, bool LABEL_OCTETS=false>
1019 struct 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";}
1028 };
1029
1030 NAMESPACE_END
1031
1032 #if CRYPTOPP_MSC_VERSION
1033 # pragma warning(pop)
1034 #endif
1035
1036 #endif