Discussion:
[cryptopp-users] Crypto++ verify large file signature
Martin Dušek
2018-10-24 11:26:02 UTC
Permalink
I would like to verify a signature I previously created for a file
using CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer . The file
is quite big (several GB) and I don't want to load it to memory in one
piece as my device can run out of RAM. Is there a way crypto++ can verify
large file's signature without loading whole file to memory?
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Walton
2018-10-24 11:36:00 UTC
Permalink
Post by Martin Dušek
I would like to verify a signature I previously created for a file
using CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer . The file
is quite big (several GB) and I don't want to load it to memory in one
piece as my device can run out of RAM. Is there a way crypto++ can verify
large file's signature without loading whole file to memory?
A FileSource should read 4K bytes at a time and feed it to the attached
filter (IIRC).

You can also manually pump the data yourself. Also see
https://www.cryptopp.com/wiki/Pumping_Data .

Jeff
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 12:11:48 UTC
Permalink
Thanks. I'm going to study it. However, if someone know sample code how to
verifyy lare file signature, please post it here.
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 12:38:26 UTC
Permalink
To be honest, at the moment, I have no clue how to supply my file data
contents and signature (which is separated from my file, it exists in
std:string variable) to cryptopp verifying pipeline. Any advise welcome.
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Walton
2018-10-24 13:15:03 UTC
Permalink
To be honest, at the moment, I have no clue how to supply my file data contents and signature (which is separated from my file, it exists in std:string variable) to cryptopp verifying pipeline. Any advise welcome.
https://www.google.com/search?q=Crypto%2B%2B+verify+ECDSA+signature+site%3Acryptopp.com

https://www.google.com/search?q=Crypto%2B%2B+verify+ECDSA+signature+site%3Astackoverflow.com
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 13:15:49 UTC
Permalink
I wrote this code (at the moment my intention is to be able to supply
signature and file contents from different sources which is my case, after
it works I will optimize it to pump file contents in small pieces):

CryptoPP::ByteQueue queue;
queue.Put((const CryptoPP::byte *)publicKey.data(), publicKey.size());
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey key;
key.Load(queue);
CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false);
CryptoPP::StringSource signatureSource( (const CryptoPP::byte*)signature.data(), signature.length(), false);
CryptoPP::SignatureVerificationFilter verificationFilter(CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier(key), new CryptoPP::ArraySink( (CryptoPP::byte*)&result, sizeof(result) ));
signatureSource.Attach(&verificationFilter);
signatureSource.Pump(signature.length()); // exception here
fileSource.Attach(&verificationFilter);
fileSource.PumpAll();
however it produces exception R6025 -pure virtual function call. Can you
advise what is wrong with this code? I'm even not sure if I'm doing it the
right way.
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 13:48:40 UTC
Permalink
The exception is thrown on line 1408 of pubkey.h:

virtual size_t SLen(const DL_GroupParameters<T> &params) const
{return params.GetSubgroupOrder().ByteCount();}
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 14:01:38 UTC
Permalink
OK, I isolated minimal example whih causes R6025 pure virtual fucntion call
exception. This code is OK:

CryptoPP::FileSource ss1( file.absoluteFilePath().toLocal8Bit().constData(), true,
new CryptoPP::SignerFilter( prng,
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ),
new CryptoPP::StringSink( signature )
)
)
CryptoPP::StringSink signatureSink( signature );


CryptoPP::SignerFilter signerFilter( prng, CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ), &signatureSink);


CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, &signerFilter);


fileSource.PumpAll();


Anyone knows why?
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Walton
2018-10-24 14:09:31 UTC
Permalink
Post by Martin Dušek
...
CryptoPP::StringSink signatureSink( signature );
CryptoPP::SignerFilter signerFilter( prng, CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ), &signatureSink);
CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, &signerFilter);
Memory error. The filter signerFilter 'owns' the StringSink . It gets
destroyed by the filter, and then gets destroyed again by stack
cleanup.

You can do it as in the first example. Or you can use:

FileSource fileSource( file.absoluteFilePath()..., false, new
Redirector(signerFilter));

The Redirector breaks the ownership chain. Also see
https://www.cryptopp.com/wiki/Pipelining#Ownership .
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 14:27:12 UTC
Permalink
Post by Martin Dušek
...
CryptoPP::StringSink signatureSink( signature );
CryptoPP::SignerFilter signerFilter( prng,
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ),
&signatureSink);
Post by Martin Dušek
CryptoPP::FileSource fileSource(
file.absoluteFilePath().toLocal8Bit().constData(), false, &signerFilter);
Memory error. The filter signerFilter 'owns' the StringSink . It gets
destroyed by the filter, and then gets destroyed again by stack
cleanup.
FileSource fileSource( file.absoluteFilePath()..., false, new
Redirector(signerFilter));
The Redirector breaks the ownership chain. Also see
https://www.cryptopp.com/wiki/Pipelining#Ownership .
I would like to do it this way, but unfortunately, it still produces the
exception on PumpAll call.

CryptoPP::StringSink signatureSink( signature );


CryptoPP::SignerFilter signerFilter( prng, CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ), new CryptoPP::Redirector(signatureSink));


CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, new CryptoPP::Redirector(signerFilter));


fileSource.PumpAll();
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 14:47:43 UTC
Permalink
This is the call stack when the exeption is thrown:

1 memcmp
MSVCR120D 0xfa614fa
2 purecall
MSVCR120D 0xfb3a943
3 CryptoPP::DL_ElgamalLikeSignatureAlgorithm<CryptoPP::ECPPoint>::SLen
pubkey.h 1408 0x200284
4
CryptoPP::DL_SignatureSchemeBase<CryptoPP::PK_Signer,CryptoPP::DL_PrivateKey<CryptoPP::ECPPoint>>::SignatureLength
pubkey.h 1508 0x1dc5f3
5 CryptoPP::SignerFilter::Put2
filters.cpp 1072 0x21f4c5
6 CryptoPP::BufferedTransformation::ChannelPut2
cryptlib.cpp 474 0x211244
7 CryptoPP::Redirector::ChannelPut2
filters.h 907 0x1fbceb
8 CryptoPP::BufferedTransformation::ChannelMessageEnd
cryptlib.h 2126 0x21459a
9 CryptoPP::BufferedTransformation::TransferMessagesTo2
cryptlib.cpp 661 0x210b5b
10 CryptoPP::BufferedTransformation::TransferAllTo2
cryptlib.cpp 702 0x210f0b
11 CryptoPP::SourceTemplate<CryptoPP::FileStore>::PumpAll2
filters.h 1366 0x1ed19d
12 CryptoPP::Source::PumpAll
filters.h 1309 0x1ed209
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 15:06:54 UTC
Permalink
For me, it seems that Cryptopp has some problems reading signature length
when pumpall = false. Do you think it is a bug or compiler issue?

This code (it copies contents of file to signature variable) works:

CryptoPP::StringSink signatureSink( signature );


CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, new CryptoPP::Redirector(signatureSink));


fileSource.PumpAll();
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Walton
2018-10-24 18:02:38 UTC
Permalink
Post by Martin Dušek
For me, it seems that Cryptopp has some problems reading signature length
when pumpall = false. Do you think it is a bug or compiler issue?
CryptoPP::StringSink signatureSink( signature );
CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, new CryptoPP::Redirector(signatureSink));
fileSource.PumpAll();
Missing signerFilter in this one.

Jeff
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 18:09:21 UTC
Permalink
Post by Jeffrey Walton
Missing signerFilter in this one.
Jeff
I know...it was just a demonstration what works and what doesn't. So this
code doesn't work, it prouces pure function call exception on pumpall:

CryptoPP::StringSink signatureSink( signature );


CryptoPP::SignerFilter signerFilter( prng, CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Signer( key ), new CryptoPP::Redirector(signatureSink));


CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), false, new CryptoPP::Redirector(signerFilter));


fileSource.PumpAll();
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-24 18:45:48 UTC
Permalink
Post by Jeffrey Walton
Missing signerFilter in this one.
Jeff
I don't understand it, this code works:

CryptoPP::FileSource f( file.absoluteFilePath().toLocal8Bit().constData(), true, new CryptoPP::SignatureVerificationFilter(CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier(key), NULL));


this code doesn't:

CryptoPP::SignatureVerificationFilter *verificationFilter = new CryptoPP::SignatureVerificationFilter(CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier(key), NULL);


CryptoPP::FileSource fileSource( file.absoluteFilePath().toLocal8Bit().constData(), true, verificationFilter);


It is exactly same code, the second case only
stores SignatureVerificationFilter pointer to variable which is then passed
to FileSource constructor.

Can you please explain, why the first case runs, but the second one
produces R6025 -pure virtual function call exception?
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Martin Dušek
2018-10-27 17:27:43 UTC
Permalink
I finally have working code:

CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey key; key.Load(
queue);
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(key);

CryptoPP::SignatureVerificationFilter verificationFilter(verifier, NULL,
CryptoPP::SignatureVerificationFilter::SIGNATURE_AT_BEGIN);
CryptoPP::FileSource fileSource( file, false, new CryptoPP::Redirector(
verificationFilter));
CryptoPP::StringSource signatureSource( (const CryptoPP::byte*)signature.
data(), signature.length(), false, new CryptoPP::Redirector(
verificationFilter));
signatureSource.Pump(signature.length());
fileSource.PumpAll();

return verificationFilter.GetLastResult();
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jeffrey Walton
2018-10-27 17:32:36 UTC
Permalink
Post by Martin Dušek
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::PublicKey key; key.Load
(queue);
CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA256>::Verifier verifier(key);
CryptoPP::SignatureVerificationFilter verificationFilter(verifier, NULL,
CryptoPP::SignatureVerificationFilter::SIGNATURE_AT_BEGIN);
CryptoPP::FileSource fileSource( file, false, new CryptoPP::Redirector(
verificationFilter));
CryptoPP::StringSource signatureSource( (const CryptoPP::byte*)signature.
data(), signature.length(), false, new CryptoPP::Redirector(
verificationFilter));
signatureSource.Pump(signature.length());
fileSource.PumpAll();
return verificationFilter.GetLastResult();
Also see https://stackoverflow.com/q/52988269/608639
--
You received this message because you are subscribed to "Crypto++ Users". More information about Crypto++ and this group is available at http://www.cryptopp.com and http://groups.google.com/forum/#!forum/cryptopp-users.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-users+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...