Add Deterministic DSA and ECDSA Signatures (Issue 121)

Based on Douglas Roark PR 131
pull/347/head
Jeffrey Walton 2016-12-11 01:02:00 -05:00
parent 26db40567d
commit 7e42780517
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
11 changed files with 320 additions and 50 deletions

View File

@ -9,7 +9,7 @@ Test: TestVectors/whrlpool.txt
Test: TestVectors/dlies.txt
Test: TestVectors/dsa.txt
Test: TestVectors/dsa_1363.txt
#Test: TestVectors/dsa_rfc6979.txt
Test: TestVectors/dsa_rfc6979.txt
#Test: TestVectors/ecdsa_rfc6979.txt
Test: TestVectors/esign.txt
Test: TestVectors/hmac.txt

View File

@ -1,5 +1,5 @@
AlgorithmType: Signature
Name: DSA/SHA-1
Name: DSA-RFC6979/SHA-1
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-1
KeyFormat: Component
@ -25,7 +25,7 @@ Signature: 42AB2052FD43E123F0607F115052A67DCD9C5C77183916B0230D45B9931491D4C6B0B
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-1
Name: DSA-RFC6979/SHA-1
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-1
KeyFormat: Component
@ -46,13 +46,13 @@ PrivateExponent: 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: 2E1A0C2562B2912CAAF89186FB0F42001585DA5529EFB6B0AFF2D7A68EB70CA313022253B9A88DF5
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 42AB2052FD43E123F0607F115052A67DCD9C5C77183916B0230D45B9931491D4C6B0BD2FB4AAF088
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-224
Name: DSA-RFC6979/SHA-224
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-224
KeyFormat: Component
@ -77,7 +77,7 @@ Signature: 6868E9964E36C1689F6037F91F28D5F2C30610F249CEC3ACDC83018C5BD2674ECAAD3
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-224
Name: DSA-RFC6979/SHA-224
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-224
KeyFormat: Component
@ -97,13 +97,13 @@ PublicElement: 5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653\
PrivateExponent: 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Message: 73616D706C65
Signature: 4BC3B686AEA70145856814A6F1BB53346F02101E410697B92295D994D21EDD2F4ADA85566F6F94C1
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 6868E9964E36C1689F6037F91F28D5F2C30610F249CEC3ACDC83018C5BD2674ECAAD35B8CD22940F
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-256
Name: DSA-RFC6979/SHA-256
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-256
KeyFormat: Component
@ -128,7 +128,7 @@ Signature: 22518C127299B0F6FDC9872B282B9E70D07908126837EC18F150D55DE95B5E29BE7AF
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-256
Name: DSA-RFC6979/SHA-256
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-256
KeyFormat: Component
@ -148,13 +148,13 @@ PublicElement: 5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653\
PrivateExponent: 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Message: 73616D706C65
Signature: 81F2F5850BE5BC123C43F71A3033E9384611C5454CDD914B65EB6C66A8AAAD27299BEE6B035F5E89
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 22518C127299B0F6FDC9872B282B9E70D07908126837EC18F150D55DE95B5E29BE7AF5D01E4FE160
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-384
Name: DSA-RFC6979/SHA-384
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-384
KeyFormat: Component
@ -179,7 +179,7 @@ Signature: 854CF929B58D73C3CBFDC421E8D5430CD6DB5E6691D0E0F53E22F898D158380676A87
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-384
Name: DSA-RFC6979/SHA-384
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-384
KeyFormat: Component
@ -199,13 +199,13 @@ PublicElement: 5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653\
PrivateExponent: 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Message: 73616D706C65
Signature: 07F2108557EE0E3921BC1774F1CA9B410B4CE65A54DF70456C86FAC10FAB47C1949AB83F2C6F7595
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 854CF929B58D73C3CBFDC421E8D5430CD6DB5E6691D0E0F53E22F898D158380676A871A157CDA622
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-512
Name: DSA-RFC6979/SHA-512
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-512
KeyFormat: Component
@ -230,7 +230,7 @@ Signature: 8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A07C670C7AD72B6C050C109E1790008
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-512
Name: DSA-RFC6979/SHA-512
Source: RFC 6979
Comment: Section A.2.1. DSA, 1024 Bits, SHA-512
KeyFormat: Component
@ -250,13 +250,13 @@ PublicElement: 5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653\
PrivateExponent: 411602CB19A6CCC34494D79D98EF1E7ED5AF25F7
Message: 73616D706C65
Signature: 16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A07C670C7AD72B6C050C109E1790008097125433E8
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-1
Name: DSA-RFC6979/SHA-1
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-1
KeyFormat: Component
@ -296,7 +296,7 @@ Signature: C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0\
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-1
Name: DSA-RFC6979/SHA-1
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-1
KeyFormat: Component
@ -330,14 +330,14 @@ Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: 3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A\
D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0\
414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-224
Name: DSA-RFC6979/SHA-224
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-224
KeyFormat: Component
@ -377,7 +377,7 @@ Signature: 272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3\
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-224
Name: DSA-RFC6979/SHA-224
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-224
KeyFormat: Component
@ -411,14 +411,14 @@ Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C\
A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3\
E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-256
Name: DSA-RFC6979/SHA-256
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-256
KeyFormat: Component
@ -458,7 +458,7 @@ Signature: 8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0\
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-256
Name: DSA-RFC6979/SHA-256
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-256
KeyFormat: Component
@ -492,14 +492,14 @@ Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809\
7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0\
7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-384
Name: DSA-RFC6979/SHA-384
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-384
KeyFormat: Component
@ -539,7 +539,7 @@ Signature: 239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE\
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-384
Name: DSA-RFC6979/SHA-384
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-384
KeyFormat: Component
@ -573,14 +573,14 @@ Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B\
19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE\
6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961
#Test: DeterministicSign
Test: DeterministicSign
AlgorithmType: Signature
Name: DSA/SHA-512
Name: DSA-RFC6979/SHA-512
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-512
KeyFormat: Component
@ -620,7 +620,7 @@ Signature: 89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307\
Test: Verify
AlgorithmType: Signature
Name: DSA/SHA-512
Name: DSA-RFC6979/SHA-512
Source: RFC 6979
Comment: Section A.2.2. DSA, 2048 Bits, SHA-512
KeyFormat: Component
@ -654,9 +654,9 @@ Test: KeyPairValidAndConsistent
Message: 73616D706C65
Signature: 2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E\
D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351
#Test: DeterministicSign
Test: DeterministicSign
Message: 74657374
Signature: 89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307\
C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1
#Test: DeterministicSign
Test: DeterministicSign

