In the encryption process, the ciphertexts c1 and c2 are added to errors e1 and e2 each to get noisy ciphertexts u and v.
c1 = A * r
c2 = b * r + m * (q/2)
u = c1 + e1
v = c2 + e1
However, choosing a random value for e1 and e2 would cause u and v to not match to its message m. Wikipedia and several research papers suggest using discrete Gaussian distribution to choose e1 and e2 that match with m. The error e requires the noise distribution χ is such that ||e|| ≤ q/4 with high probability, for e ← χ. We can choose χ to be a discrete Gaussian distribution that satisfies this constraint. However, I am not sure how to go about that.
These are my Python functions for encryption and for picking e1 and e2, which are incorrect because they did not produce the correct binary values upon decryption.
def encrypt(binaryMessage):
m = ''
u_list =[]
v_list = []
s, q, A, b = getKeyValues()
binary_list = [int(bit) for bit in binaryMessage]
print("no. of bits")
print(len(binary_list))
i= 0
for m_bit in binary_list:
r = np.array([0, 0, 1, 0, 0, 0, 1])
c1 = np.dot(A.T, r)
c2 = round((np.dot(b, r.T) + np.dot(m_bit, q/2)))
u = pickE1(c1) % q
v = pickE2(c2) % q
m_bit = computeM(u, c2, q, s)
m += m_bit
print(m)