¿Cómo se implementa la función keccak256(a, b)?

Necesito entender cómo se implementa keccak256(a, b) y en qué se diferencia de keccak256(a || b).

¿El contenido está acolchado?

Necesito esto porque no quiero permitir vulnerabilidades en las que un usuario pueda falsificar un hash, por ejemplo, haciendo: H(0xabc, 0xdef) = H(0xa, 0xbcdef) que sería una gran vulnerabilidad de seguridad.

Gracias

Implementé un breve ejemplo en Solidity y ejecutar keccak256 (0xa, 0xa) no es igual a keccak256 (0xaa). Sin embargo, todavía necesito entender lo que está pasando debajo del capó.

Respuestas (2)

Solidity utiliza un modo empaquetado no estándar en el que los argumentos se empaquetan de forma compacta. Puede consultar el algoritmo en los documentos: Solidity: non-standard-packed-mode

En resumen, keccak256(a,b) = keccak(a || b)se da. Quizás se pregunte por qué su ejemplo keccak256(0xa, 0xa) ≠ keccak256(0xaa)parece probar que mi tesis es incorrecta. Esto se debe simplemente a que intentó usar un tipo de datos desconocido en Solidity. En Solidity los números se almacenan en un múltiplo de 8 bits. Intentó usar un número que contiene solo 4 bits, lo que lleva a una situación en la que el compilador de Solidity se ve obligado a rellenar su número para que quepa en 8 bits. 0xase convirtió 0x0apor ejemplo. Así que trataste de comparar keccak256(0xa, 0xa) = keccak256(0x0a, 0x0a) = keccak256(0x0a0a)conkeccak256(0xaa)

Esto significa que si desea evitar los ataques de relleno, debe asegurarse de que sus variables tengan las longitudes correctas, de modo que ninguna variable pueda "desbordarse" sobre la otra.

Se recomienda usar el nuevo abi.encodePacked cuando hay más de un parámetro parakeccak256

Estas funciones de codificación se pueden usar para crear datos para llamadas a funciones sin llamar realmente a una función. Además, keccak256(abi.encodePacked(a, b))es una forma más explícita de computar keccak256(a, b), que quedará obsoleta en futuras versiones.