¡Advertencia!
Este tema no ha tenido respuestas en más de un mes. Recuerda que si deseas añadir una nueva debes cumplir con las normas de la web.
Aporto un pequeño programa que hice para una práctica pasada y que puede servirle a cualquiera que esté interesado en ponerlo en práctica, o para ver cómo funciona un poco el lenguaje ensamblador con las instrucciones más básicas que hay (almacenar palabra, leer palabra, mover a registro, salto, operaciones aritmeticológicas, desplazamientos, etc).
Consiste en encriptar una cadena de texto por la rutina de cifrado TEA (Tiny Encryption Algorithm), y tiene miles de aplicaciones (si bien hoy en día existen algoritmos de encriptación más eficientes aparte de los sucesores de este mismo, como XTEA o XXTEA). En este programa simplemente se le pide al usuario si quiere cifrar o descifrar un texto, o definir previamente una clave de cifrado a través del cual realizar la encriptación.
Para realizar este código en ensamblador, antes me he basado en el siguiente escrito en C++, y a partir de ahí implementar cada uno de los algoritmos:
Y el resultado final del código en ensamblador MIPS de 32 bits, quedará así (aunque he de reconocer que tiene algún pequeño bug trivial por ahí, a la hora de introducir datos que no se corresponden con el tipo que se pide). Las líneas de comentario van precedidas de '#' y las etiquetas con el sufijo ':' en el lenguaje ensamblador:
Ejemplo de salida:
Si alguien tiene interés en probarlo, puede hacerlo desde el programa Mars del que no se necesita instalar nada y funciona en Java (cosa que me gusta porque así funciona en múltiples plataformas).
El código ASM que he pegado en la entrada contendrá algunos chufanos si se visualiza desde Windows (el programa lo hice desde Ubuntu y desde ahí se verá bien al utilizarse otra codificación de texto). Se puede trabajar de todas formas con él sin problemas desde cualquier plataforma (desde Mac no lo he probado, pero lo más seguro es que también).
Consiste en encriptar una cadena de texto por la rutina de cifrado TEA (Tiny Encryption Algorithm), y tiene miles de aplicaciones (si bien hoy en día existen algoritmos de encriptación más eficientes aparte de los sucesores de este mismo, como XTEA o XXTEA). En este programa simplemente se le pide al usuario si quiere cifrar o descifrar un texto, o definir previamente una clave de cifrado a través del cual realizar la encriptación.
Para realizar este código en ensamblador, antes me he basado en el siguiente escrito en C++, y a partir de ahí implementar cada uno de los algoritmos:
#include <stdint.h>
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}Fuente: WikipediaY el resultado final del código en ensamblador MIPS de 32 bits, quedará así (aunque he de reconocer que tiene algún pequeño bug trivial por ahí, a la hora de introducir datos que no se corresponden con el tipo que se pide). Las líneas de comentario van precedidas de '#' y las etiquetas con el sufijo ':' en el lenguaje ensamblador:
#####################################################
### PROGRAMA CIFRADOR/DESCIFRADOR DE TEXTO EN TEA ###
#####################################################
# Definición de textos.
.data 0x10000000 # Se trabajará sobre esta dirección de memoria.
menu: .asciiz "
MENU PRINCIPAL
1. Cifrar un texto.
2. Descifrar un texto.
3. Modificar la clave de cifrado.
Introduzca opción (1-3): "
.align 2
error: .asciiz "HA SELECCIONADO UNA OPCIÓN INCORRECTA
"
.align 2
mtin: .asciiz "Introduce el texto: "
.align 2
clci: .asciiz "Introduce la nueva clave de cifrado: "
.align 2
clave: .asciiz "
La nueva clave de cifrado es: "
.align 2
txtin: .asciiz "
Texto introducido: "
.align 2
txtci: .asciiz "
Texto cifrado: "
.align 2
txtdc: .asciiz "
Texto descifrado: "
.align 2
# Definición de variables y constantes globales.
delta: .word 0x9e3779b9
sum: .word 0xc6ef3720
# Comienzo del programa.
.text
main: # Declaración de constantes y variables.
lw $s4, 0x10000148 # delta
li $s6, 0x0 # Iteraciones
li $s7, 0x20 # Número de tandas para la encriptación
li $v0, 4 # Imprime cadena de menú de usuario.
la $a0, menu # Carga dirección de la cadena en el registro a0 (mostrar por pantalla).
syscall ### Petición al sistema.
li $v0, 5 # Lee un entero por teclado.
syscall ### Petición al sistema.
move $t0, $v0 # Copia en el registro temporal $t0 el valor de $v0.
beq $t0, 1,opt1 # Condiciones de salto para acceder a cada opción.
beq $t0, 2,opt2
beq $t0, 3,opt3
beq $t0, 0,end
li $v0, 4 # Imprime cadena de error.
la $a0, error # Carga dirección de la cadena.
syscall ### Petición al sistema.
opt1: move $s5, $zero # Variable sum=0
li $v0, 4
la $a0, mtin # Pregunta al usuario por el texto a introducir.
syscall
li $v0, 8 # Lee un string por teclado.
li $a0, 0x10000160
li $a1, 9
syscall ### Petición al sistema.
la $t1, 0x10000160 # En t1 se almacenará la dirección de inicio de datos a cifrar.
lw $t2, 0($t1) # t2 contendrá los primeros 32 bits del registro t1
lw $t3, 4($t1) # t3 contendrá los siguientes 32 bits del registro t1
# COMIENZO CIFRADO TEA
op1a: addu $s5, $s5, $s4 # sum=sum+delta
sll $t4, $t3, 4 # z<<4
addu $t5, $t4, $s0 # (z<<4)+k[0]
addu $t6, $t3, $s5 # z+sum
srl $t7, $t3, 5 # z>>5
addu $t8, $t7, $s1 # (z>>5)+k[1]
xor $t9, $t5, $t6 # ((z<<4)+k[0]) xor (z+sum)
xor $t9, $t9, $t8 # (((z<<4)+k[0]) xor (z+sum)) xor ((z>>5)+k[1])
addu $t2, $t2, $t9 # y=y+"t9"
sll $t4, $t2, 4 # y<<4
addu $t5, $t4, $s2 # (y<<4)+k[2]
addu $t6, $t2, $s5 # y+sum
srl $t7, $t2, 5 # y>>5
addu $t8, $t7, $s3 # (y>>5)+k[3]
xor $t9, $t5, $t6 # ((y<<4)+k[2] xor (y+sum)
xor $t9, $t9, $t8 # (((y<<4)+k[2]) ^ (y+sum)) ^ ((y>>5)+k[3])
addu $t3, $t3, $t9 # z=z+"t9"
addi $s6, $s6, 1 # Suma iteración.
bne $s6, $s7, op1a
sw $t2, 0x10000180 # Copia los registros en memoria.
sw $t3, 0x10000184
li $v0, 4 # Imprime cadena de texto cifrado.
la $a0, txtci # Carga dirección de la cadena.
syscall ### Petición al sistema.
li $v0, 4 # Muestra el string codificado.
li $a0, 0x10000180
syscall ## Petición al sistema.
# Limpia el espacio de memoria utilizada.
sw $zero, 0x10000160
sw $zero, 0x10000164
sw $zero, 0x10000180
sw $zero, 0x10000184
j main # Regresa al menú.
opt2: lw $s5, 0x1000014c # Variable sum.
li $v0, 4
la $a0, mtin # Pregunta al usuario por el texto a introducir.
syscall
li $v0, 8 # Lee un string por teclado.
li $a0, 0x10000160
li $a1, 9
syscall ### Petición al sistema.
la $t1, 0x10000160 # En t1 se almacenará la dirección de inicio de datos a cifrar.
lw $t2, 0($t1) # t2 contendrá los primeros 32 bits del registro t1
lw $t3, 4($t1) # t3 contendrá los siguientes 32 bits del registro t1
# COMIENZO CIFRADO TEA
op2a: sll $t4, $t2, 4 # y<<4
addu $t5, $t4, $s2 # (y<<4)+k[2]
addu $t6, $t2, $s5 # y+sum
srl $t7, $t2, 5 # y>>5
addu $t8, $t7, $s3 # (y>>5)+k[3]
xor $t9, $t5, $t6 # ((y<<4)+k[2] xor (y+sum)
xor $t9, $t9, $t8 # (((y<<4)+k[2]) ^ (y+sum)) ^ ((y>>5)+k[3])
subu $t3, $t3, $t9 # z=z-"t9"
sll $t4, $t3, 4 # z<<4
addu $t5, $t4, $s0 # (z<<4)+k[0]
addu $t6, $t3, $s5 # z+sum
srl $t7, $t3, 5 # z>>5
addu $t8, $t7, $s1 # (z>>5)+k[1]
xor $t9, $t5, $t6 # ((z<<4)+k[0]) xor (z+sum)
xor $t9, $t9, $t8 # (((z<<4)+k[0]) xor (z+sum)) xor ((z>>5)+k[1])
subu $t2, $t2, $t9 # y=y-"t9"
subu $s5, $s5, $s4 # sum=sum-delta
addi $s6, $s6, 1 # Suma iteración.
bne $s6, $s7, op2a
sw $t2, 0x10000180 # Copia los registros en memoria.
sw $t3, 0x10000184
li $v0, 4 # Imprime cadena de texto cifrado.
la $a0, txtdc # Carga dirección de la cadena.
syscall ### Petición al sistema.
li $v0, 4 # Muestra el string codificado.
li $a0, 0x10000180
syscall
# Limpia el espacio de memoria utilizada.
sw $zero, 0x10000160
sw $zero, 0x10000164
sw $zero, 0x10000180
sw $zero, 0x10000184
j main # Regresa al menú.
opt3: li $v0, 4
la $a0, clci # Pregunta al usuario por el texto a introducir.
syscall
li $v0, 8 # Lee un string por teclado.
li $a0, 0x10000160
li $a1, 17
syscall ### Petición al sistema.
li $v0, 4
la $a0, clave
syscall
li $v0, 4 # Muestra el string introducido por pantalla.
li $a0, 0x10000160
syscall
# Almacenamos cada palabra en registros fijos.
lw $s0, 0x10000160
lw $s1, 0x10000164
lw $s2, 0x10000168
lw $s3, 0x1000016C
# Limpia el buffer.
sw $zero, 0x10000160
sw $zero, 0x10000164
sw $zero, 0x10000168
sw $zero, 0x1000016C
j main # Regresa al menú.
end: li $v0, 10 # Fin del programa.
syscall ### Petición al sistema.
Ejemplo de salida:
MENU PRINCIPAL
1. Cifrar un texto.
2. Descifrar un texto.
3. Modificar la clave de cifrado.
Introduzca opciýn (1-3): 1
Introduce el texto: hola
Texto cifrado: RP¥õ´
MENU PRINCIPAL
1. Cifrar un texto.
2. Descifrar un texto.
3. Modificar la clave de cifrado.
Introduzca opciýn (1-3): 3
Introduce la nueva clave de cifrado: clavecilla
La nueva clave de cifrado es: clavecilla
MENU PRINCIPAL
1. Cifrar un texto.
2. Descifrar un texto.
3. Modificar la clave de cifrado.
Introduzca opciýn (1-3): 2
Introduce el texto: 46783269
Texto descifrado: 4òÛÎä
MENU PRINCIPAL
1. Cifrar un texto.
2. Descifrar un texto.
3. Modificar la clave de cifrado.
Introduzca opciýn (1-3): 0
-- program is finished running --Si alguien tiene interés en probarlo, puede hacerlo desde el programa Mars del que no se necesita instalar nada y funciona en Java (cosa que me gusta porque así funciona en múltiples plataformas).
El código ASM que he pegado en la entrada contendrá algunos chufanos si se visualiza desde Windows (el programa lo hice desde Ubuntu y desde ahí se verá bien al utilizarse otra codificación de texto). Se puede trabajar de todas formas con él sin problemas desde cualquier plataforma (desde Mac no lo he probado, pero lo más seguro es que también).
Perro viejo de Habbo y de HabboStium. Y lo mismo en la vida real, pero sin el "perro".