First Commit
This commit is contained in:
334
externals/cryptopp/gfpcrypt.cpp
vendored
Normal file
334
externals/cryptopp/gfpcrypt.cpp
vendored
Normal file
@@ -0,0 +1,334 @@
|
||||
// dsa.cpp - originally written and placed in the public domain by Wei Dai
|
||||
|
||||
#include "pch.h"
|
||||
#include "config.h"
|
||||
|
||||
// TODO: fix the C4589 warnings
|
||||
#if CRYPTOPP_MSC_VERSION
|
||||
# pragma warning(disable: 4189 4589)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPTOPP_IMPORTS
|
||||
|
||||
#include "gfpcrypt.h"
|
||||
#include "nbtheory.h"
|
||||
#include "modarith.h"
|
||||
#include "integer.h"
|
||||
#include "asn.h"
|
||||
#include "oids.h"
|
||||
#include "misc.h"
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
|
||||
void TestInstantiations_gfpcrypt()
|
||||
{
|
||||
GDSA<SHA1>::Signer test;
|
||||
GDSA<SHA1>::Verifier test1;
|
||||
DSA::Signer test5(NullRNG(), 100);
|
||||
DSA::Signer test2(test5);
|
||||
NR<SHA1>::Signer test3;
|
||||
NR<SHA1>::Verifier test4;
|
||||
DLIES<>::Encryptor test6;
|
||||
DLIES<>::Decryptor test7;
|
||||
}
|
||||
#endif
|
||||
|
||||
void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
|
||||
{
|
||||
Integer p, q, g;
|
||||
|
||||
if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
|
||||
{
|
||||
q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
|
||||
Initialize(p, q, g);
|
||||
}
|
||||
else
|
||||
{
|
||||
int modulusSize = 2048, defaultSubgroupOrderSize;
|
||||
alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize);
|
||||
|
||||
switch (modulusSize)
|
||||
{
|
||||
case 1024:
|
||||
defaultSubgroupOrderSize = 160;
|
||||
break;
|
||||
case 2048:
|
||||
defaultSubgroupOrderSize = 224;
|
||||
break;
|
||||
case 3072:
|
||||
defaultSubgroupOrderSize = 256;
|
||||
break;
|
||||
default:
|
||||
throw InvalidArgument("DSA: not a valid prime length");
|
||||
}
|
||||
|
||||
DL_GroupParameters_GFP::GenerateRandom(rng, CombinedNameValuePairs(alg, MakeParameters(Name::SubgroupOrderSize(), defaultSubgroupOrderSize, false)));
|
||||
}
|
||||
}
|
||||
|
||||
bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
|
||||
{
|
||||
bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level);
|
||||
CRYPTOPP_ASSERT(pass);
|
||||
|
||||
const int pSize = GetModulus().BitCount(), qSize = GetSubgroupOrder().BitCount();
|
||||
pass = pass && ((pSize==1024 && qSize==160) || (pSize==2048 && qSize==224) || (pSize==2048 && qSize==256) || (pSize==3072 && qSize==256));
|
||||
CRYPTOPP_ASSERT(pass);
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng,
|
||||
const byte *recoverableMessage, size_t recoverableMessageLength,
|
||||
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
|
||||
byte *representative, size_t representativeBitLength) const
|
||||
{
|
||||
CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(recoverableMessage), CRYPTOPP_UNUSED(recoverableMessageLength);
|
||||
CRYPTOPP_UNUSED(messageEmpty), CRYPTOPP_UNUSED(hashIdentifier);
|
||||
CRYPTOPP_ASSERT(recoverableMessageLength == 0);
|
||||
CRYPTOPP_ASSERT(hashIdentifier.second == 0);
|
||||
|
||||
const size_t representativeByteLength = BitsToBytes(representativeBitLength);
|
||||
const size_t digestSize = hash.DigestSize();
|
||||
const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
|
||||
|
||||
std::memset(representative, 0, paddingLength);
|
||||
hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
|
||||
|
||||
if (digestSize*8 > representativeBitLength)
|
||||
{
|
||||
Integer h(representative, representativeByteLength);
|
||||
h >>= representativeByteLength*8 - representativeBitLength;
|
||||
h.Encode(representative, representativeByteLength);
|
||||
}
|
||||
}
|
||||
|
||||
void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng,
|
||||
const byte *recoverableMessage, size_t recoverableMessageLength,
|
||||
HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty,
|
||||
byte *representative, size_t representativeBitLength) const
|
||||
{
|
||||
CRYPTOPP_UNUSED(rng);CRYPTOPP_UNUSED(recoverableMessage); CRYPTOPP_UNUSED(recoverableMessageLength);
|
||||
CRYPTOPP_UNUSED(hash); CRYPTOPP_UNUSED(hashIdentifier); CRYPTOPP_UNUSED(messageEmpty);
|
||||
CRYPTOPP_UNUSED(representative); CRYPTOPP_UNUSED(representativeBitLength);
|
||||
|
||||
CRYPTOPP_ASSERT(recoverableMessageLength == 0);
|
||||
CRYPTOPP_ASSERT(hashIdentifier.second == 0);
|
||||
const size_t representativeByteLength = BitsToBytes(representativeBitLength);
|
||||
const size_t digestSize = hash.DigestSize();
|
||||
const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize);
|
||||
|
||||
std::memset(representative, 0, paddingLength);
|
||||
hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize));
|
||||
|
||||
if (digestSize*8 >= representativeBitLength)
|
||||
{
|
||||
Integer h(representative, representativeByteLength);
|
||||
h >>= representativeByteLength*8 - representativeBitLength + 1;
|
||||
h.Encode(representative, representativeByteLength);
|
||||
}
|
||||
}
|
||||
|
||||
bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
|
||||
{
|
||||
const Integer &p = GetModulus(), &q = GetSubgroupOrder();
|
||||
bool pass = true;
|
||||
|
||||
CRYPTOPP_ASSERT(p > Integer::One() && p.IsOdd());
|
||||
pass = pass && p > Integer::One() && p.IsOdd();
|
||||
|
||||
CRYPTOPP_ASSERT(q > Integer::One() && q.IsOdd());
|
||||
pass = pass && q > Integer::One() && q.IsOdd();
|
||||
|
||||
if (level >= 1)
|
||||
{
|
||||
CRYPTOPP_ASSERT(GetCofactor() > Integer::One());
|
||||
CRYPTOPP_ASSERT(GetGroupOrder() % q == Integer::Zero());
|
||||
|
||||
pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
|
||||
}
|
||||
if (level >= 2)
|
||||
{
|
||||
CRYPTOPP_ASSERT(VerifyPrime(rng, q, level-2));
|
||||
CRYPTOPP_ASSERT(VerifyPrime(rng, p, level-2));
|
||||
|
||||
pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
|
||||
{
|
||||
const Integer &p = GetModulus(), &q = GetSubgroupOrder();
|
||||
bool pass = true;
|
||||
|
||||
CRYPTOPP_ASSERT(GetFieldType() == 1 ? g.IsPositive() : g.NotNegative());
|
||||
pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
|
||||
|
||||
CRYPTOPP_ASSERT(g < p && !IsIdentity(g));
|
||||
pass = pass && g < p && !IsIdentity(g);
|
||||
|
||||
if (level >= 1)
|
||||
{
|
||||
if (gpc)
|
||||
{
|
||||
CRYPTOPP_ASSERT(gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g);
|
||||
pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
|
||||
}
|
||||
}
|
||||
if (level >= 2)
|
||||
{
|
||||
if (GetFieldType() == 2)
|
||||
{
|
||||
CRYPTOPP_ASSERT(Jacobi(g*g-4, p)==-1);
|
||||
pass = pass && Jacobi(g*g-4, p)==-1;
|
||||
}
|
||||
|
||||
// verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
|
||||
// and at most 1 bit is leaked if it's false
|
||||
bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable();
|
||||
|
||||
if (fullValidate && pass)
|
||||
{
|
||||
Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
|
||||
CRYPTOPP_ASSERT(IsIdentity(gp));
|
||||
pass = pass && IsIdentity(gp);
|
||||
}
|
||||
else if (GetFieldType() == 1)
|
||||
{
|
||||
CRYPTOPP_ASSERT(Jacobi(g, p) == 1);
|
||||
pass = pass && Jacobi(g, p) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
|
||||
{
|
||||
Integer p, q, g;
|
||||
|
||||
if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g))
|
||||
{
|
||||
q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
int modulusSize, subgroupOrderSize;
|
||||
|
||||
if (!alg.GetIntValue("ModulusSize", modulusSize))
|
||||
modulusSize = alg.GetIntValueWithDefault("KeySize", 2048);
|
||||
|
||||
if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize))
|
||||
subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize);
|
||||
|
||||
PrimeAndGenerator pg;
|
||||
pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize);
|
||||
p = pg.Prime();
|
||||
q = pg.SubPrime();
|
||||
g = pg.Generator();
|
||||
}
|
||||
|
||||
Initialize(p, q, g);
|
||||
}
|
||||
|
||||
void DL_GroupParameters_IntegerBased::EncodeElement(bool reversible, const Element &element, byte *encoded) const
|
||||
{
|
||||
CRYPTOPP_UNUSED(reversible);
|
||||
element.Encode(encoded, GetModulus().ByteCount());
|
||||
}
|
||||
|
||||
unsigned int DL_GroupParameters_IntegerBased::GetEncodedElementSize(bool reversible) const
|
||||
{
|
||||
CRYPTOPP_UNUSED(reversible);
|
||||
return GetModulus().ByteCount();
|
||||
}
|
||||
|
||||
Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const
|
||||
{
|
||||
CRYPTOPP_UNUSED(checkForGroupMembership);
|
||||
Integer g(encoded, GetModulus().ByteCount());
|
||||
if (!ValidateElement(1, g, NULLPTR))
|
||||
throw DL_BadElement();
|
||||
return g;
|
||||
}
|
||||
|
||||
void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt)
|
||||
{
|
||||
BERSequenceDecoder parameters(bt);
|
||||
Integer p(parameters);
|
||||
Integer q(parameters);
|
||||
Integer g;
|
||||
if (parameters.EndReached())
|
||||
{
|
||||
g = q;
|
||||
q = ComputeGroupOrder(p) / 2;
|
||||
}
|
||||
else
|
||||
g.BERDecode(parameters);
|
||||
parameters.MessageEnd();
|
||||
|
||||
SetModulusAndSubgroupGenerator(p, g);
|
||||
SetSubgroupOrder(q);
|
||||
}
|
||||
|
||||
void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const
|
||||
{
|
||||
DERSequenceEncoder parameters(bt);
|
||||
GetModulus().DEREncode(parameters);
|
||||
m_q.DEREncode(parameters);
|
||||
GetSubgroupGenerator().DEREncode(parameters);
|
||||
parameters.MessageEnd();
|
||||
}
|
||||
|
||||
bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
||||
{
|
||||
return GetValueHelper<DL_GroupParameters<Element> >(this, name, valueType, pValue)
|
||||
CRYPTOPP_GET_FUNCTION_ENTRY(Modulus);
|
||||
}
|
||||
|
||||
void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source)
|
||||
{
|
||||
AssignFromHelper(this, source)
|
||||
CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator)
|
||||
CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
|
||||
;
|
||||
}
|
||||
|
||||
OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const
|
||||
{
|
||||
return ASN1::id_dsa();
|
||||
}
|
||||
|
||||
void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const
|
||||
{
|
||||
ModularArithmetic ma(GetModulus());
|
||||
ma.SimultaneousExponentiate(results, base, exponents, exponentsCount);
|
||||
}
|
||||
|
||||
DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const
|
||||
{
|
||||
return a_times_b_mod_c(a, b, GetModulus());
|
||||
}
|
||||
|
||||
DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const
|
||||
{
|
||||
ModularArithmetic ma(GetModulus());
|
||||
return ma.CascadeExponentiate(element1, exponent1, element2, exponent2);
|
||||
}
|
||||
|
||||
Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const
|
||||
{
|
||||
return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount())));
|
||||
}
|
||||
|
||||
unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const
|
||||
{
|
||||
return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize);
|
||||
}
|
||||
|
||||
NAMESPACE_END
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user