An open API service indexing awesome lists of open source software.

https://github.com/harbingeroffire/python-lwe-pqc

Latice based encryption using the LWE method, made in python
https://github.com/harbingeroffire/python-lwe-pqc

Last synced: 20 days ago
JSON representation

Latice based encryption using the LWE method, made in python

Awesome Lists containing this project

README

        

# Python-LWE
Latice based encryption using the LWE method, made in python

## Objective
Create a modulized example of the Learning With Errors encryption method. This method uses the idea of the complexity of polynomials with induced errors.

## Procedure
The first steps of this method is to identify the constants q and n. For first attempts at this project, I tried to define them dynamically but this effected decryption in adverse ways. As a result, I statically defined them as follows:

q=216 (modulus operator)

n=210 (width of array A)

### Key Generation
LWE is a asymmetric key encryption with public and private keys generated during encryption. To make these keys, 3 polynomiasl are used: A, s, and e.

-A is a polynomial defined to have coefficients in the range [0, q) and n terms
-s is a polynomial defined to have coefficients in the range [0, q) and n terms This is the private key (aka secret polynomial).

-e is a polynomial defined to have coefficients in the set {0,1} and n terms. This is the error polynomial, used to increase difficulty of reversing the primary key.

These polynomials are combined in a fashion to create a polynomial b so that b=(A\*s+e)%q. The public key is (A,b)

To store the keys I used a method to convert the keys to strings, compressed them, and then encoded them, which made it easier to store in a text file.

### Encryption
To encrypt a buffer (B) we create two polynomials c1 and c2. These polynomials rely on a polynomial, r, defined to have coefficients in the set {0,1} and n terms. Note that B must beconverted to a binary list before going through this cipher.

C1=(A\*>r)%q

C2=(b\*r+(q//2)*B)%q

The cipher text is the pair (C1, C2). To store this, I converted it to string, compressed it, and encoded it.

### Decryption
Given the encoded ciphertext, I converted back into it's polynomial version, and then had to run the following algorithms on it:

v=(C1\*s)%q

d=(C2-v)%q

The value d is the original list of bits, but is slightly off (by up to q) due to the errors introduced during encryption. To determine the value, we round the each bit as follows:
```python
if abs(d-0) < abs(d-(q/2)):
d=0
else:
d=1
```
## POINTS OF INTEREST
Private keys and Public keys have their own classes that allow them to be saved. I used `tuple` as a superclass instead with the second value of the tuple being `None` for the private key bue to errors in an earlier version of this code.

I considered using `zlib` instead of `gzip` to compress, but there was no visible increase in compression.

## SOURCE OF DESCRIPTION:
https://en.wikipedia.org/wiki/Lattice-based_cryptography

https://en.wikipedia.org/wiki/Learning_with_errors