View File

@ -293,6 +293,7 @@ void BenchmarkAll2(double t, double hertz)
BenchMarkSignature<LUCSS<PSSR, SHA> >(CRYPTOPP_DATA_DIR "TestData/luc1024.dat", "LUC 1024", t);
BenchMarkSignature<NR<SHA> >(CRYPTOPP_DATA_DIR "TestData/nr1024.dat", "NR 1024", t);
BenchMarkSignature<DSA>(CRYPTOPP_DATA_DIR "TestData/dsa1024.dat", "DSA 1024", t);
// BenchMarkSignature<DSA_RFC6979>(CRYPTOPP_DATA_DIR "TestData/dsa1024.dat", "DSA-RFC6979 1024", t);
BenchMarkSignature<LUC_HMP<SHA> >(CRYPTOPP_DATA_DIR "TestData/lucs512.dat", "LUC-HMP 512", t);
BenchMarkSignature<ESIGN<SHA> >(CRYPTOPP_DATA_DIR "TestData/esig1023.dat", "ESIGN 1023", t);
BenchMarkSignature<ESIGN<SHA> >(CRYPTOPP_DATA_DIR "TestData/esig1536.dat", "ESIGN 1536", t);
@ -333,6 +334,8 @@ void BenchmarkAll2(double t, double hertz)
ECIES<ECP>::Encryptor cpub(cpriv);
ECDSA<ECP, SHA>::Signer spriv(cpriv);
ECDSA<ECP, SHA>::Verifier spub(spriv);
ECDSA_RFC6979<ECP, SHA>::Signer spriv2(cpriv);
ECDSA_RFC6979<ECP, SHA>::Verifier spub2(spriv);
ECDH<ECP>::Domain ecdhc(ASN1::secp256k1());
ECMQV<ECP>::Domain ecmqvc(ASN1::secp256k1());
@ -340,6 +343,8 @@ void BenchmarkAll2(double t, double hertz)
BenchMarkDecryption("ECIES over GF(p) 256", cpriv, cpub, t);
BenchMarkSigning("ECDSA over GF(p) 256", spriv, t);
BenchMarkVerification("ECDSA over GF(p) 256", spriv, spub, t);
BenchMarkSigning("ECDSA-RFC6979 over GF(p) 256", spriv2, t);
BenchMarkVerification("ECDSA-RFC6979 over GF(p) 256", spriv2, spub2, t);
BenchMarkKeyGen("ECDHC over GF(p) 256", ecdhc, t);
BenchMarkAgreement("ECDHC over GF(p) 256", ecdhc, t);
BenchMarkKeyGen("ECMQVC over GF(p) 256", ecmqvc, t);
@ -352,6 +357,8 @@ void BenchmarkAll2(double t, double hertz)
ECIES<EC2N>::Encryptor cpub(cpriv);
ECDSA<EC2N, SHA>::Signer spriv(cpriv);
ECDSA<EC2N, SHA>::Verifier spub(spriv);
ECDSA_RFC6979<EC2N, SHA>::Signer spriv2(cpriv);
ECDSA_RFC6979<EC2N, SHA>::Verifier spub2(spriv);
ECDH<EC2N>::Domain ecdhc(ASN1::sect233r1());
ECMQV<EC2N>::Domain ecmqvc(ASN1::sect233r1());
@ -359,6 +366,8 @@ void BenchmarkAll2(double t, double hertz)
BenchMarkDecryption("ECIES over GF(2^n) 233", cpriv, cpub, t);
BenchMarkSigning("ECDSA over GF(2^n) 233", spriv, t);
BenchMarkVerification("ECDSA over GF(2^n) 233", spriv, spub, t);
BenchMarkSigning("ECDSA-RFC6979 over GF(2^n) 233", spriv2, t);
BenchMarkVerification("ECDSA-RFC6979 over GF(2^n) 233", spriv2, spub2, t);
BenchMarkKeyGen("ECDHC over GF(2^n) 233", ecdhc, t);
BenchMarkAgreement("ECDHC over GF(2^n) 233", ecdhc, t);
BenchMarkKeyGen("ECMQVC over GF(2^n) 233", ecmqvc, t);

