parent
1c6a96a57e
commit
0ca4c41a97
35
donna.h
35
donna.h
|
|
@ -81,6 +81,23 @@ int ed25519_publickey(byte publicKey[32], const byte secretKey[32]);
|
|||
/// SHA512.
|
||||
int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32], const byte publicKey[32], byte signature[64]);
|
||||
|
||||
/// \brief Creates a signature on a message
|
||||
/// \param stream std::istream derived class
|
||||
/// \param publicKey byte array with the public key
|
||||
/// \param secretKey byte array with the private key
|
||||
/// \param signature byte array for the signature
|
||||
/// \returns 0 on success, non-0 otherwise
|
||||
/// \details ed25519_sign() generates a signature on a message using
|
||||
/// the public and private keys. The various buffers can be exact
|
||||
/// sizes, and do not require extra space like when using the
|
||||
/// NaCl library functions.
|
||||
/// \details This ed25519_sign() overload handles large streams. It
|
||||
/// was added for signing and verifying files that are too large
|
||||
/// for a memory allocation.
|
||||
/// \details At the moment the hash function for signing is fixed at
|
||||
/// SHA512.
|
||||
int ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32], byte signature[64]);
|
||||
|
||||
/// \brief Verifies a signature on a message
|
||||
/// \param message byte array with the message
|
||||
/// \param messageLength size of the message, in bytes
|
||||
|
|
@ -88,13 +105,29 @@ int ed25519_sign(const byte* message, size_t messageLength, const byte secretKey
|
|||
/// \param signature byte array with the signature
|
||||
/// \returns 0 on success, non-0 otherwise
|
||||
/// \details ed25519_sign_open() verifies a signature on a message using
|
||||
/// the public. The various buffers can be exact sizes, and do not
|
||||
/// the public key. The various buffers can be exact sizes, and do not
|
||||
/// require extra space like when using the NaCl library functions.
|
||||
/// \details At the moment the hash function for signing is fixed at
|
||||
/// SHA512.
|
||||
int
|
||||
ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64]);
|
||||
|
||||
/// \brief Verifies a signature on a message
|
||||
/// \param stream std::istream derived class
|
||||
/// \param publicKey byte array with the public key
|
||||
/// \param signature byte array with the signature
|
||||
/// \returns 0 on success, non-0 otherwise
|
||||
/// \details ed25519_sign_open() verifies a signature on a message using
|
||||
/// the public key. The various buffers can be exact sizes, and do not
|
||||
/// require extra space like when using the NaCl library functions.
|
||||
/// \details This ed25519_sign_open() overload handles large streams. It
|
||||
/// was added for signing and verifying files that are too large
|
||||
/// for a memory allocation.
|
||||
/// \details At the moment the hash function for signing is fixed at
|
||||
/// SHA512.
|
||||
int
|
||||
ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64]);
|
||||
|
||||
//****************************** Internal ******************************//
|
||||
|
||||
#ifndef CRYPTOPP_DOXYGEN_PROCESSING
|
||||
|
|
|
|||
122
donna_32.cpp
122
donna_32.cpp
|
|
@ -27,6 +27,9 @@
|
|||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
|
||||
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
|
||||
# pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
|
@ -1033,7 +1036,21 @@ ed25519_extsk(hash_512bits extsk, const byte sk[32]) {
|
|||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const unsigned char *m, size_t mlen) {
|
||||
UpdateFromStream(HashTransformation& hash, std::istream& stream)
|
||||
{
|
||||
SecByteBlock block(4096);
|
||||
while (stream.read((char*)block.begin(), block.size()))
|
||||
hash.Update(block, block.size());
|
||||
|
||||
std::streamsize rem = stream.gcount();
|
||||
if (rem)
|
||||
hash.Update(block, (size_t)rem);
|
||||
|
||||
block.SetMark(0);
|
||||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const byte *m, size_t mlen) {
|
||||
SHA512 hash;
|
||||
hash.Update(RS, 32);
|
||||
hash.Update(pk, 32);
|
||||
|
|
@ -1041,6 +1058,15 @@ ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const unsi
|
|||
hash.Final(hram);
|
||||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], std::istream& stream) {
|
||||
SHA512 hash;
|
||||
hash.Update(RS, 32);
|
||||
hash.Update(pk, 32);
|
||||
UpdateFromStream(hash, stream);
|
||||
hash.Final(hram);
|
||||
}
|
||||
|
||||
inline bignum256modm_element_t
|
||||
lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
|
||||
return (a - b) >> 31;
|
||||
|
|
@ -1556,7 +1582,7 @@ ge25519_pack(byte r[32], const ge25519 *p) {
|
|||
}
|
||||
|
||||
int
|
||||
ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) {
|
||||
ed25519_verify(const byte *x, const byte *y, size_t len) {
|
||||
size_t differentbits = 0;
|
||||
while (len--)
|
||||
differentbits |= (*x++ ^ *y++);
|
||||
|
|
@ -1857,6 +1883,55 @@ ed25519_publickey(byte publicKey[32], const byte secretKey[32])
|
|||
return ed25519_publickey_CXX(publicKey, secretKey);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byte RS[64])
|
||||
{
|
||||
using namespace CryptoPP::Donna::Ed25519;
|
||||
|
||||
bignum256modm r, S, a;
|
||||
ALIGN(16) ge25519 R;
|
||||
hash_512bits extsk, hashr, hram;
|
||||
|
||||
// Unfortunately we need to read the stream twice. The fisrt time calculates
|
||||
// 'r = H(aExt[32..64], m)'. The second time calculates 'S = H(R,A,m)'. There
|
||||
// is a data dependency due to hashing 'RS' with 'R = [r]B' that does not
|
||||
// allow us to read the stream once.
|
||||
std::streampos where = stream.tellg();
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
|
||||
/* r = H(aExt[32..64], m) */
|
||||
SHA512 hash;
|
||||
hash.Update(extsk + 32, 32);
|
||||
UpdateFromStream(hash, stream);
|
||||
hash.Final(hashr);
|
||||
expand256_modm(r, hashr, 64);
|
||||
|
||||
/* R = rB */
|
||||
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
|
||||
ge25519_pack(RS, &R);
|
||||
|
||||
// Reset stream for the second digest
|
||||
stream.clear();
|
||||
stream.seekg(where);
|
||||
|
||||
/* S = H(R,A,m).. */
|
||||
ed25519_hram(hram, RS, pk, stream);
|
||||
expand256_modm(S, hram, 64);
|
||||
|
||||
/* S = H(R,A,m)a */
|
||||
expand256_modm(a, extsk, 32);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(RS + 32, S);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32], byte RS[64])
|
||||
{
|
||||
|
|
@ -1896,6 +1971,13 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32],
|
||||
byte signature[64])
|
||||
{
|
||||
return ed25519_sign_CXX(stream, secretKey, publicKey, signature);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32],
|
||||
const byte publicKey[32], byte signature[64])
|
||||
|
|
@ -1903,6 +1985,34 @@ ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32]
|
|||
return ed25519_sign_CXX(message, messageLength, secretKey, publicKey, signature);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]) {
|
||||
|
||||
using namespace CryptoPP::Donna::Ed25519;
|
||||
|
||||
ALIGN(16) ge25519 R, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
byte checkR[32];
|
||||
|
||||
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
|
||||
return -1;
|
||||
|
||||
/* hram = H(R,A,m) */
|
||||
ed25519_hram(hash, RS, pk, stream);
|
||||
expand256_modm(hram, hash, 64);
|
||||
|
||||
/* S */
|
||||
expand256_modm(S, RS + 32, 32);
|
||||
|
||||
/* SB - H(R,A,m)A */
|
||||
ge25519_double_scalarmult_vartime(&R, &A, hram, S);
|
||||
ge25519_pack(checkR, &R);
|
||||
|
||||
/* check that R = SB - H(R,A,m)A */
|
||||
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte RS[64]) {
|
||||
|
||||
|
|
@ -1911,7 +2021,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
|
|||
ALIGN(16) ge25519 R, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
unsigned char checkR[32];
|
||||
byte checkR[32];
|
||||
|
||||
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
|
||||
return -1;
|
||||
|
|
@ -1937,6 +2047,12 @@ ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKe
|
|||
return ed25519_sign_open_CXX(message, messageLength, publicKey, signature);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64])
|
||||
{
|
||||
return ed25519_sign_open_CXX(stream, publicKey, signature);
|
||||
}
|
||||
|
||||
NAMESPACE_END // Donna
|
||||
NAMESPACE_END // CryptoPP
|
||||
|
||||
|
|
|
|||
122
donna_64.cpp
122
donna_64.cpp
|
|
@ -27,6 +27,9 @@
|
|||
#include "misc.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include <istream>
|
||||
#include <sstream>
|
||||
|
||||
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
|
||||
# pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
|
@ -781,7 +784,21 @@ ed25519_extsk(hash_512bits extsk, const byte sk[32]) {
|
|||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const unsigned char *m, size_t mlen) {
|
||||
UpdateFromStream(HashTransformation& hash, std::istream& stream)
|
||||
{
|
||||
SecByteBlock block(4096);
|
||||
while (stream.read((char*)block.begin(), block.size()))
|
||||
hash.Update(block, block.size());
|
||||
|
||||
std::streamsize rem = stream.gcount();
|
||||
if (rem)
|
||||
hash.Update(block, rem);
|
||||
|
||||
block.SetMark(0);
|
||||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const byte *m, size_t mlen) {
|
||||
SHA512 hash;
|
||||
hash.Update(RS, 32);
|
||||
hash.Update(pk, 32);
|
||||
|
|
@ -789,6 +806,15 @@ ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], const unsi
|
|||
hash.Final(hram);
|
||||
}
|
||||
|
||||
void
|
||||
ed25519_hram(hash_512bits hram, const byte RS[64], const byte pk[32], std::istream& stream) {
|
||||
SHA512 hash;
|
||||
hash.Update(RS, 32);
|
||||
hash.Update(pk, 32);
|
||||
UpdateFromStream(hash, stream);
|
||||
hash.Final(hram);
|
||||
}
|
||||
|
||||
bignum256modm_element_t
|
||||
lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) {
|
||||
return (a - b) >> 63;
|
||||
|
|
@ -861,7 +887,6 @@ barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256m
|
|||
reduce256_modm(r);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) {
|
||||
bignum256modm_element_t c;
|
||||
|
|
@ -1272,7 +1297,7 @@ ge25519_pack(byte r[32], const ge25519 *p) {
|
|||
}
|
||||
|
||||
int
|
||||
ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) {
|
||||
ed25519_verify(const byte *x, const byte *y, size_t len) {
|
||||
size_t differentbits = 0;
|
||||
while (len--)
|
||||
differentbits |= (*x++ ^ *y++);
|
||||
|
|
@ -1573,6 +1598,54 @@ ed25519_publickey(byte publicKey[32], const byte secretKey[32])
|
|||
return ed25519_publickey_CXX(publicKey, secretKey);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byte RS[64])
|
||||
{
|
||||
using namespace CryptoPP::Donna::Ed25519;
|
||||
|
||||
bignum256modm r, S, a;
|
||||
ALIGN(16) ge25519 R;
|
||||
hash_512bits extsk, hashr, hram;
|
||||
|
||||
// Unfortunately we need to read the stream twice. The fisrt time calculates
|
||||
// 'r = H(aExt[32..64], m)'. The second time calculates 'S = H(R,A,m)'. There
|
||||
// is a data dependency due to hashing 'RS' with 'R = [r]B' that does not
|
||||
// allow us to read the stream once.
|
||||
std::streampos where = stream.tellg();
|
||||
|
||||
ed25519_extsk(extsk, sk);
|
||||
|
||||
/* r = H(aExt[32..64], m) */
|
||||
SHA512 hash;
|
||||
hash.Update(extsk + 32, 32);
|
||||
UpdateFromStream(hash, stream);
|
||||
hash.Final(hashr);
|
||||
expand256_modm(r, hashr, 64);
|
||||
|
||||
/* R = rB */
|
||||
ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r);
|
||||
ge25519_pack(RS, &R);
|
||||
|
||||
// Reset stream for the second digest
|
||||
stream.clear();
|
||||
stream.seekg(where);
|
||||
|
||||
/* S = H(R,A,m).. */
|
||||
ed25519_hram(hram, RS, pk, stream);
|
||||
expand256_modm(S, hram, 64);
|
||||
|
||||
/* S = H(R,A,m)a */
|
||||
expand256_modm(a, extsk, 32);
|
||||
mul256_modm(S, S, a);
|
||||
|
||||
/* S = (r + H(R,A,m)a) */
|
||||
add256_modm(S, S, r);
|
||||
|
||||
/* S = (r + H(R,A,m)a) mod L */
|
||||
contract256_modm(RS + 32, S);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32], byte RS[64])
|
||||
{
|
||||
|
|
@ -1611,6 +1684,13 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign(std::istream& stream, const byte secretKey[32], const byte publicKey[32],
|
||||
byte signature[64])
|
||||
{
|
||||
return ed25519_sign_CXX(stream, secretKey, publicKey, signature);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign(const byte* message, size_t messageLength, const byte secretKey[32],
|
||||
const byte publicKey[32], byte signature[64])
|
||||
|
|
@ -1626,7 +1706,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
|
|||
ALIGN(16) ge25519 R, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
unsigned char checkR[32];
|
||||
byte checkR[32];
|
||||
|
||||
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
|
||||
return -1;
|
||||
|
|
@ -1646,6 +1726,40 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
|
|||
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]) {
|
||||
|
||||
using namespace CryptoPP::Donna::Ed25519;
|
||||
|
||||
ALIGN(16) ge25519 R, A;
|
||||
hash_512bits hash;
|
||||
bignum256modm hram, S;
|
||||
byte checkR[32];
|
||||
|
||||
if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk))
|
||||
return -1;
|
||||
|
||||
/* hram = H(R,A,m) */
|
||||
ed25519_hram(hash, RS, pk, stream);
|
||||
expand256_modm(hram, hash, 64);
|
||||
|
||||
/* S */
|
||||
expand256_modm(S, RS + 32, 32);
|
||||
|
||||
/* SB - H(R,A,m)A */
|
||||
ge25519_double_scalarmult_vartime(&R, &A, hram, S);
|
||||
ge25519_pack(checkR, &R);
|
||||
|
||||
/* check that R = SB - H(R,A,m)A */
|
||||
return ed25519_verify(RS, checkR, 32) ? 0 : -1;
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open(std::istream& stream, const byte publicKey[32], const byte signature[64])
|
||||
{
|
||||
return ed25519_sign_open_CXX(stream, publicKey, signature);
|
||||
}
|
||||
|
||||
int
|
||||
ed25519_sign_open(const byte *message, size_t messageLength, const byte publicKey[32], const byte signature[64])
|
||||
{
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ void Poly1305_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, con
|
|||
if (params.GetValue(Name::IV(), t) && t.begin() && t.size())
|
||||
{
|
||||
CRYPTOPP_ASSERT(t.size() == m_nk.size());
|
||||
Resynchronize(t.begin(), t.size());
|
||||
Resynchronize(t.begin(), (int)t.size());
|
||||
}
|
||||
|
||||
Restart();
|
||||
|
|
|
|||
53
validat7.cpp
53
validat7.cpp
|
|
@ -537,6 +537,59 @@ bool TestEd25519()
|
|||
else
|
||||
std::cout << "FAILED:";
|
||||
std::cout << " " << SIGN_COUNT << " verifications" << std::endl;
|
||||
|
||||
// Test signature verification using streams
|
||||
for (unsigned int i = 0; i<SIGN_COUNT; ++i)
|
||||
{
|
||||
// Fresh keypair
|
||||
(void)NaCl::crypto_sign_keypair(pk1, sk1);
|
||||
std::memcpy(sk2, sk1, 32);
|
||||
std::memcpy(pk2, pk1, 32);
|
||||
|
||||
// Message and signatures
|
||||
byte msg1[MSG_SIZE+NACL_EXTRA], msg2[MSG_SIZE];
|
||||
byte sig1[MSG_SIZE+NACL_EXTRA], sig2[64];
|
||||
GlobalRNG().GenerateBlock(msg1, MSG_SIZE);
|
||||
size_t len = GlobalRNG().GenerateWord32(0, MSG_SIZE);
|
||||
std::memcpy(msg2, msg1, len);
|
||||
|
||||
// Spike the signatures
|
||||
sig1[1] = 1; sig2[2] = 2;
|
||||
|
||||
// Create a stream
|
||||
std::string str2((const char*)msg2, len);
|
||||
std::istringstream iss(str2);
|
||||
|
||||
word64 smlen = sizeof(sig1);
|
||||
int ret1 = NaCl::crypto_sign(sig1, &smlen, msg1, len, sk1);
|
||||
int ret2 = Donna::ed25519_sign(iss, sk2, pk2, sig2);
|
||||
int ret3 = std::memcmp(sig1, sig2, 64);
|
||||
|
||||
bool tamper = !!GlobalRNG().GenerateBit();
|
||||
if (tamper)
|
||||
{
|
||||
sig1[1] ^= 1;
|
||||
sig2[1] ^= 1;
|
||||
}
|
||||
|
||||
// Reset stream
|
||||
iss.clear();
|
||||
iss.seekg(0);
|
||||
|
||||
// Verify the other's signature using the other's key
|
||||
word64 mlen = len+NACL_EXTRA;
|
||||
int ret4 = NaCl::crypto_sign_open(msg1, &mlen, sig1, smlen, pk2);
|
||||
int ret5 = Donna::ed25519_sign_open(iss, pk1, sig2);
|
||||
|
||||
bool fail = ret1 != 0 || ret2 != 0 || ret3 != 0 || ((ret4 != 0) ^ tamper) || ((ret5 != 0) ^ tamper);
|
||||
pass = pass && !fail;
|
||||
}
|
||||
|
||||
if (pass)
|
||||
std::cout << "passed:";
|
||||
else
|
||||
std::cout << "FAILED:";
|
||||
std::cout << " " << SIGN_COUNT << " streams" << std::endl;
|
||||
#endif
|
||||
|
||||
// RFC 8032 test vector
|
||||
|
|
|
|||
21
xed25519.cpp
21
xed25519.cpp
|
|
@ -685,6 +685,17 @@ size_t ed25519Signer::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccum
|
|||
return ret == 0 ? SIGNATURE_LENGTH : 0;
|
||||
}
|
||||
|
||||
size_t ed25519Signer::SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const
|
||||
{
|
||||
CRYPTOPP_ASSERT(signature != NULLPTR); CRYPTOPP_UNUSED(rng);
|
||||
|
||||
const ed25519PrivateKey& pk = static_cast<const ed25519PrivateKey&>(GetPrivateKey());
|
||||
int ret = Donna::ed25519_sign(stream, pk.GetPrivateKeyBytePtr(), pk.GetPublicKeyBytePtr(), signature);
|
||||
CRYPTOPP_ASSERT(ret == 0);
|
||||
|
||||
return ret == 0 ? SIGNATURE_LENGTH : 0;
|
||||
}
|
||||
|
||||
// ******************** ed25519 Verifier ************************* //
|
||||
|
||||
bool ed25519PublicKey::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
||||
|
|
@ -856,4 +867,14 @@ bool ed25519Verifier::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator
|
|||
return ret == 0;
|
||||
}
|
||||
|
||||
bool ed25519Verifier::VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const
|
||||
{
|
||||
CRYPTOPP_ASSERT(signatureLen == SIGNATURE_LENGTH);
|
||||
|
||||
const ed25519PublicKey& pk = static_cast<const ed25519PublicKey&>(GetPublicKey());
|
||||
int ret = Donna::ed25519_sign_open(stream, pk.GetPublicKeyBytePtr(), signature);
|
||||
|
||||
return ret == 0;
|
||||
}
|
||||
|
||||
NAMESPACE_END // CryptoPP
|
||||
|
|
|
|||
21
xed25519.h
21
xed25519.h
|
|
@ -574,6 +574,18 @@ struct ed25519Signer : public PK_Signer
|
|||
|
||||
size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const;
|
||||
|
||||
/// \brief Sign a stream
|
||||
/// \param rng a RandomNumberGenerator derived class
|
||||
/// \param stream an std::istream derived class
|
||||
/// \param signature a block of bytes for the signature
|
||||
/// \return actual signature length
|
||||
/// \details SignStream() handles large streams. It was added for signing and verifying
|
||||
/// files that are too large for a memory allocation.
|
||||
/// \details ed25519 is a determinsitic signature scheme. <tt>IsProbabilistic()</tt>
|
||||
/// returns false and the random number generator can be <tt>NullRNG()</tt>.
|
||||
/// \pre <tt>COUNTOF(signature) == MaxSignatureLength()</tt>
|
||||
size_t SignStream (RandomNumberGenerator &rng, std::istream& stream, byte *signature) const;
|
||||
|
||||
protected:
|
||||
ed25519PrivateKey m_key;
|
||||
};
|
||||
|
|
@ -742,6 +754,15 @@ struct ed25519Verifier : public PK_Verifier
|
|||
|
||||
bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const;
|
||||
|
||||
/// \brief Check whether input signature is a valid signature for input message
|
||||
/// \param stream an std::istream derived class
|
||||
/// \param signature a pointer to the signature over the message
|
||||
/// \param signatureLen the size of the signature
|
||||
/// \return true if the signature is valid, false otherwise
|
||||
/// \details VerifyStream() handles large streams. It was added for signing and verifying
|
||||
/// files that are too large for a memory allocation.
|
||||
bool VerifyStream(std::istream& stream, const byte *signature, size_t signatureLen) const;
|
||||
|
||||
DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const {
|
||||
CRYPTOPP_UNUSED(recoveredMessage); CRYPTOPP_UNUSED(messageAccumulator);
|
||||
throw NotImplemented("ed25519Verifier: this object does not support recoverable messages");
|
||||
|
|
|
|||
Loading…
Reference in New Issue