Biblioteca SHA3_512, convierte la entrada y la salida a bytes de 512 bits

La biblioteca SHA3_512 toma una entrada uint64[8]y una salida uint32[16]. Para convertir la entrada de 64 bytesy 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;
    }

Respuestas (1)

La máquina virtual Ethereum es big endian ( leer más ), por lo que para formatear la entrada de bytesa 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];
    }