Dentre os sistemas criptográficos assimétricos ou de chave pública práticos, eficientes e seguros temos: DSA, RSA, baseados em curvas Elípticas, entre outros. A segurança desses sistemas está ameaçada devido ao advento da computação quântica e do algoritmo quântico desenvolvido por Peter Shor em 1994, que resolve o problema da fatoração de números inteiros em tempo polinomial.
Em 1978 Robert McEliece propôs um sistema criptográfico aleatório que, na época, não foi posto em prática devido ao fato do tamanho de suas chaves serem consideravelmente grandes. Atualmente esse sistema tem tido muita aceitação por parte da comunidade de pesquisadores em criptografia devido à sua resistência aos ataques provenientes dos algoritmos quânticos, como o algoritmo o de Shor. Outra vantagem deste sistema criptográfico é o fato de que seus algoritmos de cifração e decifração são mais rápidos, no que se refere à complexidade de tempo, em comparação com o sistema consolidado RSA.
Este post está focado na implementação do algoritmo de decodificação para códigos de Goppa [1]. Para isto, apresentarei, embaixo, esta implementação feita no CAS SAGE. Note que o código escrito ali pode ser "rodado" fazendo click no botão Evaluate.
Implementação do Algoritmo do Patterson
xxxxxxxxxx
#Algoritmos Auxiliares
def split(p):
# split polynomial p over F into even part po
# and odd part p1 such that p(z) = p2 (z) + z p2 (z)
Phi1 = p.parent()
p0 = Phi1([sqrt(c) for c in p.list()[0::2]])
p1 = Phi1([sqrt(c) for c in p.list()[1::2]])
return (p0,p1)
def xgcdm1(self, other):
delta = self.degree()
if other.is_zero():
R = self.parent()
return self, R.one_element(), R.zero_element()
# Algorithm 3.2.2 of Cohen, GTM 138
R = self.parent()
A = self
B = other
U = R.one_element()
G = A
V1 = R.zero_element()
V3 = B
while true:
Q,R = G.quo_rem(V3)
T = U - V1*Q
U = V1
G = V3
V1 = T
V3 = R
if V3.degree() <= floor((delta-1)/2) and G.degree() <= floor((delta)/2):
#if V3.degree() < floor((delta-1)/2):# or Q.degree() < floor((delta-1)/2):#(delta-2)/2)):# or V3 == 0:
break
V = (G-A*U)//B
lc = G.leading_coefficient()
return G/lc, U/lc, V/lc
def g_inverse(p,g):
(d,u,v) = xgcd(p,g)
return u.mod(g)
#Implementação do algoritmo de Patterson
def decodePatterson(y):
s2 = H*y
s2 = vector(s2)
print 's2',s2
X1 = X;
g1 = g
polSyn1 = PR(0);
for i in range(len(s2)):
polSyn1 = polSyn1 + s2[i]*(X1^(len(s2)-i-1))
g0g1 = split(g1);
w = ((g0g1[0])*g_inverse(g0g1[1],g1)).mod(g1)
T0T1 = split(g_inverse(polSyn1,g1) + X1)
R = (T0T1[0]+(w)*(T0T1[1])).mod(g1)
(a11,b11,c11) = xgcdm1(g1,R);
sigma = a11^2+X1*(c11^2)
for i in range(N):
if (sigma(a^i)==0): # an error occured
print 'error position',i
m = 4; K = GF(2); F.<a> = GF(2^m); delta = 3
PR = PolynomialRing(F,'X')
X = PR.gen()
N = 15
L = [a^i for i in range(N)]
g = X^3 + X + 1
print 'polinômio de Goppa'
print g
T = matrix(F,delta,delta)
for i in range(delta):
count = delta - i + 1 - 1
for j in range(delta):
if i > j:
T[i,j]=g.list()[count]
count = count + 1
if i < j:
T[i,j] = 0
if i == j:
T[i,j] = 1
V = matrix([[L[j]^i for j in range(N)] for i in range(delta)])
D = diagonal_matrix([1/g(L[i]) for i in range(N)])
H = T*V*D
#print H #descomentar para olhar a matrix de teste de paridade em GF(2^m)
H_Goppa_K = matrix(K, m*H.nrows(), H.ncols())
for i in range (H.nrows()):
for j in range(H.ncols()):
be = bin(eval(H[i,j].int_repr()))[2:]
be = '0'*(m-len(be))+be; be = list(be)
H_Goppa_K[m*i:m*(i+1),j]=vector(map(int,be))
print 'matrix de teste de paridade'
print H_Goppa_K
krnl = H_Goppa_K.right_kernel();
G_Goppa = krnl.basis_matrix();
print 'matrix geradora'
print G_Goppa #descomentar para olhar a matrix geradora
#Caso de prova
u = vector(K,[randint(0,1) for _ in range(G_Goppa.nrows())])
print 'vetor a codificar'
print u
c = u*G_Goppa
print 'vetor codificado'
print c
e = vector(K,N)
#Suponhamos que ao vetor c é adicionado erros nas posições 2 e 3
e[2] = 1
e[3] = 1
print 'vetor erro'
print e
y = c + e
print 'vetor c com erro'
print y
print 'decodificando'
decodePatterson(y)