View File

@ -228,6 +228,7 @@
<None Include="TestVectors\dlies.txt" />
<None Include="TestVectors\dsa.txt" />
<None Include="TestVectors\dsa_1363.txt" />
<None Include="TestVectors\dsa_rfc6979.txt" />
<None Include="TestVectors\eax.txt" />
<None Include="TestVectors\esign.txt" />
<None Include="TestVectors\gcm.txt" />

View File

@ -54,6 +54,9 @@
<None Include="TestVectors\dsa_1363.txt">
<Filter>TestVectors</Filter>
</None>
<None Include="TestVectors\dsa_rfc6979.txt">
<Filter>TestVectors</Filter>
</None>
<None Include="TestVectors\eax.txt">
<Filter>TestVectors</Filter>
</None>

View File

@ -2427,6 +2427,7 @@ public:
//! \class PK_SignatureScheme
//! \brief Interface for public-key signers and verifiers
//! \details This class provides an interface common to signers and verifiers for querying scheme properties
//! \sa DL_SignatureSchemeBase, TF_SignatureSchemeBase, DL_SignerBase, TF_SignerBase
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme
{
public:

View File

@ -291,10 +291,12 @@ void TestSignatureScheme(TestData &v)
// additional determinsitic signatures are added, then the test harness will
// likely need to be extended.
string signature;
SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new StringSink(signature)));
SignerFilter f(GlobalRNG(), *signer, new StringSink(signature));
StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f));
if (GetDecodedDatum(v, "Signature") != signature)
SignalTestFailure();
return;
}
else if (test == "RandomSign")

View File

