void PAILLIER_ENCRYPT()

in src/paillier.c [136:182]


void PAILLIER_ENCRYPT(csprng *RNG, PAILLIER_public_key *PUB, const octet* PT, octet* CT, octet* R)
{
    // plaintext
    BIG_512_60 pt[HFLEN_4096];

    // workspaces
    BIG_512_60 ws1[FFLEN_4096];
    BIG_512_60 ws2[FFLEN_4096];
    BIG_512_60 dws[2 * FFLEN_4096];

    FF_4096_fromOctet(pt, PT, HFLEN_4096);

    // In production generate R from RNG
    if (RNG!=NULL)
    {
        FF_4096_randomnum(ws1, PUB->n2, RNG,FFLEN_4096);
    }
    else
    {
        FF_4096_fromOctet(ws1, R, FFLEN_4096);
    }

    // Output R for Debug
    if (R!=NULL)
    {
        FF_4096_toOctet(R, ws1, FFLEN_4096);
    }

    // r^n
    FF_4096_nt_pow(ws1, ws1, PUB->n, PUB->n2, FFLEN_4096, HFLEN_4096);

    // g^pt = 1 + pt * n
    FF_4096_mul(ws2, pt, PUB->n, HFLEN_4096);
    FF_4096_inc(ws2, 1, FFLEN_4096);
    FF_4096_norm(ws2, FFLEN_4096);

    // ct = g^pt * r^n mod n^2
    FF_4096_mul(dws, ws1, ws2, FFLEN_4096);
    FF_4096_dmod(ws1, dws, PUB->n2, FFLEN_4096);

    // Output
    FF_4096_toOctet(CT, ws1, FFLEN_4096);

    // Clean memory
    FF_4096_zero(ws2, FFLEN_4096);
    FF_4096_zero(pt, HFLEN_4096);
}