La biblioteca SHA3_512 toma una entrada uint64[8]
y una salida uint32[16]
. Para convertir la entrada de 64 bytes
y la salida de nuevo a bytes
, escribí esto, pero da un resultado incorrecto. ¿Cuáles son algunos ejemplos que funcionan?
function 64bytesToSHA3_512(bytes _message) returns (bytes) {
uint64[8] memory input;
for(uint i = 0; i < 8; i++) {
bytes8 oneEigth;
// Load 8 byte from _message at position 32 + i * 8
assembly {
oneEigth := mload(add(_message, add(32, mul(i, 8))))
}
input[i] = uint64(oneEigth);
}
uint32[16] memory output = hash(input); // hash() is in contract SHA3_512
bytes memory messageHash = new bytes(64);
for(i = 0; i < 16; i++) {
bytes4 oneSixteenth = bytes4(output[i]);
// Store 4 byte in messageHash at position 32 + i * 4
assembly { mstore(add(messageHash, add(32, mul(i, 4))), oneSixteenth) }
}
return messageHash;
}
La máquina virtual Ethereum es big endian ( leer más ), por lo que para formatear la entrada de bytes
a uint64[8]
, el byte debe invertirse.
uint64[8] memory input;
// The evm is big endian, reverse the bytes
bytes memory reversed = new bytes(64);
for(uint i = 0; i < 64; i++) {
reversed[i] = _message[63 - i];
}
A continuación, generar la entrada de la inversamessage
for(i = 0; i < 8; i++) {
bytes8 oneEigth;
// Load 8 byte from reversed message at position 32 + i * 8
assembly {
oneEigth := mload(add(reversed, add(32, mul(i, 8))))
}
input[7 - i] = uint64(oneEigth);
}
uint32[16] memory output = hash(input); // hash() is in contract SHA3_512
Para la salida, repita el mismo proceso,
bytes memory reverseHash = new bytes(64);
for(i = 0; i < 16; i++) {
bytes4 oneSixteenth = bytes4(output[15 - i]);
// Store 4 byte in reverseHash at position 32 + i * 4
assembly { mstore(add(reverseHash, add(32, mul(i, 4))), oneSixteenth) }
}
bytes memory messageHash = new bytes(64);
for(uint i = 0; i < 64; i++) {
messageHash[i] = reverseHash[63 - i];
}