@ -1,4 +1,5 @@
// eccrypto.h - written and placed in the public domain by Wei Dai
// deterministic signatures added by by Douglas Roark
//! \file eccrypto.h
//! \brief Classes and functions for Elliptic Curves over prime and binary fields
@ -343,6 +344,16 @@ public:
CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";}
};
//! \class DL_Algorithm_ECDSA_RFC6979
//! \brief Elliptic Curve DSA (ECDSA) signature algorithm
//! \tparam EC elliptic curve field
template <class EC, class H>
class DL_Algorithm_ECDSA_RFC6979 : public DL_Algorithm_DSA_RFC6979<typename EC::Point, H>
{
public:
CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECDSA-RFC6979";}
};
//! \class DL_Algorithm_ECNR
//! \brief Elliptic Curve NR (ECNR) signature algorithm
//! \tparam EC elliptic curve field
@ -363,6 +374,23 @@ struct ECDSA : public DL_SS<DL_Keys_ECDSA<EC>, DL_Algorithm_ECDSA<EC>, DL_Signat
{
};
//! \class ECDSA_RFC6979
//! \brief Elliptic Curve DSA (ECDSA) deterministic signature scheme
//! \tparam EC elliptic curve field
//! \tparam H HashTransformation derived class
//! \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">Deterministic Usage of the
//! Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>
template <class EC, class H>
struct ECDSA_RFC6979 : public DL_SS<
DL_Keys_ECDSA<EC>,
DL_Algorithm_ECDSA_RFC6979<EC, H>,
DL_SignatureMessageEncodingMethod_DSA,
H,
ECDSA_RFC6979<EC,H> >
{
static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("ECDSA-RFC6979/") + H::StaticAlgorithmName();}
};
//! \class ECNR
//! \brief Elliptic Curve NR (ECNR) signature scheme
//! \tparam EC elliptic curve field
@ -415,7 +443,8 @@ struct ECIES
DL_EncryptionAlgorithm_Xor<HMAC<HASH>, DHAES_MODE, LABEL_OCTETS>,
ECIES<EC> >
{
static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized
// TODO: fix this after name is standardized
CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "ECIES";}
};
NAMESPACE_END

View File

