intel / pailliercryptolib_python

Intel Paillier Cryptosystem Library is an open-source library which provides accelerated performance of a partial homomorphic encryption (HE), named Paillier cryptosystem, by utilizing Intel® IPP-Crypto technologies on Intel CPUs supporting the AVX512IFMA instructions. The library is written in modern standard C++ and provides the essential API for the Paillier cryptosystem scheme. Intel Paillier Cryptosystem Library - Python is a Python extension package intended for Python based privacy preserving machine learning solutions which utilizes the partial HE scheme for increased data and model protection.
Apache License 2.0
55 stars 12 forks source link

Why overflow happens? how to avoid? #38

Closed huangfuhuijie closed 1 year ago

huangfuhuijie commented 1 year ago

I tried to make some complicated calculations using this tool. But I got overflow in the end.

File "/media/huangfu/file/study/pailliercryptolib_python/src/ipcl_python/bindings/fixedpoint.py", line 116, in decode
    raise OverflowError(f'Overflow detected in decode number, encoding: {self.encoding}'
OverflowError: Overflow detected in decode number, encoding: 499292294837459474140108112497223611580686219841719423966657767 1133903371235054466471947314077246552455908109544722298091357

the hole Fixedpoint is : haha = FixedPointNumber(705361150197804755266289057325361285250549624426136155181147,767,1118730334634704471636946556425407013478208269605842668197023,372910111544901490545648852141802337826069423201947556065673)

all calculations are after encrypted, I have no idea about how to solve it. And i don't know is it my fault or the tool's fault. QQ图片20230522133049

do you have any ideas about this? thank you very much.

By the way, as you can see in this picture, there is a missing space between self.encoding and self.exponent(int fixedpoint.py, line 117), so this two number connected in output, which is quite confusing in the start.

fangxiaoran commented 1 year ago

Hi @huangfuhuijie, thanks for your question.

The overflow happens since neither self.encoding <= self.max_int nor self.encoding >= self.n - self.max_int satisfies. In other words, the encoded number exceeds the range [-max_int, max_int].

FixedPointNumber is used to convert floating-point number to fixed-point number during Paillier encryption. Usually we don't use its constructor function directly, but ipcl.pubkey.encrypt() or FixedPointNumber.encode().

You can try haha = FixedPointNumber.encode(705361150197804755266289057325361285250549624426136155181147,1118730334634704471636946556425407013478208269605842668197023,372910111544901490545648852141802337826069423201947556065673,max_exponent=767) to get a clearer error message.

For your second issue. I believe it's a typo and I'll update it in the next commit. Thank you for pointing it out.

huangfuhuijie commented 1 year ago

@fangxiaoran , thanks for your explain. However, I didn't use FixedPointNumber constructor function directly, this error occurs when i finish my encrypted calculation and tried to decrypt. Meaning I have done all the calculations and there is no overflow in the calculations.

fangxiaoran commented 1 year ago

If so, can you let me know how to reproduce this error?

huangfuhuijie commented 1 year ago

sure, here is my python code

def err():
    pk, sk = PaillierKeypair.generate_keypair(200)
    # Acquire QAT engine control
    context.initializeContext("QAT")

    a = np.random.random()
    ct_a = pk.encrypt(a)
    for i in range(10000):
        r = np.random.random()
        ct_a = ct_a * r
        sk.decrypt(ct_a)

    context.terminateContext()

thx very much

fangxiaoran commented 1 year ago

OK, I got the overflow error too. Below is the reason.

In your code, ct_a = ct_a * r is in a for-loop. So, the ciphertext continues to increase, which leads to an overflow when the FixedPointNumber of ct_a exceeds the limitation (pk.max_int).

Not sure why you do so many multiplications on a ciphertext. It's rare as I know. Maybe you can put ct_a * r outside the loop.

Btw, I see you set the key length to 200. In practical cases, 2048 is more recommended.

huangfuhuijie commented 1 year ago

@fangxiaoran Thanks for your explain, But I truly have to make a lot of multiplications. And as I know, image there is a mod n^2 after multiplications, why this operation doesn't stop overflow? Is there anything wrong in my opinion? I tried to set the key length to 2048, it did release the overflow problem a little. But is there any way to avoid overflow to make free calculation? looking forward to your reply

fangxiaoran commented 1 year ago

When converting float-point number to fixed-point number, we multiply it by a scaling factor, then encrypt. The ciphertext increases is because of it will be multiplied by the scaling factor each time ct_a * r.

Actually, when performing ct_a * r, we are not using the property you mentioned, but the equation below. image

In addition, 2048 is recommended for security, not for solving this issue.

huangfuhuijie commented 1 year ago

I see, I will use 2048. Thank you for your contribution to making such a great tool and patience to answer my queations.