11.1. Paillier Encryption#
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from aijack.defense.paillier import (
PaillierKeyGenerator,
PaillierTensor,
)
/usr/local/lib/python3.10/dist-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
/usr/local/lib/python3.10/dist-packages/torchvision/io/image.py:13: UserWarning: Failed to load image Python extension: '/usr/local/lib/python3.10/dist-packages/torchvision/image.so: undefined symbol: _ZN3c104cuda20CUDACachingAllocator9allocatorE'If you don't plan on using image functionality from `torchvision.io`, you can ignore this warning. Otherwise, there might be something wrong with your environment. Did you have `libjpeg` or `libpng` installed before building `torchvision` from source?
warn(
keygenerator = PaillierKeyGenerator(512)
pk, sk = keygenerator.generate_keypair()
11.1.1. Basics#
ct_1 = pk.encrypt(13)
assert sk.decrypt2int(ct_1) == 13
ct_2 = ct_1 * 2
assert sk.decrypt2int(ct_2) == 26
ct_3 = ct_1 + 5.6
np.testing.assert_array_almost_equal(sk.decrypt2float(ct_3), 18.6, decimal=6)
ct_4 = ct_1 + ct_3
np.testing.assert_array_almost_equal(sk.decrypt2float(ct_4), 31.6, decimal=6)
11.1.2. PyTorch - Tensor#
ct_1 = pk.encrypt(13)
ct_2 = pk.encrypt(0.5)
ct_3 = ct_1 + ct_2
pt_1 = PaillierTensor([ct_1, ct_2, ct_3])
torch.testing.assert_close(
pt_1.decrypt(sk), torch.Tensor([13, 0.5, 13.5]), atol=1e-5, rtol=1
)
pt_2 = pt_1 + torch.Tensor([0.4, 0.1, 0.2])
torch.testing.assert_close(
pt_2.decrypt(sk), torch.Tensor([13.4, 0.6, 13.7]), atol=1e-5, rtol=1
)
pt_3 = pt_1 * torch.Tensor([1, 2.5, 0.5])
torch.testing.assert_close(
pt_3.decrypt(sk), torch.Tensor([13, 1.25, 6.75]), atol=1e-5, rtol=1
)
pt_4 = pt_1 - torch.Tensor([0.7, 0.3, 0.6])
torch.testing.assert_close(
pt_4.decrypt(sk), torch.Tensor([14.3, 0.2, 12.9]), atol=1e-5, rtol=1
)
pt_5 = pt_1 * 2
torch.testing.assert_close(
pt_5.decrypt(sk), torch.Tensor([26, 1, 27]), atol=1e-5, rtol=1
)
11.1.3. PyTorch - NN#
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(10, 5)
self.fc2 = nn.Linear(5, 2)
def forward(self, x):
x = self.fc1(x)
x = self.fc2(x)
return x
model = Net()
data = list(range(10))
tensor = torch.Tensor([data])
encrypted_data = [pk.encrypt(d) for d in data]
encrypted_tensor = PaillierTensor([encrypted_data])
model(tensor)
tensor([[ 1.8293, -2.0024]], grad_fn=<AddmmBackward0>)
model(encrypted_tensor).decrypt(sk)
tensor([[ 1.8293, -2.0024]])