snucrypto / HEAAN

Other
359 stars 94 forks source link

Why is `sub` inaccurate? #32

Open jayavanth opened 5 years ago

jayavanth commented 5 years ago

Here's the code to reproduce sub compared to unencrypted


#include "../src/HEAAN.h"
#include "../src/SchemeAlgo.h"

double *randomRealArray(long n, double bound)
{
    double *res = new double[n];
    for (long i = 0; i < n; ++i)
    {
        res[i] = EvaluatorUtils::randomReal(bound);
    }
    return res;
}

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

    long logq = 1200; 
    long logp = 50;   
    long logSlots = 4;
    long logT = 2;    
    long logI = 4;
    long logQ = 1200;
    long boot_logq =62;
    long loopy=12;

    srand(time(NULL));
    SetNumThreads(8);
    TimeUtils timeutils;
    Ring ring;
    SecretKey secretKey(ring);
    Scheme scheme(secretKey, ring);

    long slots = (1 << logSlots);
    double* x = randomRealArray(slots, 1.0);
    double* y = randomRealArray(slots, 1.0);
    double* z = randomRealArray(slots, 1.0);

    Ciphertext cipherx, ciphery, cipherz;
    scheme.encrypt(cipherx, x, slots, logp, logq);
    scheme.encrypt(ciphery, y, slots, logp, logq);

    // sub unenc
    for (long i = 0; i < slots; ++i)
    {
        z[i] = y[i] - x[i];
        // z[i] = y[i] + x[i];
    }

    double* dval = new double[slots];

    scheme.sub(cipherz, ciphery, cipherx);
    // scheme.add(cipherz, ciphery, cipherx);

    std::cout << "decrypt to compare" << std::endl;
    dval = scheme.decrypt_double(secretKey, cipherz);
    StringUtils::compare(z, dval, slots, "boot");

    return 0;
}

This results in the output : https://pastebin.com/4EmFZvdQ

Also, is there an alternative? The alternatives negate() -> add() OR multByConst(-1) -> add() are also resulting in similar error ranges.

gamma-2017 commented 4 years ago

Hi. Tried that with

complex<double> *dvalc = scheme.decrypt(secretKey, cipherz);
for (long i=0; i<slots; i++)
    dval[i] = dvalc[i].real();

instead of your scheme.decrypt_double line. That works and produces errors of size 3e-15.