1 #ifndef CRYPTOPP_GFPCRYPT_H
2 #define CRYPTOPP_GFPCRYPT_H
18 NAMESPACE_BEGIN(CryptoPP)
29 {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());}
31 {GenerateRandom(rng, MakeParameters(
"ModulusSize", (
int)pbits));}
32 void Initialize(
const Integer &p,
const Integer &g)
33 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);}
34 void Initialize(
const Integer &p,
const Integer &q,
const Integer &g)
35 {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);}
44 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const;
48 const Integer & GetSubgroupOrder()
const {
return m_q;}
49 Integer GetGroupOrder()
const {
return GetFieldType() == 1 ? GetModulus()-
Integer::One() : GetModulus()+
Integer::One();}
52 bool FastSubgroupCheckAvailable()
const {
return GetCofactor() == 2;}
53 void EncodeElement(
bool reversible,
const Element &element, byte *encoded)
const
54 {element.
Encode(encoded, GetModulus().ByteCount());}
55 unsigned int GetEncodedElementSize(
bool reversible)
const {
return GetModulus().ByteCount();}
56 Integer DecodeElement(
const byte *encoded,
bool checkForGroupMembership)
const;
57 Integer ConvertElementToInteger(
const Element &element)
const
59 Integer GetMaxExponent()
const;
60 static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {
return "";}
62 OID GetAlgorithmID()
const;
64 virtual const Integer & GetModulus()
const =0;
65 virtual void SetModulusAndSubgroupGenerator(
const Integer &p,
const Integer &g) =0;
67 void SetSubgroupOrder(
const Integer &q)
68 {m_q = q; ParametersChanged();}
71 Integer ComputeGroupOrder(
const Integer &modulus)
const
72 {
return modulus-(GetFieldType() == 1 ? 1 : -1);}
75 virtual int GetFieldType()
const =0;
76 virtual unsigned int GetDefaultSubgroupOrderSize(
unsigned int modulusSize)
const;
83 template <
class GROUP_PRECOMP,
class BASE_PRECOMP = DL_FixedBasePrecomputationImpl<CPP_TYPENAME GROUP_PRECOMP::Element> >
89 typedef typename GROUP_PRECOMP::Element Element;
92 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
93 {
return GetValueHelper<DL_GroupParameters_IntegerBased>(
this, name, valueType, pValue).Assignable();}
96 {AssignFromHelper<DL_GroupParameters_IntegerBased>(
this, source);}
103 const Integer & GetModulus()
const {
return this->m_groupPrecomputation.GetModulus();}
104 const Integer & GetGenerator()
const {
return this->m_gpc.GetBase(this->GetGroupPrecomputation());}
106 void SetModulusAndSubgroupGenerator(
const Integer &p,
const Integer &g)
107 {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();}
111 {
return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();}
113 {
return !operator==(rhs);}
124 void SimultaneousExponentiate(Element *results,
const Element &base,
const Integer *exponents,
unsigned int exponentsCount)
const;
127 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const
129 return GetValueHelper<DL_GroupParameters_IntegerBased>(
this, name, valueType, pValue).Assignable();
133 Element MultiplyElements(
const Element &a,
const Element &b)
const;
134 Element CascadeExponentiate(
const Element &element1,
const Integer &exponent1,
const Element &element2,
const Integer &exponent2)
const;
137 int GetFieldType()
const {
return 1;}
147 unsigned int GetDefaultSubgroupOrderSize(
unsigned int modulusSize)
const {
return modulusSize-1;}
155 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "DSA-1363";}
159 const Integer &q = params.GetSubgroupOrder();
162 s = (kInv * (x*r + e)) % q;
168 const Integer &q = params.GetSubgroupOrder();
169 if (r>=q || r<1 || s>=q || s<1)
176 return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
187 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "NR";}
191 const Integer &q = params.GetSubgroupOrder();
199 const Integer &q = params.GetSubgroupOrder();
200 if (r>=q || r<1 || s>=q)
204 return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q;
215 {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);}
217 {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);}
219 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);}
223 {this->SetPublicElement(
Integer(bt));}
225 {this->GetPublicElement().DEREncode(bt);}
236 {this->
GenerateRandom(rng, MakeParameters(
"Modulus", p)(
"SubgroupGenerator", g));}
238 {this->
GenerateRandom(rng, MakeParameters(
"Modulus", p)(
"SubgroupOrder", q)(
"SubgroupGenerator", g));}
240 {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);}
242 {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);}
244 {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);}
264 template <
class BASE>
275 if (seq.EndReached())
277 this->AccessGroupParameters().Initialize(v1, v1/2, v2);
278 this->SetPublicElement(v3);
283 this->AccessGroupParameters().Initialize(v1, v2, v3);
284 this->SetPublicElement(v4);
293 this->GetGroupParameters().GetModulus().DEREncode(seq);
294 if (this->GetGroupParameters().GetCofactor() != 2)
295 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
296 this->GetGroupParameters().GetGenerator().DEREncode(seq);
297 this->GetPublicElement().DEREncode(seq);
303 template <
class BASE>
315 if (seq.EndReached())
317 this->AccessGroupParameters().Initialize(v1, v1/2, v2);
318 this->SetPrivateExponent(v4 % (v1/2));
323 this->AccessGroupParameters().Initialize(v1, v2, v3);
324 this->SetPrivateExponent(v5);
333 this->GetGroupParameters().GetModulus().DEREncode(seq);
334 if (this->GetGroupParameters().GetCofactor() != 2)
335 this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
336 this->GetGroupParameters().GetGenerator().DEREncode(seq);
337 this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq);
338 this->GetPrivateExponent().DEREncode(seq);
346 DL_SignatureKeys_GFP,
347 DL_Algorithm_GDSA<Integer>,
348 DL_SignatureMessageEncodingMethod_DSA,
356 DL_SignatureKeys_GFP,
357 DL_Algorithm_NR<Integer>,
358 DL_SignatureMessageEncodingMethod_NR,
386 DL_Algorithm_GDSA<Integer>,
387 DL_SignatureMessageEncodingMethod_DSA,
391 static const char * CRYPTOPP_API StaticAlgorithmName() {
return "DSA";}
398 static bool CRYPTOPP_API GeneratePrimes(
const byte *seed,
unsigned int seedLength,
int &counter,
399 Integer &p,
unsigned int primeLength,
Integer &q,
bool useInputCounterValue =
false);
401 static bool CRYPTOPP_API IsValidPrimeLength(
unsigned int pbits)
402 {
return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
406 #if (DSA_1024_BIT_MODULUS_ONLY)
407 MIN_PRIME_LENGTH = 1024,
409 MIN_PRIME_LENGTH = 512,
411 MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64};
419 template <
class MAC,
bool DHAES_MODE>
424 size_t GetSymmetricKeyLength(
size_t plaintextLength)
const
425 {
return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
426 size_t GetSymmetricCiphertextLength(
size_t plaintextLength)
const
427 {
return plaintextLength + MAC::DIGESTSIZE;}
428 size_t GetMaxSymmetricPlaintextLength(
size_t ciphertextLength)
const
429 {
return (
unsigned int)SaturatingSubtract(ciphertextLength, (
unsigned int)MAC::DIGESTSIZE);}
430 void SymmetricEncrypt(
RandomNumberGenerator &rng,
const byte *key,
const byte *plaintext,
size_t plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters)
const
432 const byte *cipherKey, *macKey;
436 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
441 macKey = key + plaintextLength;
447 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
449 mac.Update(ciphertext, plaintextLength);
450 mac.Update(encodingParameters.begin(), encodingParameters.size());
453 byte L[8] = {0,0,0,0};
454 PutWord(
false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
457 mac.Final(ciphertext + plaintextLength);
459 DecodingResult SymmetricDecrypt(
const byte *key,
const byte *ciphertext,
size_t ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters)
const
461 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
462 const byte *cipherKey, *macKey;
466 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
471 macKey = key + plaintextLength;
478 mac.Update(ciphertext, plaintextLength);
479 mac.Update(encodingParameters.begin(), encodingParameters.size());
482 byte L[8] = {0,0,0,0};
483 PutWord(
false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
486 if (!mac.Verify(ciphertext + plaintextLength))
489 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
495 template <
class T,
bool DHAES_MODE,
class KDF>
500 void Derive(
const DL_GroupParameters<T> ¶ms, byte *derivedKey,
size_t derivedLength,
const T &agreedElement,
const T &ephemeralPublicKey,
const NameValuePairs ¶meters)
const
505 agreedSecret.
New(params.GetEncodedElementSize(
true) + params.GetEncodedElementSize(
false));
506 params.EncodeElement(
true, ephemeralPublicKey, agreedSecret);
507 params.EncodeElement(
false, agreedElement, agreedSecret + params.GetEncodedElementSize(
true));
511 agreedSecret.
New(params.GetEncodedElementSize(
false));
512 params.EncodeElement(
false, agreedElement, agreedSecret);
517 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
522 template <
class COFACTOR_OPTION = NoCofactorMultiplication,
bool DHAES_MODE = true>
526 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
527 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
528 DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
531 static std::string CRYPTOPP_API StaticAlgorithmName() {
return "DLIES";}
used to pass byte array input as part of a NameValuePairs object
Discrete Log Integrated Encryption Scheme, AKA DLIES
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
static const Integer & One()
avoid calling constructors for these frequently used integers
Discrete Log Based Signature Scheme.
This file contains helper classes/functions for implementing public key algorithms.
interface for DL group parameters
the XOR encryption method, for use with DL-based cryptosystems
GF(p) group parameters that default to same primes.
interface for key derivation algorithms used in DL cryptosystems
interface for random number generators
void New(size_type newSize)
change size, without preserving contents
Discrete Log Based Encryption Scheme.
interface for DL public keys
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
used to return decoding results
bool GetValue(const char *name, T &value) const
get a named value, returns true if the name exists
interface for Elgamal-like signature algorithms
const char * EncodingParameters()
ConstByteArrayParameter.
DL signing/verification keys (in GF(p) groups)
DL encryption/decryption keys (in GF(p) groups)
multiple precision integer and basic arithmetics
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard...
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
DL private key (in GF(p) groups)
Integer InverseMod(const Integer &n) const
calculate multiplicative inverse of *this mod n
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
calls the above function with a NameValuePairs object that just specifies "KeySize" ...
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
void DEREncodePublicKey(BufferedTransformation &bt) const
encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
const char * KeyDerivationParameters()
ConstByteArrayParameter.
interface for symmetric encryption algorithms used in DL cryptosystems
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms)
generate a random key or crypto parameters
void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t)
decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header ...
interface for retrieving values given their names