ECP::ValidateParameters() checks that !m_b.IsNegative() && m_b<p. So you need to do b %= p at least.

But you need to figure out why VC++ is not letting your debug Crypto++. Is it missing symbols for the DLL?

----- Original Message ----- From: "Jeffrey Walton" <[EMAIL PROTECTED]>
To: "Crypto" <[email protected]>
Sent: Friday, November 10, 2006 7:26 AM
Subject: Using Crypto++ with ECIES and User Defined Domain Parameters


// Runtime Includes
#include <iostream>
#include <string>

// Crypto++ Library
#ifdef _DEBUG
#  pragma comment ( lib, "cryptlibd" )
#else
#  pragma comment ( lib, "cryptlib" )
#endif

// Crypto++ Includes
#include "cryptlib.h"
#include "osrng.h"      // Random Number Generator
#include "eccrypto.h"   // Elliptic Curve
#include "ecp.h"        // F(p) EC
#include "integer.h"    // Integer Operations
#include "nbtheory.h"   // ModularSquareRoot(...)

//
// Fuction Prototype
//   Solves y^2 === x^3 + a*x + b (mod p)
//
CryptoPP::Integer Y(CryptoPP::Integer x, CryptoPP::Integer a,
                   CryptoPP::Integer b, CryptoPP::Integer p);

//
// The following parameters were generated using Elliptic Curve Builder
//   ECB can be downloaded at http://www.ellipsa.net/
//
// P = 54972968989
// R = 27486254087
// S = 2
// A = 41049296989
// B = -7218879543

// P = 10067747603
// R = 10067650487
// S = 1
// A = 9184076370
// B = -320466536

// P = 62348328737
// R = 62348265779
// S = 1
// A = 29283225645
// B = -14090433241


int main(int argc, char* argv[]) {

   try {

       CryptoPP::AutoSeededRandomPool rng;

       // User Defined Domain Parameters
       CryptoPP::Integer p("62348328737");

       CryptoPP::Integer n("62348265779");          // R from ECB
CryptoPP::Integer h("1"); // S from ECB, must be <= 4

       CryptoPP::Integer a("29283225645");
       CryptoPP::Integer b("-14090433241");

       CryptoPP::Integer x = n;
       CryptoPP::Integer y = Y( x, a, b, p );

       CryptoPP::ECP ec( p, a, b );
       CryptoPP::ECP::Point G( x, y );

       CryptoPP::ECIES< CryptoPP::ECP >::PrivateKey    PrivateKey;
       CryptoPP::ECIES< CryptoPP::ECP >::PublicKey     PublicKey;

       //
       // Curve Initialization and Key Generation
       //
       PrivateKey.Initialize( ec, G, n, h );
       PrivateKey.MakePublicKey( PublicKey );

       //
       // Key Validation
       //
       //   User Defined Domain Parameters always fail, even at level 0???
       //
       //   From cryptlib.h, Validate(...):
       //
       //   0 - using this object won't cause a crash or exception
(rng is ignored)
       //   1 - this object will probably function (encrypt, sign,
etc.) correctly
       //       (but may not check for weak keys and such)
       //   2 - make sure this object will function correctly, and do
reasonable
       //       security checks
       //   3 - do checks that may take a long time
       //
       // if( false == PrivateKey.Validate( rng, 0 ) ) { throw
std::string( "Private Key Validation" ); }
       // if( false == PublicKey.Validate( rng, 0 ) ) { 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 ";
       // std::string PlainText = "ECC Test";
// std::string PlainText = "Yoda said, Do or do not. There is no try.";
       // std::string PlainText = "Winnie the Pooh said, I am a bear
of very little brain, and long words bother me.";

       // Runtime Sizes...
       unsigned int PlainTextLength = PlainText.length() + 1;
       unsigned int CipherTextLength = Encryptor.CiphertextLength(
PlainTextLength );
       if( 0 == CipherTextLength ) { throw
std::string("plaintextLength is not valid (too long)"); }

       // Diagnostics
       std::cout << "Plain text (" << PlainTextLength << " bytes
including the trailing '\\0'):";
       std::cout << std::endl << "'" << PlainText << "'" << std::endl
<< 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 );

       // Scratch for Decryption
       unsigned int RecoveredTextLength =
Decryptor.MaxPlaintextLength( CipherTextLength );
       if( 0 == RecoveredTextLength ) { throw
std::string("ciphertextLength is not valid (too long or too short)");
}

       // Decryption Buffer
       char* RecoveredText = new char[ RecoveredTextLength ];
       if( NULL == RecoveredText ) { throw std::string(
"RecoveredText CipherText Allocation Failure" ); }
       ::memset( RecoveredText, 0xFB, RecoveredTextLength );

       // Decryption
       Decryptor.Decrypt( rng, CipherText, CipherTextLength,
reinterpret_cast<byte*>( RecoveredText ) );

       // Diagnostics
       std::cout << "Recovered text (" << RecoveredTextLength << "
bytes):" << std::endl;
       std::cout << "'" << 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;
   }

   catch( std::string& s ) {
       std::cerr << "Error: " << s << std::endl;
   }

   catch (...) {
       std::cerr << "Unknown Error" << std::endl;
   }

return 0;
}

CryptoPP::Integer Y(CryptoPP::Integer x, CryptoPP::Integer a,
                   CryptoPP::Integer b, CryptoPP::Integer p)
{
   // if( b < 0 ) { b += p; }

   CryptoPP::Integer y = CryptoPP::a_exp_b_mod_c( x, 3, p );
   y += a * x + b;
   y %= p;
   y = CryptoPP::ModularSquareRoot( y, p );

#ifdef _DEBUG
   std::cout << std::endl;
   std::cout << "Point G: " << std::endl;
   std::cout << "  X: " << x << std::endl;
   std::cout << "  Y: " << y << std::endl;
   std::cout << std::endl;
#endif

   //
   // If y = 0, the cipher text will not decrypt properly
   //  In this case, generate different Domain Parameters
   //
   return y;
}



Reply via email to