parent
4d7cb70ea8
commit
5cc29e0e05
16
eccrypto.h
16
eccrypto.h
|
|
@ -225,7 +225,7 @@ struct DL_Keys_EC
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class EC, class H>
|
template <class EC, class H, bool useDetK = false>
|
||||||
struct ECDSA;
|
struct ECDSA;
|
||||||
|
|
||||||
//! ECDSA keys
|
//! ECDSA keys
|
||||||
|
|
@ -241,8 +241,8 @@ struct DL_Keys_ECDSA
|
||||||
};
|
};
|
||||||
|
|
||||||
//! ECDSA algorithm
|
//! ECDSA algorithm
|
||||||
template <class EC>
|
template <class EC, class H, bool useDetK = false>
|
||||||
class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point>
|
class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA<typename EC::Point, H, useDetK>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
|
static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
|
||||||
|
|
@ -265,8 +265,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
|
//! <a href="http://www.weidai.com/scan-mirror/sig.html#ECDSA">ECDSA</a>
|
||||||
template <class EC, class H>
|
template <class EC, class H, bool useDetK>
|
||||||
struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_SignatureMessageEncodingMethod_DSA, H>
|
struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC, H, useDetK>, DL_SignatureMessageEncodingMethod_DSA, H>
|
||||||
{
|
{
|
||||||
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
||||||
virtual ~ECDSA() {}
|
virtual ~ECDSA() {}
|
||||||
|
|
@ -327,8 +327,10 @@ CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<ECP> >;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl<DL_GroupParameters_EC<EC2N> >;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<ECP>;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC<EC2N>;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point>;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point, SHA256, false>;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point>;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<ECP::Point, SHA256, true>;
|
||||||
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point, SHA256, false>;
|
||||||
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<EC2N::Point, SHA256, true>;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<ECP>, ECDSA<ECP, SHA256> >;
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest<DL_PrivateKey_EC<EC2N>, ECDSA<EC2N, SHA256> >;
|
||||||
|
|
||||||
|
|
|
||||||
154
gfpcrypt.h
154
gfpcrypt.h
|
|
@ -181,7 +181,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
//! GDSA algorithm
|
//! GDSA algorithm
|
||||||
template <class T>
|
template <class T, class H, bool useDetK>
|
||||||
class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T>
|
class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm<T>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -209,12 +209,150 @@ public:
|
||||||
return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
|
return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UseDeterministicK() const
|
||||||
|
{
|
||||||
|
return useDetK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates a k-value based on RFC 6979. Uses the message to hash and its size,
|
||||||
|
// the curve order and its bit length, and a private key. Returns true to
|
||||||
|
// indicate that the returned k-value is valid.
|
||||||
|
const bool getDetKVal(const byte* hmsg, const size_t& hmsgSize,
|
||||||
|
const Integer& cord, const size_t& cordBits,
|
||||||
|
const Integer& pk, Integer& kVal) const
|
||||||
|
{
|
||||||
|
// After doing the initial setup, get the msg hash and work towards the final
|
||||||
|
// k value, per the spec.
|
||||||
|
SecByteBlock zeroByte(1);
|
||||||
|
SecByteBlock oneByte(1);
|
||||||
|
memset(zeroByte, '\x00', 1);
|
||||||
|
memset(oneByte, '\x01', 1);
|
||||||
|
|
||||||
|
size_t cordBytes = (cordBits + 7) / 8;
|
||||||
|
SecByteBlock hkey(H::DIGESTSIZE);
|
||||||
|
memset(hkey, '\x00', H::DIGESTSIZE);
|
||||||
|
K.SetKey(hkey, hkey.size());
|
||||||
|
SecByteBlock msgHash(K.DIGESTSIZE);
|
||||||
|
SecByteBlock V(K.DIGESTSIZE);
|
||||||
|
SecByteBlock prvKeyBlock = int2octets(pk, (const unsigned int)cordBytes);
|
||||||
|
memset(V, '\x01', K.DIGESTSIZE);
|
||||||
|
hashFunct.CalculateDigest(msgHash, hmsg, hmsgSize);
|
||||||
|
|
||||||
|
SecByteBlock octetMsg = bits2octets(msgHash, cord, cordBits);
|
||||||
|
SecByteBlock hmacInput1 = V + zeroByte + prvKeyBlock + octetMsg;
|
||||||
|
K.CalculateDigest(hkey, hmacInput1, hmacInput1.size());
|
||||||
|
|
||||||
|
K.SetKey(hkey, hkey.size());
|
||||||
|
K.CalculateDigest(V, V, V.size());
|
||||||
|
|
||||||
|
SecByteBlock hmacInput2 = V + oneByte + prvKeyBlock + octetMsg;
|
||||||
|
K.CalculateDigest(hkey, hmacInput2, hmacInput2.size());
|
||||||
|
|
||||||
|
K.SetKey(hkey, hkey.size());
|
||||||
|
K.CalculateDigest(V, V, V.size());
|
||||||
|
|
||||||
|
Integer retVal;
|
||||||
|
for(bool done = false; done != true; )
|
||||||
|
{
|
||||||
|
SecByteBlock b2iData;
|
||||||
|
for(size_t s = 0; s < cordBytes; s += hkey.size())
|
||||||
|
{
|
||||||
|
K.CalculateDigest(V, V, V.size());
|
||||||
|
b2iData += V;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Odds of failure are practically nil but we must play it safe.
|
||||||
|
Integer b2i = bits2int(b2iData, (const unsigned int)cordBits);
|
||||||
|
if(b2i >= Integer::One() && b2i < cord)
|
||||||
|
{
|
||||||
|
retVal = b2i;
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SecByteBlock newHMACInput = V + zeroByte;
|
||||||
|
K.CalculateDigest(hkey, newHMACInput, newHMACInput.size());
|
||||||
|
|
||||||
|
K.SetKey(hkey, hkey.size());
|
||||||
|
K.CalculateDigest(V, V, V.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Before running the k-val, hash & HMAC functs need to be cleared.
|
||||||
|
// CalculateDigest() does this every time, though, so we're good.
|
||||||
|
kVal = retVal;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
|
||||||
virtual ~DL_Algorithm_GDSA() {}
|
virtual ~DL_Algorithm_GDSA() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// RFC 6979 support function. Takes a set of bits, takes the most significant
|
||||||
|
// bytes (subject to a given bit limit), and turns them into an integer.
|
||||||
|
Integer bits2int(const SecByteBlock& bits, const unsigned int& qlen) const
|
||||||
|
{
|
||||||
|
Integer retVal(bits, bits.size());
|
||||||
|
if((retVal.ByteCount() * 8) > qlen)
|
||||||
|
{
|
||||||
|
retVal >>= ((retVal.ByteCount() * 8) - qlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RFC 6979 support function. Takes an integer and converts it into bytes that
|
||||||
|
// are the same length as an elliptic curve's order.
|
||||||
|
SecByteBlock int2octets(const Integer& val, const unsigned int& rlenBytes) const
|
||||||
|
{
|
||||||
|
SecByteBlock octetBlock(val.ByteCount());
|
||||||
|
val.Encode(octetBlock, val.ByteCount());
|
||||||
|
SecByteBlock retVal = octetBlock;
|
||||||
|
|
||||||
|
// The least significant bytes are the ones we need to preserve.
|
||||||
|
if(octetBlock.size() > rlenBytes)
|
||||||
|
{
|
||||||
|
SecByteBlock octetBlock1(rlenBytes);
|
||||||
|
size_t offset = octetBlock.size() - rlenBytes;
|
||||||
|
memcpy(octetBlock1, octetBlock + offset, rlenBytes);
|
||||||
|
retVal = octetBlock1;
|
||||||
|
}
|
||||||
|
else if(octetBlock.size() < rlenBytes)
|
||||||
|
{
|
||||||
|
SecByteBlock octetBlock2(rlenBytes);
|
||||||
|
memset(octetBlock2, '\x00', rlenBytes);
|
||||||
|
size_t offset = rlenBytes - octetBlock.size();
|
||||||
|
memcpy(octetBlock2 + offset, octetBlock, rlenBytes - offset);
|
||||||
|
retVal = octetBlock2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn a stream of bits into a set of bytes with the same length as an elliptic
|
||||||
|
// curve's order.
|
||||||
|
SecByteBlock bits2octets(const SecByteBlock& inData, const Integer& curveOrder,
|
||||||
|
const size_t& curveOrderNumBits) const
|
||||||
|
{
|
||||||
|
Integer bintTemp = bits2int(inData, (const unsigned int)curveOrderNumBits);
|
||||||
|
Integer bint = bintTemp - curveOrder;
|
||||||
|
return int2octets(bint.IsNegative() ? bintTemp : bint,
|
||||||
|
curveOrder.ByteCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get() returns const ref
|
||||||
|
const H& GetHash() const { return const_cast<const H&>(hashFunct); }
|
||||||
|
const HMAC<H>& GetHMAC() const { return const_cast<const HMAC<H>&>(K); }
|
||||||
|
// Access() returns non-const ref
|
||||||
|
H& AccessHash() { return hashFunct; }
|
||||||
|
HMAC<H>& AccessHMAC() { return K; }
|
||||||
|
private:
|
||||||
|
mutable H hashFunct;
|
||||||
|
mutable HMAC<H> K;
|
||||||
};
|
};
|
||||||
|
|
||||||
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer, SHA256, false>;
|
||||||
|
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer, SHA256, true>;
|
||||||
|
|
||||||
//! NR algorithm
|
//! NR algorithm
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -406,10 +544,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
//! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
|
//! <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
|
||||||
template <class H>
|
template <class H, bool useDetK = false>
|
||||||
struct GDSA : public DL_SS<
|
struct GDSA : public DL_SS<
|
||||||
DL_SignatureKeys_GFP,
|
DL_SignatureKeys_GFP,
|
||||||
DL_Algorithm_GDSA<Integer>,
|
DL_Algorithm_GDSA<Integer, H, useDetK>,
|
||||||
DL_SignatureMessageEncodingMethod_DSA,
|
DL_SignatureMessageEncodingMethod_DSA,
|
||||||
H>
|
H>
|
||||||
{
|
{
|
||||||
|
|
@ -451,7 +589,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class H>
|
template <class H, bool useDetK = false>
|
||||||
class DSA2;
|
class DSA2;
|
||||||
|
|
||||||
//! DSA keys
|
//! DSA keys
|
||||||
|
|
@ -467,13 +605,13 @@ struct DL_Keys_DSA
|
||||||
|
|
||||||
//! <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3
|
//! <a href="http://en.wikipedia.org/wiki/Digital_Signature_Algorithm">DSA</a>, as specified in FIPS 186-3
|
||||||
// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class)
|
// class named DSA2 instead of DSA for backwards compatibility (DSA was a non-template class)
|
||||||
template <class H>
|
template <class H, bool useDetK>
|
||||||
class DSA2 : public DL_SS<
|
class DSA2 : public DL_SS<
|
||||||
DL_Keys_DSA,
|
DL_Keys_DSA,
|
||||||
DL_Algorithm_GDSA<Integer>,
|
DL_Algorithm_GDSA<Integer, H, useDetK>,
|
||||||
DL_SignatureMessageEncodingMethod_DSA,
|
DL_SignatureMessageEncodingMethod_DSA,
|
||||||
H,
|
H,
|
||||||
DSA2<H> >
|
DSA2<H, useDetK> >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
|
static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
|
||||||
|
|
|
||||||
27
pubkey.h
27
pubkey.h
|
|
@ -1304,6 +1304,18 @@ public:
|
||||||
|
|
||||||
virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
|
virtual void Sign(const DL_GroupParameters<T> ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0;
|
||||||
virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
|
virtual bool Verify(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0;
|
||||||
|
virtual bool UseDeterministicK() const
|
||||||
|
{
|
||||||
|
// By default, assume k-value won't be deterministic.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual const bool getDetKVal(const byte* hmsg, const size_t& hmsgSize,
|
||||||
|
const Integer& cord, const size_t& cordBits,
|
||||||
|
const Integer& pk, Integer& kVal) const
|
||||||
|
{
|
||||||
|
// By default, assume there is no deterministic k-value.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
|
virtual Integer RecoverPresignature(const DL_GroupParameters<T> ¶ms, const DL_PublicKey<T> &publicKey, const Integer &r, const Integer &s) const
|
||||||
{
|
{
|
||||||
CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
|
CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(publicKey); CRYPTOPP_UNUSED(r); CRYPTOPP_UNUSED(s);
|
||||||
|
|
@ -1497,7 +1509,20 @@ public:
|
||||||
// after virtual machine rollback
|
// after virtual machine rollback
|
||||||
if (rng.CanIncorporateEntropy())
|
if (rng.CanIncorporateEntropy())
|
||||||
rng.IncorporateEntropy(representative, representative.size());
|
rng.IncorporateEntropy(representative, representative.size());
|
||||||
Integer k(rng, 1, params.GetSubgroupOrder()-1);
|
|
||||||
|
// By default, RFC 6979 won't be applied.
|
||||||
|
Integer k;
|
||||||
|
if(alg.UseDeterministicK()) {
|
||||||
|
alg.getDetKVal(representative,
|
||||||
|
representative.size(),
|
||||||
|
params.GetSubgroupOrder(),
|
||||||
|
params.GetSubgroupOrder().BitCount(),
|
||||||
|
key.GetPrivateExponent(),
|
||||||
|
k);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
|
||||||
|
}
|
||||||
Integer r, s;
|
Integer r, s;
|
||||||
r = params.ConvertElementToInteger(params.ExponentiateBase(k));
|
r = params.ConvertElementToInteger(params.ExponentiateBase(k));
|
||||||
alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
|
alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);
|
||||||
|
|
|
||||||
1
test.cpp
1
test.cpp
|
|
@ -955,6 +955,7 @@ bool Validate(int alg, bool thorough, const char *seedInput)
|
||||||
case 70: result = ValidateHKDF(); break;
|
case 70: result = ValidateHKDF(); break;
|
||||||
case 71: result = ValidateBLAKE2s(); break;
|
case 71: result = ValidateBLAKE2s(); break;
|
||||||
case 72: result = ValidateBLAKE2b(); break;
|
case 72: result = ValidateBLAKE2b(); break;
|
||||||
|
case 73: result = ValidateRFC6979(); break;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ bool ValidateAll(bool thorough)
|
||||||
pass=ValidateRabin() && pass;
|
pass=ValidateRabin() && pass;
|
||||||
pass=ValidateRW() && pass;
|
pass=ValidateRW() && pass;
|
||||||
// pass=ValidateBlumGoldwasser() && pass;
|
// pass=ValidateBlumGoldwasser() && pass;
|
||||||
|
pass=ValidateRFC6979() && pass;
|
||||||
pass=ValidateECP() && pass;
|
pass=ValidateECP() && pass;
|
||||||
pass=ValidateEC2N() && pass;
|
pass=ValidateEC2N() && pass;
|
||||||
pass=ValidateECDSA() && pass;
|
pass=ValidateECDSA() && pass;
|
||||||
|
|
|
||||||
1407
validat2.cpp
1407
validat2.cpp
File diff suppressed because it is too large
Load Diff
|
|
@ -83,6 +83,7 @@ bool ValidateXTR_DH();
|
||||||
bool ValidateRabin();
|
bool ValidateRabin();
|
||||||
bool ValidateRW();
|
bool ValidateRW();
|
||||||
//bool ValidateBlumGoldwasser();
|
//bool ValidateBlumGoldwasser();
|
||||||
|
bool ValidateRFC6979();
|
||||||
bool ValidateECP();
|
bool ValidateECP();
|
||||||
bool ValidateEC2N();
|
bool ValidateEC2N();
|
||||||
bool ValidateECDSA();
|
bool ValidateECDSA();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue