4

I wan to encrypt /decrypt data using ECIES , I am using cryptopp for this.

AutoSeededRandomPool prng;

//get private key generated
ECIES<ECP>::Decryptor d0(prng, ASN1::secp256r1());
PrintPrivateKey(d0.GetKey());

//get public key 
ECIES<ECP>::Encryptor e0(d0);
PrintPublicKey(e0.GetKey());

//encrypt the message
string em0; // encrypted message
StringSource ss1 (message, true, new PK_EncryptorFilter(prng, e0, new StringSink(em0) ) );

//decrypt the message   
string dm0; // decrypted message
StringSource ss2 (em0, true, new PK_DecryptorFilter(prng, d1, new StringSink(dm0) ) );

Everything else is fine but I want to do the above same thing using already generated 'private key' and not randomly generated 'private key' unlike the case above. How can I do this?

I have tried the following code but it just simply crashes

AutoSeededRandomPool prng;

std::string  privatekeyString="02C200102C180F9E6A4E7A2F58B5BE86BC179478";

CryptoPP::HexDecoder decoder;
decoder.Put((byte*)privatekeyString.data(), privatekeyString.size());
decoder.MessageEnd();

ECIES<ECP> ::Decryptor d0;
d0.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());

crash point

//load private key  
d0.AccessKey().Load(decoder);
PrintPrivateKey(d0.GetKey());

//get public key    
ECIES<ECP>::Encryptor e0(d0);
PrintPublicKey(e0.GetKey());

string em0; // encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, e0, new StringSink(em0) ) );
cout<<"encrypted msg: "<<em0<<"  and its length: "<<em0.length()<<endl;

string dm0; // decrypted message
StringSource ss2 (em0, true, new PK_DecryptorFilter(prng, d0, new StringSink(dm0) ) );
cout <<"decrypted msg: "<< dm0<<"  and its length: "<<dm0.length() <<   endl;

Edit 2

In response to @jww answer I managed to decode the message with the private key as:

  try
  {
    AutoSeededRandomPool prng;

    std::string exponent="AsIAECwYD55qTnovWLW+hrwXlHg=";
    StringSource ss(exponent, true /*pumpAll*/, new CryptoPP::HexDecoder);


    Integer x;
    x.Decode(ss, ss.MaxRetrievable(), Integer::UNSIGNED);
    // cout << "Exponent: " << std::hex << x << endl;

    ECIES<ECP>::Decryptor decryptor;
    decryptor.AccessKey().Initialize(ASN1::secp128r1(), x);

    bool valid = decryptor.AccessKey().Validate(prng, 3);
    if(!valid)
    {
        cout<<"Exponent is not valid for P-128"<<endl;
        return;
    }
      //  throw  Exception(CryptoPP::Exception::OTHER_ERROR, "Exponent is not valid for P-256");

    // Or: decryptor.AccessKey().ThrowIfInvalid(prng, 3);

    cout << "Exponent is valid for P-128" << endl;

    PrintPrivateKey(decryptor.GetKey());


    //get public key
    ECIES<ECP>::Encryptor encryptor(decryptor);
    PrintPublicKey(encryptor.GetKey());



    string em0; // encrypted message
    StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(em0) ) );
    cout<<"encrypted msg: "<<em0<<"  and its length: "<<em0.length()<<endl;

    string dm0; // decrypted message
    StringSource ss2 (em0, true, new PK_DecryptorFilter(prng, decryptor, new StringSink(dm0) ) );
    cout <<"decrypted msg: "<< dm0<<"  and its length: "<<dm0.length() << endl;

}
catch(const CryptoPP::Exception& ex)
{
    std::cerr << ex.what() << endl;
}

But when I try to encrypt the message using public key I got error

CryptoPP::CryptoMaterial::InvalidMaterial: CryptoMaterial: this object contains invalid values

Here is my code:

std::string     public_point="AsIAEFjzIcX+Kvhe8AmLoGUc8aYAEAwf5ecREGZ2u4RLxQuav/A=";
StringSource ss(public_point, true, new CryptoPP::HexDecoder);

ECIES<ECP>::Encryptor encryptor;
    encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());

ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "X: " << std::hex << point.x << endl;
cout << "Y: " << std::hex << point.y << endl;

encryptor.AccessKey().SetPublicElement(point);


encryptor.AccessKey().ThrowIfInvalid(prng, 3);

