Closed VicenteVicente closed 2 years ago
Gracias por las preguntas, estas convenciones son importantes para obtener el hash correcto.
Aquí van las respuestas:
(1) Si el largo del mensaje m
no es divisible por l_block
, entonces se debe agregar 10...0
al último bloque de m
para que su largo sea divisible por l_block
. Si largo del mensaje m
es divisible por l_block
, entonces no se debe agregar 10...0
a m
.
(2.1) Sí, el largo que se debe poner en el último bloque del padding es n_bytes % (2**l_block)
.
(2.2) Para representar el largo en el último bloque del padding debes considerar a un arreglo de bytes como un número en base 256
.
Aquí van algunos ejemplos del resultado de la función pad
suponiendo que el largo del bloque (l_block
) es 16
.
Si el mensaje es 0123456789012345
, entonces el resultado de llamar a pad
es
0123456789012345\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10
En este caso no se agrega 10...0
ya que el largo del mensaje es 16
, y el resultado del padding tiene dos bloques de 16
bytes cada uno. En el segundo bloque se codifica el largo 16
como un número en base 256
: como 16 = 16*(256**0)
, se debe poner en el dígito menos significativo el valor 16
que corresponde a \x10
como byte.
Si el mensaje es 0
, entonces el resultado de llamar a pad
es
0\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01
En este caso se agrega 100000000000000
al primer bloque para que su largo sea 16
. En el segundo bloque se codifica el largo 1
como un número en base 256
: como 1 = 1*(256**0)
, se debe poner en el dígito menos significativo el valor 1
que corresponde a \x01
como byte.
Considera el siguiente mensaje que tiene largo 300
:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789
En este caso el resultado de llamar a la función pad
es:
01234567890123456789012345678901234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789012345678901234567890123456789
01234567890123456789012345678901234567890123456789012345678901234567890123456789
012345678901234567890123456789012345678901234567890123456789\x01\x00\x00\x00
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01,
Se debe agregar 1000
al último bloque del mensaje ya que su largo es 12
. En el último bloque del padding se codifica el largo 300
como un número en base 256
: como 300 = 1*(256**1) + 44*(256**0)
, se debe poner 1
en el segundo dígito menos significativo y 44
en el dígito menos significativo, lo cual corresponde a \x01
y ,
como bytes, respectivamente (44
en la tabla ASCII corresponde a ,
).
¿Queda más claro con estos ejemplos?
Saludos!
Sí!, me quedaron todas mis dudas clarísimas. Sin embargo, me surgió otra sobre un detalle de la base 256:
Si en python
yo tengo un int N
, y luego hago N.to_bytes(l_block, "big")
, pareciera que el resultado ya está en base 256. ¿Estoy en lo correcto?
Sí, estás en lo correcto.
Saludos!
@marceloarenassaavedra una duda respecto a lo que debe entregar pad. En el ejemplo de largo 300 está efectivamente el mensaje y su pad, junto con el largo del mensaje en bytes. Dado que no se puede concatenar string y byte la idea es que lo pasemos a algun formato en particular cada byte? (me imagino que hacer str(\x00...) no seria del todo correcto porque se ven los strings por separado.
Gracias de antemano!
En el ejemplo que mencionas, la función pad
recibe el mensaje como un bytearray
de largo 300, y debe retornar el padding de este mensaje como un bytearray
de largo 320.
Saludos!
Me surge un pregunta. el bloque final va a ser de largo l_block y este permite representar un numero de tamaño: (2 8) l_block - 1, pues cada byte al final es de 8 bits que da un tamaño de 2 8. no sería posible dejar el valor final como n%(2 8)** l_block?
Efectivamente, en el último bloque se puede almacenar un número entre 0 y (2**8)**l_block - 1
. Si el largo del mensaje es mayor que este número, se podría utilizar n%((2**8)**l_block)
como tú sugieres. En todo caso, en la práctica no es necesario utilizar utiliza %
ya que se requiere de mensajes muy grandes para superar el largo máximo que se puede almacenar. Por ejemplo, si usamos bloques de 16 bytes, entonces necesitamos un mensaje con al menos (2**8)**16 = 340282366920938463463374607431768211456
dígitos decimales para no poder almacenar su largo en el último bloque del padding. Para la tarea estamos en la misma situación, en ninguno de los casos de prueba va a ser necesario utilizar %
.
Saludos!
Hola! tengo un par de dudas sobre la implementación de esta función:
Si $|message| \mod l\_block = 0$, ¿También debo añadir un bloque de padding, o bien, eso lo debo hacer SOLAMENTE en el caso que no sea divisible por
l_block
?Para la tarea se pide que el último bloque sea el largo en bytes del mensaje (llamémoslo
n_bytes
): 2.1. ¿Este largo debería ser $n\_bytes\mod 2^{l\_block}$? (Como lo vimos en clases pero ahora en bytes) 2.2. ¿Cómo debo codificarlo?, por ejemplo se me ocurre simplemente pasar este número a binario y dejarlo en el nuevo bloque.Desde ya muchas gracias :)