Hi All,
Based on Jason Smethers code, with additions of buffer management
(using CiphertextLength() and MaxPlaintextLength() from base class
PK_CryptoSystem ).
Wei - would it be possible to add to the FAQ (for a convenient place
to find without searching the archives)?
// Runtime Includes
#include <iostream>
#include <string>
// Crypto++ Includes
#include "cryptlib.h"
#include "oids.h"
#include "osrng.h"
#include "eccrypto.h"
#include "asn.h"
#include "ecp.h"
#include "simple.h"
int main(int argc, char* argv[])
{
try {
CryptoPP::ECIES< CryptoPP::ECP >::PrivateKey PrivateKey;
CryptoPP::ECIES< CryptoPP::ECP >::PublicKey PublicKey;
CryptoPP::AutoSeededRandomPool rng;
// Key Generation (160 bit curve)
// See Jason Smethers post at the following for a copy/paste
of other curves:
// http://www.mail-archive.com/[email protected]/msg02770.html
PrivateKey.Initialize( rng, CryptoPP::ASN1::secp160r2() );
PrivateKey.MakePublicKey( PublicKey );
// Key Validation
if( false == PrivateKey.Validate( rng, 6 ) ) { throw
std::string( "Private Key Validation" ); }
if( false == PublicKey.Validate( rng, 6 ) ) { throw
std::string( "Public Key Validation" ); }
// Encryptor and Decryptor
CryptoPP::ECIES< CryptoPP::ECP >::Encryptor Encryptor( PublicKey );
CryptoPP::ECIES< CryptoPP::ECP >::Decryptor Decryptor( PrivateKey );
// Message
// std::string PlainText = "ECC Test";
std::string PlainText = "Now is the time for all good men to
come to the aid of their country";
// Runtime Sizes...
unsigned int PlainTextLength = PlainText.length() + 1;
unsigned int CipherTextLength = Encryptor.CiphertextLength(
PlainText.length() + 1 );
if( 0 == CipherTextLength ) { throw
std::string("plaintextLength is not valid (too long)"); }
// Diagnostics
std::cout << "The plain text is '" << PlainText << "'" << std::endl;
std::cout << "The plain text length is " << PlainTextLength <<
" (including the trailing '\\0')" << std::endl;
std::cout << "The cipher text length for this message is " <<
CipherTextLength << std::endl;
// Scratch for Encryption
byte* CipherText = new byte[ CipherTextLength ];
if( NULL == CipherText ) { throw std::string( "CipherText
Allocation Failure" ); }
::memset( CipherText, 0xFB, Encryptor.CiphertextLength(
PlainTextLength ) );
// Encryption
Encryptor.Encrypt( rng, reinterpret_cast<const byte*>(
PlainText.c_str() ), PlainTextLength, CipherText );
//
// Take a break...
//
std::cout << std::endl;
// Scratch for Decryption
unsigned int RecoveredTextLength =
Decryptor.MaxPlaintextLength( CipherTextLength );
if( 0 == RecoveredTextLength ) { throw
std::string("ciphertextLength is not valid (too long or too short)");
}
byte* RecoveredText = new byte[ RecoveredTextLength ];
if( NULL == RecoveredText ) { throw std::string(
"RecoveredText CipherText Allocation Failure" ); }
::memset( RecoveredText, 0xFB, PlainTextLength );
// Decryption
Decryptor.Decrypt( rng, CipherText, CipherTextLength, RecoveredText );
// Diagnostics
std::cout << "The recovered text length for this curve is " <<
RecoveredTextLength << std::endl;
std::cout << "The recovered text for this curve is '" <<
reinterpret_cast<char*>( RecoveredText ) << "'" << std::endl;
// Cleanup
if( NULL != CipherText ) { delete[] CipherText; }
if( NULL != RecoveredText ) { delete[] RecoveredText; }
}
catch( CryptoPP::Exception& e ) {
std::cerr << "Crypto++ Error: " << e.what() << std::endl;
return -3;
}
catch( std::string& s ) {
std::cerr << "Error: " << s << std::endl;
return -2;
}
catch (...) {
std::cerr << "Unknown Error" << std::endl;
return -1;
}
return 0;
}