PrintPublicKey(encryptor.GetKey());



string em0; // encrypted message
StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(em0) ) );
cout<<"encrypted msg: "<<em0<<"  and its length: "<<em0.length()<<endl;
SandeepAggarwal
  • 1,273
  • 3
  • 14
  • 38
  • *"I have tried the following code but it just simply crashes..."* - what is the crash or the error? Please state where you got the private key from, and what they told you it was. – jww Jun 17 '15 at 02:18
  • In your edits, you need to use a `Base64Decoder`, and not a `HexDecoder`. – jww Jun 17 '15 at 07:37
  • @jww how can I add a nonce using iv(initialization vector) to the encryption /decryption part? – SandeepAggarwal Jul 09 '15 at 11:30
  • You can't/don't set an IV. ECIES provides everything needed in the Key Encapsulation Mechanism (KEM). Effectively, there's a big seed encrypted under your EC key. The seed material is decrypted and then digested. The seed is then used to generate a key stream. Then, the key stream is XOR'd with the plain text (to encrypt) or cipher text (to decrypt). About the most you can do is seed the PRNG used in the process. – jww Jul 09 '15 at 12:13
  • @jww we have to use the same token again and again, that is why we have to somehow include nonce.What is the best way to include it? – SandeepAggarwal Jul 09 '15 at 12:34
  • *"What is the best way to include it?"* - Use a deterministic PRNG. A deterministic PRNG will produce the same stream given the same seed. So use the Nonce/IV as a seed to the PRNG. For a deterministic PRNG, see [RandomNumberGenerator | Reproducibility](http://www.cryptopp.com/wiki/RandomNumberGenerator#Reproducibility) on the Crypto++ Wiki. It could be a bad idea, though (but I am just [bike shedding](http://bikeshed.com/) because I don't have a complete picture of what you are trying to accomplish). – jww Jul 09 '15 at 12:54
  • I think I am unable to make you understand the process.The token which we are trying to encrypt produces different encrypted text and that is pretty good for us but lets suppose the case of middlemen attack in which he gets our encrypted text which he could he can use in future (since any randomised version of encrypted text produced by ecies gets decrypted to the same token) , so I wanted to send a nonce value encrypted along with original token and nonce as well which we can compare at decryption end whether it was used before or not. – SandeepAggarwal Jul 09 '15 at 13:04
  • Going back to: *"...we have to use the same token again and again, that is why we have to somehow include nonce..."* - is the token or nonce part of the message? I mean, is it unencrypted data that needs to be encrypted under ECIES? – jww Jul 09 '15 at 13:38
  • yes, this is what the concept of nonce I suppose. – SandeepAggarwal Jul 09 '15 at 13:43
  • A nonce originally was a one-time byte block used in challenge/response protocols. More recently, its use includes the random part of a counter for CTR mode ciphers. When you say nonce in the context of ECIES, I think you are trying to use it with the stream cipher because CTR mode adapts a block cipher to a stream cipher :) – jww Jul 09 '15 at 13:56
  • Since the token or nonce is part of the message, just prepend it the the message and encrypt it. Open another question if you are having trouble writing or reading the bytes in the plain text message. Or see the use of `PutWord32` and `GetWord32` at [InvalidCiphertext exception when decrypting ciphertext](http://stackoverflow.com/a/28131144/608639). – jww Jul 09 '15 at 16:06

3 Answers3

3

The problem I am having is you don't appear to know what you have, and the some of the parameters you are using are wrong when taken with the other parameters. So its pretty much a stab in the dark.


First, you should wrap the disk operations in a try/catch. I/O can always cause problems, so be sure to catch exceptions related to the iostream stuff. You should also catch the Crypto++ Exception related to key loading. That will handle the "crash" with no information.

So your code might look something like:

try
{
    // Read key from disk, load it into Crypto++ object
}
catch(const Exception& ex)
{
    cerr << "Caught Crypto++ exception " << ex.what() << endl;
}
catch(const std::runtime_error& ex)
{
    cerr << "Caught C++ runtime error " << ex.what() << endl;
}

Second, this looks like a private exponent, and not a private key:

std::string  privatekeyString="02C200102C180F9E6A4E7A2F58B5BE86BC179478";

And its too big to be in P-128. Maybe you should do something like:

try
{
    AutoSeededRandomPool prng;

    std::string exponent="02C200102C180F9E6A4E7A2F58B5BE86BC179478";
    StringSource ss(exponent, true /*pumpAll*/, new HexDecoder);

    Integer x;
    x.Decode(ss, ss.MaxRetrievable(), Integer::UNSIGNED);        
    // cout << "Exponent: " << std::hex << x << endl;

    ECIES<ECP>::Decryptor decryptor;
    decryptor.AccessKey().Initialize(ASN1::secp256r1(), x);

    bool valid = decryptor.AccessKey().Validate(prng, 3);
    if(!valid)
        throw  Exception(Exception::OTHER_ERROR, "Exponent is not valid for P-256");

    // Or: decryptor.AccessKey().ThrowIfInvalid(prng, 3);

    cout << "Exponent is valid for P-256" << endl;        
}
catch(const Exception& ex)
{
    cerr << ex.what() << endl;
}

Or, you can:

ECIES<ECP>::Decryptor decryptor;
decryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp256r1());
decryptor.AccessKey().SetPrivateExponent(x);

If you add the following to the program above:

// Encode key, use OID versus domain paramters
string encoded;
HexEncoder encoder(new StringSink(encoded));

decryptor.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
decryptor.GetKey().Save(encoder);

cout << "Private key: " << encoded << endl;

You will get the following for the private key:

$ ./ecies-test.exe
Exponent: 2c200102c180f9e6a4e7a2f58b5be86bc179478h
Private key: 3041020100301306072A8648CE3D020106082A8648CE3D030107042730250201010
42000000000000000000000000002C200102C180F9E6A4E7A2F58B5BE86BC179478

As you can see, the key is not "02C200102C180F9E6A4E7A2F58B5BE86BC179478".

The 12 leading 0's look suspicious to me. Though the exponent validates, you should verify the exponent and the field. The closest fit I could find is the curve secp160r2 (of course, curves like secp192k1 and secp224k1 work too).

The private key above is the hex encoding of ecies.priv.der shown below.


Third, this could be a public point in compressed form due to the leading 02.

std::string  privatekeyString="02C200102C180F9E6A4E7A2F58B5BE86BC179478";

If that is the case, then you are supposed to be able to do this, but I can't get it to decode the point (see Minimizing Key Size for Persistence on the wiki). x and y are 0 after the operation; maybe the problem is with the field:

std::string public_point="02C200102C180F9E6A4E7A2F58B5BE86BC179478";
StringSource ss(public_point, true, new HexDecoder);

ECIES<ECP>::Encryptor encryptor;
encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp128r1());

ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
cout << "X: " << std::hex << point.x << endl;
cout << "Y: " << std::hex << point.y << endl;

encryptor.AccessKey().SetPublicElement(point);
encryptor.AccessKey().ThrowIfInvalid(prng, 3);

Fourth, you should probably save the entire key, and not just the exponent. Here's a program for you that shows you how to save and load the keys. It also shows you how to perform encryption and decryption in one-liners.

/////////////////////////////////////////////////
// Part one - generate keys

ECIES<ECP>::Decryptor decryptor(prng, ASN1::secp256r1());
ECIES<ECP>::Encryptor encryptor(decryptor);

/////////////////////////////////////////////////
// Part two - save keys

FileSink fs1("ecies.priv.der", true /*binary*/);
decryptor.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
decryptor.GetKey().Save(fs1);

FileSink fs2("ecies.pub.der", true /*binary*/);
encryptor.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
encryptor.GetKey().Save(fs2);

/////////////////////////////////////////////////
// Part three - encrypt/decrypt

string message, encrypted, recovered;

if(argc >= 2 && argv[1] != NULL)
    message = argv[1];
else
    message = "Attack at dawn!";

StringSource ss1 (message,   true /*pumpAll*/, new PK_EncryptorFilter(prng, encryptor, new StringSink(encrypted)));
StringSource ss2 (encrypted, true /*pumpAll*/, new FileSink("ecies.encrypted.bin", true /*binary*/));
StringSource ss3 (encrypted, true /*pumpAll*/, new PK_DecryptorFilter(prng, decryptor, new StringSink(recovered)));

cout << recovered << endl;

Here is what a private key looks like from the test program above. Notice it has the field encoded into the structure so you don't have to guess at it (P-256 versus P-128 versus P-521).

$ dumpasn1 ecies.priv.der 
  0  65: SEQUENCE {
  2   1:   INTEGER 0
  5  19:   SEQUENCE {
  7   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
 16   8:     OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
       :     }
 26  39:   OCTET STRING, encapsulates {
 28  37:     SEQUENCE {
 30   1:       INTEGER 1
 33  32:       OCTET STRING
       :         00 00 00 00 00 00 00 00 00 00 00 00 02 C2 00 10
       :         2C 18 0F 9E 6A 4E 7A 2F 58 B5 BE 86 BC 17 94 78
       :       }
       :     }
       :   }

And the public key:

$ dumpasn1 ecies.pub.der 
  0  89: SEQUENCE {
  2  19:   SEQUENCE {
  4   7:     OBJECT IDENTIFIER ecPublicKey (1 2 840 10045 2 1)
 13   8:     OBJECT IDENTIFIER prime256v1 (1 2 840 10045 3 1 7)
       :     }
 23  66:   BIT STRING
       :     04 08 9B D2 1C 3A DC 08 8B 1F F1 D0 F4 97 A0 87
       :     FE 4F 78 EA E2 B8 30 B8 E7 06 37 68 27 4C 71 CD
       :     63 C3 E2 90 66 64 2B 1C F6 79 00 36 AF 72 4C 61
       :     69 FA E9 06 00 9A 15 32 0B 85 B5 88 B2 C5 88 46
       :     5E
       :   }

Crypto++ has a wiki page on ECIES. See Elliptic Curve Integrated Encryption Scheme. They also have Bouncy Castle interop workarounds.


You can also PEM encode the keys, but you need a patch to do it because its not part of the library. For the patch, see PEM Pack on the Crypto++ wiki.

