Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce the number of DoubleCRT constants in unpack function #231

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

fionser
Copy link
Contributor

@fionser fionser commented Jul 11, 2018

PR for this issue.

@fionser
Copy link
Contributor Author

fionser commented Jul 12, 2018

Unfortunately, the current code increases the number of frobeniusAutomorph (i.e., O(d^2)) times.
(Perhaps with the Baby-step/Giant-step tech, we can reduce it to O(d \sqrt(d)))
Even with hoisting, I found it slower than previous version.


Following is slow due to O(d^2) frobeniusAutomorph;

    DoubleCRT coeff(unpackSlotEncoding.front(), ctxt.getContext(), ctxt.getPrimeSet());
    Ctxt tmp1(ZeroCtxtLike, ctxt);
    for (long i = 0; i < unpacked.size(); i++) {
        /// accumulative frobenius: frobenius(v, 2) = frobenius(frobenius(v, 1), 1)
        if (i > 0)
            coeff.automorph(t % m); 
        *(unpacked[i]) = ctxt;
        unpacked[i]->multByConstant(coeff);
        Ctxt origin(*unpacked[i]);
        /// TODO use hoisting here
        for (long j = 1; j < d; j++) {
            tmp1 = origin;
            tmp1.frobeniusAutomorph(j);
            tmp1.cleanUp();
            *(unpacked[i]) += tmp1;
        }
    }

A quick fix is to exchange the outer-side and inner-side loop.
This keeps the number of frobeniusAutomorph to O(d); at the cost of increasing the number of
multByConstant from O(d) to O(d^2) (also, with BSGS, it should be O(d sqrt(d))

// make sure the unpacked ciphertext is empty
    for (long i = 0; i < unpacked.size(); i++)
        unpacked[i]->clear();

    DoubleCRT coeff(unpackSlotEncoding.front(), ctxt.getContext(), ctxt.getPrimeSet());
    Ctxt tmp1(ZeroCtxtLike, ctxt);
    Ctxt tmp2(ZeroCtxtLike, ctxt);
    /// TODO Use hoisting for the outer-loop
    for (long j = 0; j < d; j++) {
        tmp1 = ctxt;
        tmp1.frobeniusAutomorph(j);
        tmp1.cleanUp();
        for (long i = 0; i < unpacked.size(); i++) {
            tmp2 = tmp1;
            auto coeff_cpy{coeff};
            coeff_cpy.automorph(NTL::PowerMod(t, mcMod(i + j, d), m));
            tmp2.multByConstant(coeff_cpy);
            *unpacked[i] += tmp2;
        }
    }

@faberga
Copy link
Collaborator

faberga commented Jul 21, 2022

Hi @fionser, would you have time to rebase your fork and check the conflicts or whether your suggestions still apply to the newer version of HElib, please?

Thank you

@faberga faberga marked this pull request as draft December 22, 2022 23:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants