weidai11 / cryptopp

free C++ class library of cryptographic schemes
https://cryptopp.com
Other
4.67k stars 1.47k forks source link

Doubt about El Gamal and homomorphic encryption #1196

Closed jtovartr closed 1 year ago

jtovartr commented 1 year ago

Hi everyone. I am using crypto++ and I want to perform homomorphic operations with the ElGamal algorithm. ElGamal is partially homomorphic as it allows to perform multiplication of encrypted numbers.

This is my code:

#include <iostream>
#include <string>
#include <cryptopp/cryptlib.h>
#include <cryptopp/elgamal.h>
#include <cryptopp/osrng.h>

using namespace CryptoPP;

int main()
{
    AutoSeededRandomPool rng;

    // Key Generation
    ElGamalKeys::PrivateKey privateKey;
    privateKey.GenerateRandomWithKeySize(rng, 1024);
    ElGamalKeys::PublicKey publicKey;
    privateKey.MakePublicKey(publicKey);

    // Integers to be encrypted
    Integer a(4);
    Integer b(3);

    // Encryptor generation
    ElGamal::Encryptor encryptor(publicKey);

    size_t ciphertextLength = encryptor.FixedCiphertextLength();
    SecByteBlock cA(ciphertextLength), cB(ciphertextLength);

    encryptor.Encrypt(rng, (const byte*)&a, sizeof(a), cA);
    encryptor.Encrypt(rng, (const byte*)&b, sizeof(b), cB);

    // Convert ciphertexts to Integer objects
    Integer cA_int, cB_int;
    cA_int.Decode(cA.BytePtr(), cA.SizeInBytes());
    cB_int.Decode(cB.BytePtr(), cB.SizeInBytes());

    // Perform homomorphic multiplication
    Integer c_int = cA_int * cB_int;

    size_t encodedSize = c_int.MinEncodedSize();
    SecByteBlock cC(encodedSize);
    c_int.Encode(cC.BytePtr(), encodedSize);

    ElGamal::Decryptor decryptor(privateKey);
    size_t maxPlaintextLength = decryptor.FixedMaxPlaintextLength();
    SecByteBlock plaintext(maxPlaintextLength);
    decryptor.Decrypt(rng, cC, maxPlaintextLength, plaintext);

    // Convert plain text from SecByteBlock to Integer
    Integer d;
    d.Decode(plaintext.BytePtr(), plaintext.SizeInBytes());

    std::cout << "Result: " << d << std::endl;

    return 0;
}

It is not possible to perform a multiplication operation directly on an object of type SecByteBlock, so I transform it to Integer. Then I transform that Integer resulting from the multiplication to SecByteBlock again to be able to perform the decryption. But the result is not as expected:

Resultado: 6572542917472774608382513568834410162264727377934020617765694936645066385167133740454762877696206395258184095730713170221027471130699023727953324305437694949176326086512309951748266792467002364743251219060740803489028914257686331972414715950498994982718110805408070136337150258922387413393882346422272.

Can someone help me or give me some advice on how to perform the homomorphic operation?