jww
  • 97,681
  • 90
  • 411
  • 885
  • Thanks a lot for such a detailed answer.What I was doing was I provided the key in hex format instead of base_64 format .The key I used was "AsIAECwYD55qTnovWLW+hrwXlHg=". – SandeepAggarwal Jun 17 '15 at 07:20
  • But I can't make it work using public key .I have edited the code above which was working for decryption but not for encryption using the public key – SandeepAggarwal Jun 17 '15 at 07:27
  • @Sandeep - nope, this does not work either: `std::string key="AsIAECwYD55qTnovWLW+hrwXlHg="; StringSource ss(key, true, new Base64Decoder);` for `P-128`. – jww Jun 17 '15 at 07:32
  • I have used HexDecoder instead of Base64Decoder but the key is itself in base_64 and its working for me .I don't know ,I am confused.Let me think over it once. – SandeepAggarwal Jun 17 '15 at 07:36
  • As you suggested I used Base64Decoder but it was not working for P-128 but for P-256 which is quite unusual because I am getting this private key from server and at server end we are using P-128 curve. – SandeepAggarwal Jun 17 '15 at 07:59
  • @Sandeep - the private exponent `x` needs to be smaller than the subgroup generator. The `x` you provided ***does not*** satisfy that for `secp128r1`, but does satisfy that for other curves like `secp160r2`, `secp192k1` and `secp224k1`. You need to tell us everything you are doing/using. It still sounds like to me you don't even know the curve you are supposed to be using. And its not clear at all (to me) why you are sending the private exponent to a client... They should probably get the public point. – jww Jun 17 '15 at 09:23
  • hi I'm Ankit, Sandeep's colleague. First of all thank you for taking time out for helping us. We are pretty much noobs in security and are trying to implement an architecture like this: http://security.stackexchange.com/questions/86516/. I guess this link should give you an overall idea of the architecture. – SandeepAggarwal Jun 17 '15 at 09:45
  • Ankit has already posted a similar problem on SO http://stackoverflow.com/questions/30868936/ – SandeepAggarwal Jun 17 '15 at 09:50
  • @Sandeep/Ankit - I think you are right in using ECIES, but I'd need to hear more details. You just need to transfer the public key to the peer. If its Bluetooth/NFC (or any other near field radio), then you should be OK because you can simply transfer the public key proximally. The "closeness" of the handsets provides a location limited channel, which is a very strong form of authentication. If its not proximal, then you have to solve the key distribution problem. That is, how does ***B*** know it got an authentic copy of ***A***'s public key? – jww Jun 17 '15 at 09:53
  • @Sandeep/Ankit - TLS solves the key distribution problem with CAs, but TLS has a lot of other baggage. When used in Browsers, it also suffers the web security model (which has so many holes you can drive a truck through them). You ***really*** want to avoid that security model. By the way, that security model is baked into Android and iOS... – jww Jun 17 '15 at 09:56
  • I had this thought initially, but I was not very sure if attacks like MITM are possible on the Bluetooth/NFC. And also i read that BLE (Bluetooth 4.0) is not secure and a new security model will be introduced in Bluetooth 4.2 (http://blog.bluetooth.com/everything-you-always-wanted-to-know-about-bluetooth-security-in-bluetooth-4-2/). Most of the devices right now have Bluetooth 4.0. So which security model would you recommend, remember we are noobs :) ? – SandeepAggarwal Jun 17 '15 at 10:07
2

I'm going to add another answer to show you how to serialize private exponents and public points in case you had trouble with the public points. It also shows you how to Save the PrivateKeyInfo and SubjectPublicKeyInfo.

Its produces output similar to below. You will need a patch for the Base64URLEncoder. its not part of the library.

$ ./ecies-test.exe
Private exponent
  Hex: 57E91FA3EF48706D07E56D8CB566204A4416B833EFB9687D75A37D572EC42277
  Base64: V+kfo+9IcG0H5W2MtWYgSkQWuDPvuWh9daN9Vy7EInc=
  Base64 (URL safe): V-kfo-9IcG0H5W2MtWYgSkQWuDPvuWh9daN9Vy7EInc=
Pubic point
  Hex: 037142DE6143B6AD44C74135FE71222AC1406F541E53CB635112DE4928EC94763C
  Base64: A3FC3mFDtq1Ex0E1/nEiKsFAb1QeU8tjURLeSSjslHY8
  Base64 (URL safe): A3FC3mFDtq1Ex0E1_nEiKsFAb1QeU8tjURLeSSjslHY8
Private key (PrivateKeyInfo)
  3059301306072A8648CE3D020106082A8648CE3D030107034200047142DE6143B6AD44C74135FE71
  222AC1406F541E53CB635112DE4928EC94763CFA903D9282691AE47A2D718297465EF44E905A89ED
  2D4553ED1DF906A6E2383B
Public key (SubjectPublicKeyInfo)
  3041020100301306072A8648CE3D020106082A8648CE3D03010704273025020101042057E91FA3EF
  48706D07E56D8CB566204A4416B833EFB9687D75A37D572EC42277

With the private exponent and public point above, the following works just fine:

string pub_point("A7EDDUXAA4/6kOZ8H+firJ95YtKZvDrPFmyVoisyBfuW");
StringSource ss(pub_point, true, new Base64Decoder);

ECIES<ECP>::Encryptor encryptor;
encryptor.AccessKey().AccessGroupParameters().Initialize(ASN1::secp256r1());

ECP::Point point;
encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());

encryptor.AccessKey().SetPublicElement(point);
encryptor.AccessKey().ThrowIfInvalid(prng, 3);

ECIES<ECP>::Decryptor decryptor;
decryptor.AccessKey().Initialize(prng, ASN1::secp256r1());

const Integer& priv_exp = decryptor.GetKey().GetPrivateExponent();
SecByteBlock x(priv_exp.MinEncodedSize());
priv_exp.Encode(x, x.size());

string s1, s2, s3;    
HexEncoder f1(new StringSink(s1));
Base64Encoder f2(new StringSink(s2));
Base64URLEncoder f3(new StringSink(s3));

ChannelSwitch cs1;
cs1.AddDefaultRoute(f1);
cs1.AddDefaultRoute(f2);
cs1.AddDefaultRoute(f3);

ArraySource as1(x, x.size(), true /*pumpAll*/, new Redirector(cs1));

cout << "Private exponent" << endl;
cout << "  Hex: " << s1 << endl;
cout << "  Base64: " << s2 << endl;
cout << "  Base64 (URL safe): " << s3 << endl;

//////////////////////////////////////////

ECIES<ECP>::Encryptor encryptor(decryptor);
ECP::Point pub_point = encryptor.GetKey().GetGroupParameters().ExponentiateBase(priv_exp);
SecByteBlock y(encryptor.GetKey().GetGroupParameters().GetCurve().EncodedPointSize(true /*compressed*/));
encryptor.GetKey().GetGroupParameters().GetCurve().EncodePoint(y, pub_point, true /*compressed*/);

