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,
373 static bool CRYPTOPP_API IsValidPrimeLength(
unsigned int pbits)
374 {
return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
376 enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
394 DL_Algorithm_GDSA<Integer>,
395 DL_SignatureMessageEncodingMethod_DSA,
400 static std::string CRYPTOPP_API StaticAlgorithmName() {
return "DSA/" + (std::string)H::StaticAlgorithmName();}
411 template <
class MAC,
bool DHAES_MODE>
416 size_t GetSymmetricKeyLength(
size_t plaintextLength)
const
417 {
return plaintextLength + MAC::DEFAULT_KEYLENGTH;}
418 size_t GetSymmetricCiphertextLength(
size_t plaintextLength)
const
419 {
return plaintextLength + MAC::DIGESTSIZE;}
420 size_t GetMaxSymmetricPlaintextLength(
size_t ciphertextLength)
const
421 {
return (
unsigned int)SaturatingSubtract(ciphertextLength, (
unsigned int)MAC::DIGESTSIZE);}
422 void SymmetricEncrypt(
RandomNumberGenerator &rng,
const byte *key,
const byte *plaintext,
size_t plaintextLength, byte *ciphertext,
const NameValuePairs ¶meters)
const
424 const byte *cipherKey, *macKey;
428 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
433 macKey = key + plaintextLength;
439 xorbuf(ciphertext, plaintext, cipherKey, plaintextLength);
441 mac.Update(ciphertext, plaintextLength);
442 mac.Update(encodingParameters.begin(), encodingParameters.size());
445 byte L[8] = {0,0,0,0};
446 PutWord(
false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
449 mac.Final(ciphertext + plaintextLength);
451 DecodingResult SymmetricDecrypt(
const byte *key,
const byte *ciphertext,
size_t ciphertextLength, byte *plaintext,
const NameValuePairs ¶meters)
const
453 size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength);
454 const byte *cipherKey, *macKey;
458 cipherKey = key + MAC::DEFAULT_KEYLENGTH;
463 macKey = key + plaintextLength;
470 mac.Update(ciphertext, plaintextLength);
471 mac.Update(encodingParameters.begin(), encodingParameters.size());
474 byte L[8] = {0,0,0,0};
475 PutWord(
false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size()));
478 if (!mac.Verify(ciphertext + plaintextLength))
481 xorbuf(plaintext, ciphertext, cipherKey, plaintextLength);
487 template <
class T,
bool DHAES_MODE,
class KDF>
492 void Derive(
const DL_GroupParameters<T> ¶ms, byte *derivedKey,
size_t derivedLength,
const T &agreedElement,
const T &ephemeralPublicKey,
const NameValuePairs ¶meters)
const
497 agreedSecret.
New(params.GetEncodedElementSize(
true) + params.GetEncodedElementSize(
false));
498 params.EncodeElement(
true, ephemeralPublicKey, agreedSecret);
499 params.EncodeElement(
false, agreedElement, agreedSecret + params.GetEncodedElementSize(
true));
503 agreedSecret.
New(params.GetEncodedElementSize(
false));
504 params.EncodeElement(
false, agreedElement, agreedSecret);
509 KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size());
514 template <
class COFACTOR_OPTION = NoCofactorMultiplication,
bool DHAES_MODE = true>
518 DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
519 DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
520 DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
523 static std::string CRYPTOPP_API StaticAlgorithmName() {
return "DLIES";}
used to pass byte array input as part of a NameValuePairs object
DSA2< SHA > DSA
DSA with SHA-1, typedef'd for backwards compatibility.
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 ...
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.
static const Integer & One()
avoid calling constructors for these frequently used integers
interface for DL public keys
Discrete Log Based Signature Scheme.
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
DSA, as specified in FIPS 186-3
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