Monday, 8 November 2021

Orthogonal Matrix Encryption Scheme in Python

I am trying to implement an encryption scheme described here which uses orthogonal matrices and the exponential function to both encrypt and decrypt a text. A short summary would say:

  1. Change plaintext to some ciphertext by taking a character to a number
  2. Construct a diagonal matrix A with e^{ciphertext #} as entries, then using some orthogonal matrix C, and a vector filled with just the ciphertext numbers, perform the operation: C.T @ A @ C @ vect = encrypt
  3. Take the resulting encrypt vector and using a slightly modified C (I have no clue how they determine this modified C) set decrypt = C @ encrypt
  4. From here, you will have a vector with multiple exponentials in each row, I need to somehow parse the power of the desired exponential and store it in an array that I can then convert. Note that this is the reason for using sympy so that my expressions do not evaluate

In order to fully understand the paper, I am recreating their results exactly and then changing from there. My main problem is bullet 4, I just have no idea how I can read the desired exponential to store in an array. I am also having trouble understanding their construction of C and how they arrive at the modified C in the decryption process. In my code snippet attached, C_1 is the decrpytion C and C_2 is the encryption C.

C_1=Matrix([[1,-1,0,0],[1,1,0,0],[0,0,1,-1],[0,0,1,1]])
C_2=C_1*(1/sqrt(2))
for i in range(0, len(encodedtext_pad), 4): # Step sizes of 4
  a=diag(sy.exp(encodedtext_pad[i]), #construct diagonal matrix with exponential raised to cipher text on diagonal
         sy.exp(encodedtext_pad[i+1]),
         sy.exp(encodedtext_pad[i+2]),
         sy.exp(encodedtext_pad[i+3]))
  vect=Matrix([[encodedtext_pad[i]],[encodedtext_pad[i+1]],[encodedtext_pad[i+2]],[encodedtext_pad[i+3]]]) #construct vector of cipher text
  encrypt=C_2.T**(j) @ a @ C_2**(j) @ vect # create encrypted vector 
  decrypt=C_1**j @ encrypt #decrypt encrypted vector, I have no idea where the C comes from, it does not follow from the original
  print("\n decrypt=")
  j=j+1

Encoder:

textfromfile="CRYPTOGRAPHY1"
encodedtext=[]
encoder= {
  ' ': '53', '0': '54', '1': '55','2':'56', '3' :'57', '4':'58','5':'59',

  'a': '27', 'b': '28', 'c': '29', 'd': '30', 'e': '31', 'f': '32',
    'g': '33', 'h': '34', 'i': '35', 'j': '36', 'k': '37', 'l': '38',
    'm': '39', 'n': '40', 'o': '41', 'p': '42', 'q': '43', 'r': '44',
    's': '45', 't': '46', 'u': '47', 'v': '48', 'w': '49', 'x': '50',
    'y': '51', 'z': '52','A': '1', 'B': '2', 'C': '3', 'D': '4', 'E': '5', 'F': '6',
    'G': '7', 'H': '8', 'I': '9', 'J': '10', 'K': '11', 'L': '12',
    'M': '13', 'N': '14', 'O': '15', 'P': '16', 'Q': '17', 'R': '18',
    'S': '19', 'T': '20', 'U': '21', 'V': '22', 'W': '23', 'X': '24',
    'Y': '25', 'Z': '26',
}
for i in range(0, len(textfromfile)):
        encodedtext.append(encoder[textfromfile[i]])
encodedtext_pad=np.pad(encodedtext, (0, 4-len(encodedtext)%4), 'constant')
encodedtext_pad = [int(i) for i in encodedtext_pad] # Pad the text with 0's so it is evenly divisible by 4.

I have tried constructing my own C by taking an upper triangular matrix with desired eigenvalues on the diagonals and 1's above, diagonalizing, taking the resulting eigenvector matrix and performing QR factorization to obtain an orthonormal eigenvector matrix. It has not yielded any significant results.

**Full disclosure - I am a student and likely have muddied up notation, best practices, explanation, and more. I warmly welcome feedback. **



from Orthogonal Matrix Encryption Scheme in Python

No comments:

Post a Comment