#inctf2021
global allowed , matrix_entries
allowed = "%UQh13S2dbjj,V6K1g$PTdaN4f!T023KUe#hi0PMOQiVN&cOcLR74+MLfeSgbaR*"
matrix_entries = 37*37
class Cipher :
def __init__(self, master_pass) :
self.n = len(master_pass)
self.key = [ord(i) for i in master_pass]
self.mod = len(allowed)
def create_key(self) :
S= []
for i in range(self.mod) :
S.append(i)
j = 0
i = 0
for i in range(self.mod - 1) :
i = (i + 1) % self.mod
j = (j + S[i] + self.key[i%self.n]) %self.mod
S[i], S[j] = S[j], S[i]
return S
def gen_stream(self , S , lgth = matrix_entries) :
i = j = 0
global key_stream
key_stream = []
for k in range(0, lgth):
i = (i + 1) % self.mod
j = (j + S[i]) % self.mod
t = (S[i]+S[j]) % self.mod
key_stream.append(S[t])
return key_stream
def get_entries(master_pass , lgth = matrix_entries) :
obj = Cipher(master_pass)
l = list(map(lambda x: allowed[x],obj.gen_stream(obj.create_key(),lgth)))
return l
if __name__ == "__main__" :
import random
master_pass_len = 2**(random.choice(range(1,7)))
master_pass = ''.join(chr(random.randint(0,64)) for i in range(master_pass_len))
f = open("master_pass.key","w")
f.write(master_pass)
f.close()
from crypto import get_entries
import math, string
from sage.all import EllipticCurve, Integer
from matrix import *
class Tabula:
def __init__(self) :
self.E = EllipticCurve(GF(37),[1,5])
self.G = self.E.gen(0)
global d,allowed
allowed = "abcdefghijKLMNOPQRSTUV0123467!#$%&*+,"
d = {}
for i in range(37) :
d[allowed[i]] = self.E.points()[i+1]
self.A = [[-1,5,-1],[-2,11,7],[1,-5,2]]
self.rows = 37
self.table = [[' ']*self.rows for i in range(self.rows)]
def update_table(self, rows , table_entries) :
self.rows = rows
for i in range(rows) :
for j in range(rows) :
self.table[i][j] = table_entries[i*rows + j]
def map_matrix(self, m) :
inf = self.E.points()[0]
row = 3
col = math.ceil(len(m)/3)
E_arr = []
ind = 0
for i in range(row) :
tmp = []
for j in range(math.ceil(len(m)/3)) :
if ( ind < len(m)) :
tmp.append( d[m[ind]] )
else :
tmp.append(inf)
ind += 1
E_arr.append(tmp)
return Matrix((row,col),E_arr)
def encrypt(self,m) :
mat = [[-1,5,-1],[-2,11,7],[1,-5,2]]
A = Matrix((3,3), mat)
P = self.map_matrix(m)
Q = A.__mul__(P)
(C1,C2) = (P.__mul__(25), Q.__add__(P.__mul__(325)))
points = []
for i in range(P.rows) :
for j in range(P.cols) :
c1 = C1.M[i][j]
c2 = C2.M[i][j]
points.append(((c1[0],c1[1]),(c2[0],c2[1])))
if((i*P.rows + j) == len(m)) :
break
return points
def gen_pass(self, website, master_pass , pass_len) :
"""
website : name of the website you want to generate the password for eg: www.amazon.com
master_pass : master password for your stateless password manager
pass_len : length of the password to be generated/retrieved for the website
"""
site = website.split(".")[1]
entries = get_entries(master_pass)
self.update_table( 37, entries)
table_row = sum([ord(i) for i in site])%self.rows
pswd = ''.join([self.table[table_row][i] for i in range(pass_len)])
points = self.encrypt(pswd)
pswd_set = [(self.table[points[i][0][0]][points[i][1][1]],(points[i][0],points[i][1])) for i in range(pass_len)]
pswd = ''.join(p[0] for p in pswd_set)
return pswd
if __name__ == "__main__" :
obj = Tabula()
class Matrix:
def __init__(self,dims , A=None) :
self.rows = dims[0]
self.cols = dims[1]
if(A == None) :
self.M = [[0] * self.cols for i in range(self.rows)]
else :
self.M = A
def __str__(self) :
m = ""
for i in range(self.rows) :
m += str(self.M[i])+"\n"
return m
def __add__(self,other) :
C = Matrix(dims = (self.rows,self.cols))
if isinstance(other,Matrix) :
for i in range(self.rows) :
for j in range(self.cols) :
C.M[i][j] = self.M[i][j] + other.M[i][j]
else :
print("Not matching type")
return C
def __radd__(self,other) :
return self.__add__(other)
def __mul__(self, other) :
if isinstance(other,Matrix) :
C = Matrix(dims = (self.rows,other.cols))
for i in range(self.rows) :
for j in range(other.cols) :
acc = 0
for k in range(other.rows) :
acc += self.M[i][k] * other.M[k][j]
C.M[i][j] = acc
else :
C = Matrix(dims = (self.rows,self.cols))
for i in range(self.rows) :
for j in range(self.cols) :
C.M[i][j] = self.M[i][j] * other
return C
def __rmul__(self,other) :
return self.__mul__(other)
def __getitem__(self,key) :
if isinstance(key, tuple) :
i = key[0]
j = key[1]
return self.M[i][j]
def __setitem__(self,key,value) :
if isinstance(key,tuple) :
i = key[0]
j = key[1]
self.M[i][j] = value
def __sub__(self,other) :
C = Matrix(dims = (self.rows,self.cols))
if isinstance(other,Matrix) :
for i in range(self.rows) :
for j in range(self.cols) :
C.M[i][j] = self.M[i][j] - other.M[i][j]
else :
print("Not matching type")
return C
def __rsub__(self,other) :
return self.__sub__(other)
if __name__ == "__main__" :
X = [[1,2,3],[4,5,6],[7,8,9]]
Y = [[10,11,12],[13,14,15],[16,17,18]]
R = [[84,90,96],[201,216,231],[318,342,366]]
X = Matrix((3,3),X)
Y = Matrix((3,3),Y)
Res = X.__mul__(Y).M
assert Res == R
print("Script successful")