string s4, s5, s6;    
HexEncoder f4(new StringSink(s4));
Base64Encoder f5(new StringSink(s5));
Base64URLEncoder f6(new StringSink(s6));

ChannelSwitch cs2;
cs2.AddDefaultRoute(f4);
cs2.AddDefaultRoute(f5);
cs2.AddDefaultRoute(f6);

ArraySource as2(y, y.size(), true /*pumpAll*/, new Redirector(cs2));

cout << "Pubic point" << endl;
cout << "  Hex: " << s4 << endl;
cout << "  Base64: " << s5 << endl;
cout << "  Base64 (URL safe): " << s6 << endl;

//////////////////////////////////////////

string s10, s11;
HexEncoder hex1(new StringSink(s10));
HexEncoder hex2(new StringSink(s11));

encryptor.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
encryptor.GetKey().Save(hex1);
decryptor.AccessKey().AccessGroupParameters().SetEncodeAsOID(true);
decryptor.GetKey().Save(hex2);

cout << "Private key" << endl;
cout << s10 << endl;

cout << "Public key" << endl;
cout << s11 << endl;
jww
  • 97,681
  • 90
  • 411
  • 885
0

As jww suggested I have successfully completed encryption and decryption. Below are the code snippets if anyone wants.

Decryption

string decrypt(std::string encryptedMessage ,  std::string   privateKeyExponent)
{
    string decryptedMessage;
    try
    {
        AutoSeededRandomPool prng;

        //since the 'privateKeyExponent' is in base-64 format use Base64Decoder
        StringSource ss(privateKeyExponent, true /*pumpAll*/, new CryptoPP::Base64Decoder);

        Integer x;
        x.Decode(ss, ss.MaxRetrievable(), Integer::UNSIGNED);

        ECIES<ECP>::Decryptor decryptor;

        //curve used is secp256k1
        //make decryptor's access key using decoded private exponent's value
        decryptor.AccessKey().Initialize(ASN1::secp256k1(), x);

        //check whether decryptor's access key is valid or not
        bool valid = decryptor.AccessKey().Validate(prng, 3);
        if(!valid)
           decryptor.AccessKey().ThrowIfInvalid(prng, 3);

        cout << "Exponent is valid for P-256k1" << endl;

        //decrypt the message using private key
        StringSource ss2 (encryptedMessage, true, new PK_DecryptorFilter(prng, decryptor, new StringSink(decryptedMessage) ) );
        cout <<"decrypted msg: "<< decryptedMessage<<"  and its length: "<<decryptedMessage.length() << endl;

    }
    catch(const CryptoPP::Exception& ex)
    {
        std::cerr << ex.what() << endl;
    }
    return decryptedMessage;
}

Encryption

string encrypt(std::string message ,  std::string  compressedPublicKeyPoint)
{
    string encryptedMessage;
    try
    {
        AutoSeededRandomPool prng;

        //public key is a point consisting of "public key point x" and "public key point y"
        //compressed public key also known as "public-point" formed using point-compression of public key


        //since the key is in base-64 format use Base64Decoder
        StringSource ss(compressedPublicKeyPoint, true, new CryptoPP::Base64Decoder);
     ECIES<ECP>::Encryptor encryptor;

        //curve used is secp256k1
        encryptor.AccessKey().AccessGroupParameters()
       .Initialize(ASN1::secp256k1());

        //get point on the used curve
        ECP::Point point;
        encryptor.GetKey().GetGroupParameters().GetCurve().DecodePoint(point, ss, ss.MaxRetrievable());
        cout << "X: " << std::hex << point.x << endl;
        cout << "Y: " << std::hex << point.y << endl;

        //set encryptor's public element
        encryptor.AccessKey().SetPublicElement(point);

        //check whether the encryptor's access key thus formed is valid or not
        encryptor.AccessKey().ThrowIfInvalid(prng, 3);

        // encrypted message
        StringSource ss1(message, true, new PK_EncryptorFilter(prng, encryptor, new StringSink(encryptedMessage) ) );
        cout<<"encrypted msg: "<<encryptedMessage<<"  and its length: "<<encryptedMessage.length()<<endl;
    }
    catch(const CryptoPP::Exception& ex)
    {
        std::cerr << ex.what() << endl;
    }

    return encryptedMessage;
}
Community
  • 1
  • 1
SandeepAggarwal
  • 1,273
  • 3
  • 14
  • 38