0

The SHA3_512 library takes an input uint64[8] and outputs uint32[16]. To convert the input from 64 bytes and the output back to bytes, I wrote this, but it gives the wrong result. What are some examples that work?

    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;
    }
Anon
  • 1
  • 3

1 Answers1

0

The Ethereum Virtual Machine is big endian (read more), so to format the input from bytes to uint64[8], the byte have to be reversed.

    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];
    }

Then generate the input from the reversed message

    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

For the output, repeat the same process,

    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];
    }
Anon
  • 1
  • 3