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;
}

Reply via email to