snucrypto / heaan Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
Could someone help me to solve this problem? I mean if I want to perform a add operation, such as "addConst",after a mult operation,the add operation doesn't work at all.
like this : m1 = [1], m2 = [2] , m3=[3] m1=m1*m2//m1=[2], then m1=m1+m3//m1still is [2]!!!
and I don't know why.
HElib has a function totalSums which finds the sum of the whole ciphertext array. Is there an equivalent function in HEAAN?
If there does not exist any such functionality currently, could you provide any guidance regarding how to develop such a function?
Thanks!
Is there a way to get inverse for a wider range of input?
#2 suggests increasing the range by increasing the range by sacrificing precision. I was wondering if there were any updates to the library for inverse or division since then. I'm looking into Matrin et al. to see if I can do it for a wider range.
Also, what do the functions idiv
, and all the functions that start with i
do?
Should't Scheme::encode then Scheme::decode give my values back?
Rephrasing the question: why does Scheme::encode call ring::encode with logq+logQ ? Shouldn't it pass logp and logq... Something is strange there. Interestingly, encrypt then decrypt somehow repairs this deficiency...
The following code (extended from Testscheme::testMult) should work and produce mmult2 roughly equal to mmult. But it does not, unless you remove the // comments.
srand(time(NULL));
SetNumThreads(8);
TimeUtils timeutils;
Ring ring;
SecretKey secretKey(ring);
Scheme scheme(secretKey, ring);
long n = (1 << logn);
complex<double>* mvec1 = EvaluatorUtils::randomComplexArray(n);
complex<double>* mvec2 = EvaluatorUtils::randomComplexArray(n);
complex<double>* mmult = new complex<double>[n];
for(long i = 0; i < n; i++) {
mmult[i] = mvec1[i] * mvec2[i];
}
Plaintext pmult;
scheme.encode( pmult, mmult, n, logp, logq, 2.0 );
// pmult.logp += logQ;
// pmult.logq += logQ;
complex<double>* mmult2 = scheme.decode( pmult );
for (long i=0; i<n; i++) { cout << "[" << i << "]=" << mmult[i] << "=" << mmult2[i] << endl; }
/*
Ciphertext cmult;
scheme.encrypt( cmult, mmult, n, logp, logq, 2.0 );
mmult2 = scheme.decrypt( secretKey, cmult );
for (long i=0; i<n; i++) { cout << "[" << i << "]=" << mmult[i] << "=" << mmult2[i] << endl; }
cout << std::make_pair(&pmult,&scheme) << endl;
//*/
I've the following code which calculates 1.1 ^ 9
, it is expected to be 2.357947691
, but it return 0.357948
. When I calculate 1.1 ^ 8
, it is still return a correct answer. Do I call the function wrong? Or is there a limit on the multiplication chain? How can I fix it?
size_t CNT = 9;
complex<double> *values1, *values2;
Ciphertext cipher1, cipher2;
values1 = new complex<double>[n];
values2 = new complex<double>[n];
values1[0].real(1.1);
values2[0].real(1.0);
scheme.encrypt(cipher1, values1, n, logp, logq);
scheme.encrypt(cipher2, values2, n, logp, logq);
for (size_t i = 0; i < CNT; i++)
{
scheme.mult(cipher2, cipher2, cipher1);
scheme.reScaleBy(cipher2, cipher2, logp);
}
auto result = scheme.decrypt(secretKey, cipher2);
Hello.
I found that using the HEAAN library, multiplying too large a number by 0(zero) would not result in 0.
So I wanna fix the number of digits above the decimal point so that it does not get larger than a certain number.
For example, If I set the number of digits above the decimal point to 3, I wanna make it not bigger than the number of three digits(The number of hundreds.).
I'll wait for your answer.
Thank you.
It seems the current FFT codes only work for power-of-2 length;
It might better to pop out a warning when a invalid slots (e.g., 3, 7) are used.
Hi,
I have noticed that other libraries like SEAL have functions for relinearization that are performed after ciphertext-ciphertext multiplication. As I understand, relinearization represents the ciphertext degree from growing too quickly.
However, in HEAAN, I can only find rescaling functions which, while still necessary, are not the same as relinearization.
How does HEAAN handle relinearization?
Any response is appreciated. Thanks!
Hello,
Actually I have two issues. What I want to do is to create a vector like this:
vector cipher_matrix;
cipher_matrix.reserve(n);
for (int i = 0; i < n; i++)
{
//Ciphertext cipher_OneDia;
temp = &plain_diagonals[i][0];
//scheme.encrypt(cipher_OneDia, temp, n, logp, logq);
scheme.encrypt(cipher_matrix[i], temp, n, logp, logq);
//cipher_matrix[i].copy(cipher_OneDia);
}
`
For some reason this doesn't work. And here comes my second issue into play. Whenever HEAAN doesn't like something (wrong parameter, logq or logp doesn't match for an addition) the execution ends in the cpp of a NTL lib called lib.cpp. No exception is thrown, thus any kind of help would be appreciated.
Regards
Hi,
So I am wondering it is an undocumented optimization here ?
Thanks.
Hi.
I tested the function 'testInverseBatch' in TestScheme.
This function is very awesome and helpful to expand other function that i wanna.
By the way, I have a question about the range of input angle .
This function uses the circularArray for generating random number by using cosine and sine trigonometric function. whatever angle is inputted, range of cosine and sine function is absolutely from -1 and 1.
So, this function can be used only for range of number between -1 and 1? or is there any other way to expand the range?
Thanks:)
I am sorry that I didn't find the "/test folder" or "test.cpp" that you mentioned in README.md, is it unavailable now?
Thank you!
scheme->multAndEqual(test1_, test2_);
scheme->reScaleByAndEqual(test1_,logp);
scheme->modDownByAndEqual(test2_,logp);
scheme->addAndEqual(test1_,test2_);
As it is,
When using NTL_EXEC_RANGE I observed that the memory is getting blowed up very much. I was under the impression that the ciphertext variables are shared between threads and hence won't be duplicated and no memory problems should occur. is this correct? Please help me if there is another way to resolve this.
Thank you
Hello.
I am trying to test my homomorphic circuits built up using binary operations on HEAAN. I previously created and tested on HElib.
I need to set the scheme parameters so that all operations are modulo 2. I hope this is possible.
Thank you!
Hello.
I'm trying to use multithreading with the SetNumThreads () function.
After setting up a multithread, how can I use each thread?
I'll wait for your answer.
Thank you.
Hi, I am reading the implementation of HEAANBOOT, which can work greatly.
I am still digging into the math. Could anyone tell me how the rp1, rp2
polynomials in the bootContext work ?
After I "make" in /run and try to ./TestHEAAN, It shows some problems:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
gitpod /workspace/HEAAN/HEAAN/lib $ make all
Building file: ../src/BootContext.cpp
Invoking: GCC C++ Compiler
g++ -I/usr/local/include -O3 -c -std=c++11 -pthread -MMD -MP -MF"src/BootContext.d" -MT"src/BootContext.o" -o "src/BootContext.o" "../src/BootContext.cpp"
In file included from ../src/BootContext.cpp:8:
../src/BootContext.h:11:10: fatal error: NTL/ZZ.h: No such file or directory
11 | #include <NTL/ZZ.h>
| ^~~~~~~~~~
compilation terminated.
make: *** [src/subdir.mk:59: src/BootContext.o] Error 1
I used gitpod. Why isn't it working?
Hello, I am trying to work on Homomorphic Encryption so I try to install and use HEAAN Library.
In their github page, they tell us to create static library libHEAAN.a with make all comment. When I try this I got errors saying M_PI is not defined in this scope. After I redifing pi number as desired then I get an error with sctruct definition timeval then I include
<sys/time.h> in Timeutilites.h then I finally get libHEAAN.a but then I can not add library to any of my compilers or I can not compile from ubuntu command. I always get same respond, the file or directory can not found. What can I do? I am so desperate for help.
Is there a method to judge if the ciphertext is zero or not?
Thank you!
Hi,
I have a question about the fftInv
and fftSpecialInv
;
bitReverse
is placed differently in these two methods: fftInv
call bitReverse
after the butterfly steps while fftSpecialInv
call before the butterfly steps;I want to know till what value I can go for bootstrapping. I have seen that for values less than 100 the bootstrapping is working fine, but beyond that the values are wrapping around some number not sure why. I think the wraparound depends on logp and the value you want to bootstrap. Kindly help me to understand this.
When I use the latest HEAAN, I found I can't save the key and encrypt the array correctly.
Even the simplest code will also happen segmentation faul
.
Environment: Ubuntu18.04.3, NTL-11.4.2
long logq = 300;
long logp = 30;
long logn = 10;
long n = 1 << logn;
TimeUtils timeutils;
Ring ring;
SecretKey secretKey(ring);
Scheme scheme(secretKey, ring, true); //1 is this right?
scheme.addLeftRotKeys(secretKey);
scheme.addRightRotKeys(secretKey);
complex<double>* mvec1 = EvaluatorUtils::randomComplexArray(slots);
complex<double>* mvec2 = EvaluatorUtils::randomComplexArray(slots);
// It's no problem that the program can run to here
cout << "Start Mat Encrypting" << endl;
Ciphertext cipher1;
// 2 Here segmentation fault, I can't encrypt anything.
scheme.encrypt(cipher1, mvec1, n, logp, logq);
Ciphertext cipher2;
scheme.encrypt(cipher2, mvec2, n, logp, logq);
mkdir serkey
.I don't know if I made a mistake with it,
and the serialization can be used in below's HEANN which from KyoohyungHan/HELR
Hi, it seems bootstrapping in this library is faster than the original HEAANBOOT:
TestScheme::testBootstrap(15, 23, 29, 620, 5, 2);
Returns
So, the EvalExp is about 2 times faster, and similar for the linear parts. Can you explain what makes this speedup?
I'm having trouble in setting up the parameters for using the following function:
void Scheme::bootstrapAndEqual(Ciphertext& cipher, long logq, long logQ, long logT, long logI)
Thank you!
These warnings seem to be about real problems:
../src/SerializationUtils.cpp:56:10: warning: address of stack memory associated with local variable 'cipher' returned [-Wreturn-stack-address]
return &cipher;
^~~~~~
../src/SerializationUtils.cpp:74:10: warning: address of stack memory associated with local variable 'key' returned [-Wreturn-stack-address]
return &key;
^~~
clang-8
What is the difference between these two?
I am sorry if I missed anything, but I didn't find any document related to this.
Or is there a way I can estimate it based on what operations I'm doing? e.g. addition, multiplication?
I am sorry if I missed anything, but I didn't find any function about square root in Scheme.cpp
.
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.
Hello,
I am implementing a matrix-vector multiplication as following:
`
Ring ring;
SecretKey sk(ring);
Scheme scheme(sk, ring);
long logq = 800; ///< Ciphertext Modulus. Should be smaller than logQ in "src/Params.h" : 800
long logp = 40; ///Scaling factor.
//Should be smaller than logN in "src/Params.h" : 16 => Max Slots = 65536
long logn = 7; // -> 128
long n = 1<< logn;
for (int j = 0; j < circuitDepth; j ++)
{
std::cout << "Multiplication " << j << std::endl;
//Perform matrix-vector multiplication
scheme.mult(c_multiplicationResult,c_matrix[0],c_fieldVec);
//new cM: logq = logq², logp = logp - logq -> rescale, so that it can be added with c_addIdentity
scheme.reScaleByAndEqual(c_multiplicationResult, logp);
//No multiplication was performed on c_addIdentity, therefore logq still has the initial value. In order to add it with cM the
//logp must match as well.
scheme.modDownByAndEqual(c_addIdentity, logp);
//At the end of the process c_fieldVec will get the value from c_result, which has the same logp and logq as cM now.
//For the next multiplication process they have to match.
scheme.modDownByAndEqual(c_matrix[0],logp);
scheme.add(c_result, c_multiplicationResult, c_addIdentity);
scheme.leftRotateFastAndEqual(c_fieldVec, r);
for(int i = 1; i< n; i++)
{
scheme.mult(c_multiplicationResult,c_matrix[i],c_fieldVec);
scheme.reScaleByAndEqual(c_multiplicationResult, logp);
scheme.modDownByAndEqual(c_matrix[i],logp);
scheme.addAndEqual(c_result, c_multiplicationResult);
scheme.leftRotateFastAndEqual(c_fieldVec, r);
}
}
`
The first multiplication gives me the expected result. But the second result consists of values with 10^187, which I have seen occasionally when the parameter were not correct.
Even though the logp and logq of c_matrix[0] and c_fieldVec matches and I have plenty of bits left (740), the second multiplication does not bring the expected result.
Does someone have an idea what I am doing wrong? Any hint would be much appreciated.
#include "../src/HEAAN.h"
#include "../src/SchemeAlgo.h"
int main(int argc, char **argv)
{
long logq = 1200;
long logp = 50;
long logSlots = 2;
long logT = 2;
long logI = 4;
long logQ = 1200;
long boot_logq = 62;
srand(time(NULL));
SetNumThreads(8);
TimeUtils timeutils;
Ring ring;
SecretKey secretKey(ring);
Scheme scheme(secretKey, ring);
timeutils.start("Key generating");
scheme.addBootKey(secretKey, logSlots, boot_logq + logI);
timeutils.stop("Key generated");
long slots = (1 << logSlots);
vector<double> mval = {1.0, 2.0, 3.0, 4.0};
Ciphertext cipher;
Ciphertext cipherArray[slots];
scheme.encrypt(cipher, &mval.front(), slots, logp, logq);
for (long i=0 ; i < slots ; i++)
scheme.encrypt(cipherArray[i], &mval[i], 1, logp, logq);
scheme.bootstrapAndEqual(cipherArray[0], boot_logq, logQ, logT, logI);
// scheme.bootstrapAndEqual(cipher, boot_logq, logQ, logT, logI);
return 0;
}
This code crashes. But if you comment the boostrapping of cipherArray[0]
and uncomment that of cipher
, it works fine.
Does boostrapping have to be done on ciphers with slots of powers of two that are greater than 0? (logSlots >=1 ?)
Hi, I am new to HEAAN and I have just finished installing the lib and I was running tests in HEAAN/run
.
I got this error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)
Did I miss some dependencies?
Is there a rule I should follow to set logp and logq (and other parameters) while bootstrapping?
In this example:
long logq = 200;
long logp = 50;
long logSlots = 1;
long logQ=1200, logT=2, logI=4;
srand(time(NULL));
SetNumThreads(8);
TimeUtils timeutils;
Ring ring;
SecretKey secretKey(ring);
Scheme scheme(secretKey, ring);
timeutils.start("Key generating");
scheme.addBootKey(secretKey, logSlots, logq + logI);
timeutils.stop("Key generated");
double c = 0.08123123;
long slots = (1 << logSlots);
complex<double>* mvec = EvaluatorUtils::randomComplexArray(slots);
Ciphertext cipher, cipherv1, res;
scheme.encrypt(cipher, mvec, slots, logp, logq);
for(long i=0; i<slots ; i++)
mvec[i] = c + mvec[i];
cout << "cipher logq before: " << cipher.logq << " logp " << cipher.logp << endl;
scheme.addConstAndEqual(cipher, c, logp);
scheme.bootstrapAndEqual(cipher, logq, logQ, logT, logI);
cout << "cipher logq after: " << cipher.logq << " logp " << cipher.logp << endl;
complex<double>* dvec = scheme.decrypt(secretKey, cipher);
StringUtils::compare(mvec, dvec, slots, "boot");
with the current logq and logp values, the program crashes with a segmentation fault during bootstrapAndEqual.
If I set logp=23 and logq=40, it works fine. Why doesn't boostrapping work with higher logq values? I've found that when I evaluate a polynomial without bootstrapping, it needs higher logq values to work.
Why does Scheme::exp2piAndEqual not use logp=cipher.logp ?
what is the value of alpha in HEAAN library??
long logq = 300; ///< Ciphertext modulus (this value s**hould be <=** logQ in "scr/Params.h")
But in scr/Params.h", static const long logQ = 800; // 128-bit security
Therefore, my question is when I need a bigger ciphertext modulus,i.e. 2000,
how to compute security level or set other parameters given security level? THX!
After I uncomment /src/HEAAN, I will make all in the /run directory. But I have some error:
Building target: HEAAN
Invoking: GCC C++ Linker
g++ -L/usr/local/lib -o "HEAAN" ./src/Ciphertext.o ./src/Context.o ./src/EvaluatorUtils.o ./src/HEAAN.o ./src/Key.o ./src/NumUtils.o ./src/Plaintext.o ./src/Ring2Utils.o ./src/Scheme.o ./src/SchemeAlgo.o ./src/SecretKey.o ./src/SerializationUtils.o ./src/StringUtils.o ./src/TestScheme.o ./src/TimeUtils.o -lntl -lgmp
./src/TestScheme.o:in function ‘NTL::BasicThreadPool* NTL::MakeRaw<NTL::BasicThreadPool, long&>(long&)’中:
TestScheme.cpp:(.text.ZN3NTL7MakeRawINS_15BasicThreadPoolEJRlEEEPT_DpOT0[ZN3NTL7MakeRawINS_15BasicThreadPoolEJRlEEEPT_DpOT0]+0x270):对‘pthread_create’ Undefined reference
/usr/local/lib/libntl.a(RR.o):in function ‘NTL::RR* NTL::details_pthread::key_wrapper::setNTL::RR(NTL::RR*)’中:
/data/xxx/ntl-11.1.0/src/../include/NTL/tools.h:665:对‘pthread_setspecific’Undefined reference
/usr/local/lib/libntl.a(RR.o):in function ‘NTL::details_pthread::key_wrapper::key_wrapper(void ()(void))’中:
/data/xxx/ntl-11.1.0/src/../include/NTL/tools.h:657:对‘pthread_key_create’Undefined reference
/usr/local/lib/libntl.a(RR.o):in function ‘NTL::RR* NTL::details_pthread::key_wrapper::setNTL::RR(NTL::RR*)’中:
/data/xxx/ntl-11.1.0/src/../include/NTL/tools.h:665:对‘pthread_setspecific’Undefined reference
/usr/local/lib/libntl.a(RR.o):in function ‘NTL::details_pthread::key_wrapper::key_wrapper(void ()(void))’中:
/data/xxx/ntl-11.1.0/src/../include/NTL/tools.h:657:对‘pthread_key_create’Undefined reference
/usr/local/lib/libntl.a(RR.o):in function ‘NTL::RR* NTL::details_pthread::key_wrapper::setNTL::RR(NTL::RR*)’中:
...
collect2: error: ld returned 1 exit status
makefile:45: recipe for target 'HEAAN' failed
make: *** [HEAAN] Error 1
What should I do to solve the error? Please help me, Thank you!
Is the bit length of the ciphertext? If you increase the slots, does it mean that you can perform more homomorphic operations?THX for your reply!
For the purposes of the FreeBSD port I had to add this instead:
do-install:
${MKDIR} ${STAGEDIR}${PREFIX}/include/${PORTNAME}
cd ${WRKSRC}/../src && ${COPYTREE_SHARE} \*.h ${STAGEDIR}${PREFIX}/include/${PORTNAME}
${INSTALL_LIB} ${WRKSRC}/libHEAAN.so ${STAGEDIR}${PREFIX}/lib
But the project is expected to install itself.
I understand that a vector of double is converted to a real polynomial via iFFT.
R^(N/2) --> R[X]/(X^N + 1)
My question is that, how to perform batch multiplication ?
I know there are API to do that in the ciphertext domain, but I want to know how it
work in the plaintext domain. Here is some code of my concerns.
std::vector<double> vec_a(slots);
std::vector<double> vec_b(slots);
NTL::ZZX poly_A = context.encode(vec_a);
NTL::ZZX poly_B = context.encode(vec_a);
NTL::ZZX poly_C = poly_A * poly_B; // should it take the polynomial mod X^N + 1 here ?
auto vec_c = context.decode(poly_C); // should vec_c[i] = vec_a[i] * vec_b[i] ?
Hello.
I want to get the square root of the ciphertext.
How can I get the square root?
ex) 2.0 -> Convert to ciphertext 'C1' -> Outputs the cryptogram of the square root of 'C1' in the encrypted state
/tmp/cchIEFuo.o: In function NTL::RR::~RR()': run.cpp:(.text._ZN3NTL2RRD2Ev[_ZN3NTL2RRD5Ev]+0x4): undefined reference to
_ntl_gfree(_ntl_gbigint_body*)'
/tmp/cchIEFuo.o: In function _GLOBAL__sub_I_main': run.cpp:(.text.startup+0x171): undefined reference to
NTL::ComputePi(NTL::RR&)'
run.cpp:(.text.startup+0x197): undefined reference to _ntl_gfree(_ntl_gbigint_body*)' run.cpp:(.text.startup+0x1d2): undefined reference to
_ntl_gfree(_ntl_gbigint_body*)'
collect2: error: ld returned 1 exit status
makefile:8: recipe for target 'HEAAN' failed
make: *** [HEAAN] Error 1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.