H(M)=M
可能有用。有可能满足这样一个习惯吗
HashTransformation
ECDSA<ECP,H>::Signer
?
对程序如下。它提供了一个
IdentityHash
将输入复制到输出的类。它需要一个模板参数来指定哈希大小。
to_sign = MF(H(M))
.
$ cat test.cxx
#include "cryptlib.h"
#include "secblock.h"
#include "eccrypto.h"
#include "osrng.h"
#include "oids.h"
#include "hex.h"
#include <iostream>
#include <string>
using namespace CryptoPP;
template <unsigned int HASH_SIZE = 32>
class IdentityHash : public HashTransformation
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = HASH_SIZE)
static const char * StaticAlgorithmName()
{
return "IdentityHash";
}
IdentityHash() : m_digest(HASH_SIZE), m_idx(0) {}
virtual unsigned int DigestSize() const
{
return DIGESTSIZE;
}
virtual void Update(const byte *input, size_t length)
{
size_t s = STDMIN(STDMIN<size_t>(DIGESTSIZE, length),
DIGESTSIZE - m_idx);
if (s)
::memcpy(&m_digest[m_idx], input, s);
m_idx += s;
}
virtual void TruncatedFinal(byte *digest, size_t digestSize)
{
if (m_idx != DIGESTSIZE)
throw Exception(Exception::OTHER_ERROR, "Input size must be " + IntToString(DIGESTSIZE));
ThrowIfInvalidTruncatedSize(digestSize);
if (digest)
::memcpy(digest, m_digest, digestSize);
m_idx = 0;
}
private:
SecByteBlock m_digest;
size_t m_idx;
};
int main(int argc, char* argv[])
{
AutoSeededRandomPool prng;
ECDSA<ECP, IdentityHash<32> >::PrivateKey privateKey;
privateKey.Initialize(prng, ASN1::secp256r1());
std::string message;
message.resize(IdentityHash<32>::DIGESTSIZE);
::memset(&message[0], 0xAA, message.size());
ECDSA<ECP, IdentityHash<32> >::Signer signer(privateKey);
std::string signature;
StringSource ss(message, true,
new SignerFilter(prng, signer,
new HexEncoder(new StringSink(signature))
) // SignerFilter
); // StringSource
std::cout << "Signature: " << signature << std::endl;
return 0;
}
我知道它编译并生成输出。我不知道输出是否正确:
skylake:cryptopp$ g++ test.cxx ./libcryptopp.a -o test.exe
skylake:cryptopp$ ./test.exe
Signature: cafb8fca487c7d5023fbc76ccf96f107f72a07fecca77254e8845a2c8f2ed0ee8b50b
8ee0702beb7572eaa30c8d250a7b082c79f2f02e58ccfb97d7091755e91
你可以测试
识别灰烬
具有以下内容。班级
识别灰烬
与上一个示例没有更改。这个
main
$ cat test.cxx
#include "cryptlib.h"
#include "secblock.h"
#include <iostream>
#include <string>
using namespace CryptoPP;
template <unsigned int HASH_SIZE = 32>
class IdentityHash : public HashTransformation
{
public:
CRYPTOPP_CONSTANT(DIGESTSIZE = HASH_SIZE)
static const char * StaticAlgorithmName()
{
return "IdentityHash";
}
IdentityHash() : m_digest(HASH_SIZE), m_idx(0) {}
virtual unsigned int DigestSize() const
{
return DIGESTSIZE;
}
virtual void Update(const byte *input, size_t length)
{
size_t s = STDMIN(STDMIN<size_t>(DIGESTSIZE, length),
DIGESTSIZE - m_idx);
if (s)
::memcpy(&m_digest[m_idx], input, s);
m_idx += s;
}
virtual void TruncatedFinal(byte *digest, size_t digestSize)
{
if (m_idx != DIGESTSIZE)
throw Exception(Exception::OTHER_ERROR, "Input size must be " + IntToString(DIGESTSIZE));
ThrowIfInvalidTruncatedSize(digestSize);
if (digest)
::memcpy(digest, m_digest, digestSize);
m_idx = 0;
}
private:
SecByteBlock m_digest;
size_t m_idx;
};
int main(int argc, char* argv[])
{
std::string message;
message.resize(IdentityHash<32>::DIGESTSIZE);
::memset(&message[0], 'A', message.size());
IdentityHash<32> hash;
hash.Update((const byte*)message.data(), message.size());
std::string digest(32, 0);
hash.TruncatedFinal((byte*)digest.data(), digest.size());
std::cout << "Message: " << message << std::endl;
std::cout << " Digest: " << digest << std::endl;
return 0;
}
skylake:cryptopp$ g++ test.cxx ./libcryptopp.a -o test.exe
skylake:cryptopp$ ./test.exe
Message: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Digest: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA