Loading [MathJax]/extensions/TeX/AMSsymbols.js

jueves, 30 de agosto de 2012

Tarea2:

 La tarea 2 es checar si las claves que genera nuestro otp (one time pad) realmente es aleatoria.

 La clave evaluada fue la siguiente:


Esta clave es generada del programa anterior con el siguiente código:

def generar_claves():
k=''
for m in range(10):
s = binary(randint(0,255))
k += s
return k
view raw g.py hosted with ❤ by GitHub
Funciona leyendo las claves del archivo llamado key.txt pasandoselo a cada uno de los test.


def leer_archivo(archivo,test):
archivo = open(archivo, 'r')
numero=''
for i in archivo.readline().strip():
numero+=i
# print numero
#print (len(numero))
if test==3:
print numero
return numero
else:
numero = map(int,numero)
numero = array(numero)
return numero
view raw leer.py hosted with ❤ by GitHub

Primero yo realice un test sencillo que se llama Monobit:

Monobit

Detecta los ceros y los unos que se encuentran en la cadena binaria, sustituyendo los ceros que encuentre por -1, asi realizando una suma. La aparición de ceros y unos en la secuencia global deberan de ser igualmente probables

Datos a tener:

n = tamaño de la clave binaria
ε =La secuencia de bits que se esta probando

Procedimiento:

1. Como mencione se buscan los ceros y se sustituyen por -1y se realiza una suma, ejemplo:
   lista=[1,1,0,0,1,0,1]
   quedaría:
   lista=[11,-1-1,1-11]
 y se realiza la suma de la lista

2-Se calcula la prueba estadística:





3. Se calcula p_value ( erfc es la función error complementaria.)


4.Si P - value > 0.01, la secuencia  es aleatoria.

Código:
def monobit(lista):
print 'Test Monobit'
n=len(lista)#tam de lalista
for m in range(n):# recorre la lista
if lista[m]==0:
lista[m]= -1 # Si encuentra un 0 en la lista lo hace -1
sn=sum(lista) # realiza la suma
s_obs=abs(sn)/math.sqrt(n) #calcula prueba estadistica
p_value= math.erfc(s_obs/math.sqrt(2)) #calcula p_value
if p_value > 0.01:
print ">> Frequency Test: PASSED -->", p_value
else:
print ">> Frequency Test: NOT PASSED --> ", p_value
view raw monobit.py hosted with ❤ by GitHub

Captura de pantalla de la prueba:



También utilice otras dos pruebas que es la de Poker y la de frecuencia de Bloques

Frecuencia de Bloques

En la prueba de bloques los ceros y unos deberan de ser igualmente probables.
 Datos:

n - largo de la secuencia
m - el largo de cada bloque
ε - secuencia de bits generada

Recomendaciones:










Procedimiento:

1. Se parte la prueba e bloques de un cierto tamaño se calcula de la siguiente manera:
  

2. Se determina la proporción de unos:


3. Se calcula la chi2=X2


4.  Se calcula la p_value:






Código
def frequency_block(list):
print 'Test Block'
n = len(list)
M = 0.01*n
N =int( n/M)
blocks = []
X2 = 0
print type(blocks)
i=0
while(len(blocks) != N):
blocks.append(list[i:(i+M)])
i = i + M
sumas = []
for i in range(len(blocks)):
sumas.append(0)
for j in range(len(blocks[i])):
sumas[i] = sumas[i] + blocks[i][j]/float(M)
for i in range(N):
X2 = X2 + math.pow((sumas[i] - .5), 2)
X2 = X2 * 4*M
df = M - 1
p_value = chi2.cdf(X2, df)
if p_value < 0.01:
print "Frequency Test with Blocks: NOT PASSED"
else:
print "Frequency Test with Blocks: PASSED"
view raw bloques.py hosted with ❤ by GitHub

Captura de pantalla



Prueba de Póker

Lo que hace la prueba de póker es dividir la clave en numeros de 4 bist, por ejemplo si yo tengo esta:

0101000001100011

se divide de la siguiente manera :
0101 0000 0110 0011

entonces como se divide en 4 hay 16 posibles resulados que pueden salir y esos 16 resultados son contados las veces que estan o el número de frecuencias de cada uno.

La formula que se realiza es la siuiente:

en donde:
m = es el tamaño de la división de la secuencia en este caso 4
n = lóngitud o tamaño de la secuencia binaria
k = es la división de m entre n

Pasos:

1. Se divide la serie de número binarios en secciones de 4 numeros (0000).
2. Se buscan las frecuencias de los 16 diferentes numeros que se pueden encontrar
3. La frecuencia se eleva al cuadrado
4. Se realiza lo que es la ecuación anterior:

         x2=(16/k)(frecuencias al cuadrado)-k

La prueba se pasa cuando 1.03 < x < 57.4

def poker(arch):
n=len(arch) # Tam de la cadena binaria
m=4 #longitud de los bloques
numeros=list()#lista de separaciones de numeros de 4
frecuencia=list() #lista para guardar las frecuencias
y = n/m #cantidad de grupo de 4
for i in range(y): # recorre la cantidad de grupos de 4
numeros.append(arch[4*i:4+(4*i)]) #los agrega a la lista numeros
for i in range(16): #realiza la lista de los 16 posibles numeros
z=bin(i)[2:].zfill(4)
frecuencia.append((numeros.count(z))**2) #cuenta las frecuencias de los numeros
print frecuencia
x = 0
a= 16.0/y
x = (a)*(sum(frecuencia)-y) #realiza la operacion
print 'x---->', x
if 1.03 < x < 57.4:
print 'Poker Test: PASSED'
else:
print 'Poker Test: NOT PASSED'
view raw poker.py hosted with ❤ by GitHub
Captura de pantalla


Con otra cantidad de claves:

Monobit



Frecuencia de Bloques



Poker test




La clave pasa las pruebas eso quiere decir que es segura.

Referencias:

Link1
Link2
LInk3

No hay comentarios:

Publicar un comentario