@ -1,6 +1,7 @@
// gfpcrypt.h - written and placed in the public domain by Wei Dai
// deterministic signatures added by by Douglas Roark
//! \file eccrypto.h
//! \file gfpcrypt.h
//! \brief Classes and functions for schemes based on Discrete Logs (DL) over GF(p)
#ifndef CRYPTOPP_GFPCRYPT_H
@ -224,7 +225,179 @@ public:
}
};
//! \class DL_Algorithm_DSA_RFC6979
//! \brief GDSA algorithm
//! \tparam T FieldElement type or class
//! \tparam H HashTransformation derived class
//! \sa <a href="http://tools.ietf.org/rfc/rfc6979.txt">Deterministic Usage of the
//! Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)</a>
template <class T, class H>
class DL_Algorithm_DSA_RFC6979 : public DL_Algorithm_GDSA<T>, public DeterministicSignatureAlgorithm
{
public:
CRYPTOPP_STATIC_CONSTEXPR const char* CRYPTOPP_API StaticAlgorithmName() {return "DSA-RFC6979";}
virtual ~DL_Algorithm_DSA_RFC6979() {}
bool IsProbabilistic() const
{return false;}
bool IsDeterministic() const
{return true;}
// Deterministic K
Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const
{
static const byte zero = 0, one = 1;
const size_t qlen = q.BitCount();
const size_t rlen = BitsToBytes(qlen);
// Step (a) - formatted E(m)
SecByteBlock BH(e.MinEncodedSize());
e.Encode(BH, BH.size());
BH = bits2octets(BH, q);
// Step (a) - private key to byte array
SecByteBlock BX(STDMAX(rlen, x.MinEncodedSize()));
x.Encode(BX, BX.size());
// Step (b)
SecByteBlock V(H::DIGESTSIZE);
std::fill(V.begin(), V.begin()+H::DIGESTSIZE, one);
// Step (c)
SecByteBlock K(H::DIGESTSIZE);
std::fill(K.begin(), K.begin()+H::DIGESTSIZE, zero);
// Step (d)
m_hmac.SetKey(K, K.size());
m_hmac.Update(V, V.size());
m_hmac.Update(&zero, 1);
m_hmac.Update(BX, BX.size());
m_hmac.Update(BH, BH.size());
m_hmac.TruncatedFinal(K, K.size());
// Step (e)
m_hmac.SetKey(K, K.size());
m_hmac.Update(V, V.size());
m_hmac.TruncatedFinal(V, V.size());
// Step (f)
m_hmac.SetKey(K, K.size());
m_hmac.Update(V, V.size());
m_hmac.Update(&one, 1);
m_hmac.Update(BX, BX.size());
m_hmac.Update(BH, BH.size());
m_hmac.TruncatedFinal(K, K.size());
// Step (g)
m_hmac.SetKey(K, K.size());
m_hmac.Update(V, V.size());
m_hmac.TruncatedFinal(V, V.size());
Integer k;
SecByteBlock temp(rlen);
for (;;)
{
// We want qlen bits, but we support only hash functions with an output length
// multiple of 8; hence, we will gather rlen bits, i.e., rolen octets.
size_t toff = 0;
while (toff < rlen)
{
m_hmac.Update(V, V.size());
m_hmac.TruncatedFinal(V, V.size());
size_t cc = STDMIN(V.size(), temp.size() - toff);
memcpy_s(temp+toff, temp.size() - toff, V, cc);
toff += cc;
}
k = bits2int(temp, qlen);
if (k > 0 && k < q)
break;
// k is not in the proper range; update K and V, and loop.
m_hmac.Update(V, V.size());
m_hmac.Update(&zero, 1);
m_hmac.TruncatedFinal(K, K.size());
m_hmac.SetKey(K, K.size());
m_hmac.Update(V, V.size());
m_hmac.TruncatedFinal(V, V.size());
}
return k;
}
protected:
#if 0
// Determine bits without converting to an Integer
inline unsigned int BitCount(const byte* buffer, size_t size) const
{
unsigned int idx = 0;
while (idx < size && buffer[idx] == 0) { idx++; }
return (size-idx)*8 - (8-BitPrecision(buffer[idx]));
}
#endif
Integer bits2int(const SecByteBlock& bits, size_t qlen) const
{
Integer ret(bits, bits.size());
size_t blen = bits.size()*8;
if (blen > qlen)
ret >>= blen - qlen;
return ret;
}
// 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, size_t rlen) const
{
SecByteBlock block(val.MinEncodedSize());
val.Encode(block, val.MinEncodedSize());
if (block.size() == rlen)
return block;
// The least significant bytes are the ones we need to preserve.
SecByteBlock t(rlen);
if (block.size() > rlen)
{
size_t offset = block.size() - rlen;
memcpy(t, block + offset, rlen);
}
else // block.size() < rlen
{
size_t offset = rlen - block.size();
memset(t, '\x00', offset);
memcpy(t + offset, block, rlen - offset);
}
return t;
}
// Turn a stream of bits into a set of bytes with the same length as an elliptic
// curve's order.
SecByteBlock bits2octets(const SecByteBlock& in, const Integer& q) const
{
Integer b2 = bits2int(in, in.size()*8);
Integer b1 = b2 - q;
return int2octets(b1.IsNegative() ? b2 : b1, q.ByteCount());
}
private:
mutable H m_hash;
mutable HMAC<H> m_hmac;
};
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA<Integer>;
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA1>;
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA224>;
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA256>;
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA384>;
CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_DSA_RFC6979<Integer, SHA512>;
//! \class DL_Algorithm_NR
//! \brief NR algorithm
@ -541,10 +714,22 @@ class DSA2 : public DL_SS<
{
public:
static std::string CRYPTOPP_API StaticAlgorithmName() {return "DSA/" + (std::string)H::StaticAlgorithmName();}
};
//#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
//enum {MIN_PRIME_LENGTH = 1024, MAX_PRIME_LENGTH = 3072, PRIME_LENGTH_MULTIPLE = 1024};
//#endif
//! \class DSA_RFC6979
//! \brief DSA deterministic signature scheme
//! \tparam H HashTransformation derived class
//! \sa <a href="http://www.weidai.com/scan-mirror/sig.html#DSA-1363">DSA-1363</a>
//! \since Crypto++ 1.0 for DSA, Crypto++ 5.6.2 for DSA2
template <class H>
struct DSA_RFC6979 : public DL_SS<
DL_SignatureKeys_GFP,
DL_Algorithm_DSA_RFC6979<Integer, H>,
DL_SignatureMessageEncodingMethod_DSA,
H,
DSA_RFC6979<H> >
{
static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("DSA-RFC6979/") + H::StaticAlgorithmName();}
};
//! DSA with SHA-1, typedef'd for backwards compatibility

View File

@ -329,6 +329,12 @@ public:
virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const
{CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(representativeBitLength); CRYPTOPP_UNUSED(hashIdentifierLength); CRYPTOPP_UNUSED(digestLength); return 0;}
//! \brief Determines whether an encoding method requires a random number generator
//! \return true if the encoding method requires a RandomNumberGenerator()
//! \details if IsProbabilistic() returns false, then NullRNG() can be passed to functions that take
//! RandomNumberGenerator().
//! \sa Bellare and Rogaway<a href="http://grouper.ieee.org/groups/1363/P1363a/contributions/pss-submission.pdf">PSS:
//! Provably Secure Encoding Method for Digital Signatures</a>
bool IsProbabilistic() const
{return true;}
bool AllowNonrecoverablePart() const
@ -1265,6 +1271,19 @@ public:
{return params.GetSubgroupOrder().ByteCount();}
virtual size_t SLen(const DL_GroupParameters<T> &params) const
{return params.GetSubgroupOrder().ByteCount();}
// RFC 6979, present in DL signers
virtual bool IsDeterministic() const
{return false;}
};
//! \brief Interface for deterministic signers
//! \details RFC 6979 signers which generate k based on the encoded message and private key
class CRYPTOPP_NO_VTABLE DeterministicSignatureAlgorithm
{
public:
virtual ~DeterministicSignatureAlgorithm() {}
virtual Integer GenerateRandom(const Integer &x, const Integer &q, const Integer &e) const =0;
};
//! \brief Interface for DL key agreement algorithms
@ -1376,6 +1395,9 @@ protected:
size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());}
size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();}
// true if the scheme conforms to RFC 6979
virtual bool IsDeterministic() const {return false;}
virtual const DL_ElgamalLikeSignatureAlgorithm<typename KEY_INTFACE::Element> & GetSignatureAlgorithm() const =0;
virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0;
virtual HashIdentifier GetHashIdentifier() const =0;
@ -1433,11 +1455,24 @@ public:
ma.m_empty = true;
Integer e(representative, representative.size());
// hash message digest into random number k to prevent reusing the same k on a different messages
// after virtual machine rollback
// hash message digest into random number k to prevent reusing the same k on
// different messages after virtual machine rollback
if (rng.CanIncorporateEntropy())
rng.IncorporateEntropy(representative, representative.size());
Integer k(rng, 1, params.GetSubgroupOrder()-1);
Integer k;
if (alg.IsDeterministic())
{
const Integer& q = params.GetSubgroupOrder();
const Integer& x = key.GetPrivateExponent();
const DeterministicSignatureAlgorithm& det = dynamic_cast<const DeterministicSignatureAlgorithm&>(alg);
k = det.GenerateRandom(x, q, e);
}
else
{
k.Randomize(rng, 1, params.GetSubgroupOrder()-1);
}
Integer r, s;
r = params.ConvertElementToInteger(params.ExponentiateBase(k));
alg.Sign(params, key.GetPrivateExponent(), k, e, r, s);

View File

@ -126,6 +126,11 @@ void RegisterFactories()
RegisterSignatureSchemeDefaultFactories<DSA2<SHA256> >();
RegisterSignatureSchemeDefaultFactories<DSA2<SHA384> >();
RegisterSignatureSchemeDefaultFactories<DSA2<SHA512> >();
RegisterSignatureSchemeDefaultFactories<DSA_RFC6979<SHA1> >();
RegisterSignatureSchemeDefaultFactories<DSA_RFC6979<SHA224> >();
RegisterSignatureSchemeDefaultFactories<DSA_RFC6979<SHA256> >();
RegisterSignatureSchemeDefaultFactories<DSA_RFC6979<SHA384> >();
RegisterSignatureSchemeDefaultFactories<DSA_RFC6979<SHA512> >();
RegisterSignatureSchemeDefaultFactories<NR<SHA1> >("NR(1363)/EMSA1(SHA-1)");
RegisterSignatureSchemeDefaultFactories<GDSA<SHA1> >("DSA-1363/EMSA1(SHA-1)");
RegisterSignatureSchemeDefaultFactories<RSASS<PKCS1v15, Weak::MD2> >("RSA/PKCS1-1.5(MD2)");