📄 gfpcrypt.h
字号:
};
//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
template <class BASE>
class DL_PublicKey_GFP_OldFormat : public BASE
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
Integer v1(seq);
Integer v2(seq);
Integer v3(seq);
if (seq.EndReached())
{
AccessGroupParameters().Initialize(v1, v1/2, v2);
SetPublicElement(v3);
}
else
{
Integer v4(seq);
AccessGroupParameters().Initialize(v1, v2, v3);
SetPublicElement(v4);
}
seq.MessageEnd();
}
void DEREncode(BufferedTransformation &bt) const
{
DERSequenceEncoder seq(bt);
GetGroupParameters().GetModulus().DEREncode(seq);
if (GetGroupParameters().GetCofactor() != 2)
GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
GetGroupParameters().GetGenerator().DEREncode(seq);
GetPublicElement().DEREncode(seq);
seq.MessageEnd();
}
};
//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format
template <class BASE>
class DL_PrivateKey_GFP_OldFormat : public BASE
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
Integer v1(seq);
Integer v2(seq);
Integer v3(seq);
Integer v4(seq);
if (seq.EndReached())
{
AccessGroupParameters().Initialize(v1, v1/2, v2);
SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q
}
else
{
Integer v5(seq);
AccessGroupParameters().Initialize(v1, v2, v3);
SetPrivateExponent(v5);
}
seq.MessageEnd();
}
void DEREncode(BufferedTransformation &bt) const
{
DERSequenceEncoder seq(bt);
GetGroupParameters().GetModulus().DEREncode(seq);
if (GetGroupParameters().GetCofactor() != 2)
GetGroupParameters().GetSubgroupOrder().DEREncode(seq);
GetGroupParameters().GetGenerator().DEREncode(seq);
GetGroupParameters().ExponentiateBase(GetPrivateExponent()).DEREncode(seq);
GetPrivateExponent().DEREncode(seq);
seq.MessageEnd();
}
};
//! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
template <class H>
struct GDSA : public DL_SS<
DL_SignatureKeys_GFP,
DL_Algorithm_GDSA<Integer>,
DL_SignatureMessageEncodingMethod_DSA,
H>
{
};
//! <a href="http://www.weidai.com/scan-mirror/sig.html#NR">NR</a>
template <class H>
struct NR : public DL_SS<
DL_SignatureKeys_GFP,
DL_Algorithm_NR<Integer>,
DL_SignatureMessageEncodingMethod_NR,
H>
{
};
//! .
class DL_GroupParameters_DSA : public DL_GroupParameters_GFP
{
public:
/*! also checks that the lengths of p and q are allowed by the DSA standard */
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
/*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */
/*! ModulusSize must be between 512 and 1024, and divisible by 64 */
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
};
struct DSA;
//! .
struct DL_Keys_DSA
{
typedef DL_PublicKey_GFP<DL_GroupParameters_DSA> PublicKey;
typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_GFP<DL_GroupParameters_DSA>, DSA> PrivateKey;
};
//! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA">DSA</a>
struct DSA : public DL_SS<
DL_Keys_DSA,
DL_Algorithm_GDSA<Integer>,
DL_SignatureMessageEncodingMethod_DSA,
SHA,
DSA>
{
static std::string StaticAlgorithmName() {return std::string("DSA");}
//! Generate DSA primes according to NIST standard
/*! Both seedLength and primeLength are in bits, but seedLength should
be a multiple of 8.
If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output
*/
static bool GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter,
Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false);
static bool IsValidPrimeLength(unsigned int pbits)
{return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;}
enum {
#if (DSA_1024_BIT_MODULUS_ONLY)
MIN_PRIME_LENGTH = 1024,
#else
MIN_PRIME_LENGTH = 512,
#endif
MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64};
};
//! .
template <class MAC, bool DHAES_MODE>
class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm
{
public:
unsigned int GetSymmetricKeyLength(unsigned int plainTextLength) const
{return plainTextLength + MAC::DEFAULT_KEYLENGTH;}
unsigned int GetSymmetricCiphertextLength(unsigned int plainTextLength) const
{return plainTextLength + MAC::DIGESTSIZE;}
unsigned int GetMaxSymmetricPlaintextLength(unsigned int cipherTextLength) const
{return SaturatingSubtract(cipherTextLength, (unsigned int)MAC::DIGESTSIZE);}
void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, unsigned int plainTextLength, byte *cipherText) const
{
const byte *cipherKey, *macKey;
if (DHAES_MODE)
{
macKey = key;
cipherKey = key + MAC::DEFAULT_KEYLENGTH;
}
else
{
cipherKey = key;
macKey = key + plainTextLength;
}
xorbuf(cipherText, plainText, cipherKey, plainTextLength);
MAC mac(macKey);
mac.Update(cipherText, plainTextLength);
if (DHAES_MODE)
{
const byte L[8] = {0,0,0,0,0,0,0,0};
mac.Update(L, 8);
}
mac.Final(cipherText + plainTextLength);
}
DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, unsigned int cipherTextLength, byte *plainText) const
{
unsigned int plainTextLength = GetMaxSymmetricPlaintextLength(cipherTextLength);
const byte *cipherKey, *macKey;
if (DHAES_MODE)
{
macKey = key;
cipherKey = key + MAC::DEFAULT_KEYLENGTH;
}
else
{
cipherKey = key;
macKey = key + plainTextLength;
}
MAC mac(macKey);
mac.Update(cipherText, plainTextLength);
if (DHAES_MODE)
{
const byte L[8] = {0,0,0,0,0,0,0,0};
mac.Update(L, 8);
}
if (!mac.Verify(cipherText + plainTextLength))
return DecodingResult();
xorbuf(plainText, cipherText, cipherKey, plainTextLength);
return DecodingResult(plainTextLength);
}
};
//! .
template <class T, bool DHAES_MODE, class KDF>
class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm<T>
{
public:
void Derive(const DL_GroupParameters<T> ¶ms, byte *derivedKey, unsigned int derivedLength, const T &agreedElement, const T &ephemeralPublicKey) const
{
SecByteBlock agreedSecret;
if (DHAES_MODE)
{
agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false));
params.EncodeElement(true, ephemeralPublicKey, agreedSecret);
params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true));
}
else
{
agreedSecret.New(params.GetEncodedElementSize(false));
params.EncodeElement(false, agreedElement, agreedSecret);
}
KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size());
}
};
//! Discrete Log Integrated Encryption Scheme, AKA <a href="http://www.weidai.com/scan-mirror/ca.html#DLIES">DLIES</a>
template <class COFACTOR_OPTION = NoCofactorMultiplication, bool DHAES_MODE = true>
struct DLIES
: public DL_ES<
DL_CryptoKeys_GFP,
DL_KeyAgreementAlgorithm_DH<Integer, COFACTOR_OPTION>,
DL_KeyDerivationAlgorithm_P1363<Integer, DHAES_MODE, P1363_KDF2<SHA1> >,
DL_EncryptionAlgorithm_Xor<HMAC<SHA1>, DHAES_MODE>,
DLIES<> >
{
static std::string StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized
};
NAMESPACE_END
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -