Commit e4dfa8ab authored by George Hotz's avatar George Hotz

move end logic into keccak256 solidity

parent a74814e7
......@@ -53,27 +53,30 @@ contract MIPSMemory {
// TODO: input 136 bytes, as many times as you'd like
// Uses about 1M gas, 7352 gas/byte
function AddLargePreimageUpdate(uint64[17] calldata data) public {
function AddLargePreimageUpdate(bytes calldata dat) public {
require(dat.length == 136, "update must be in multiples of 136");
// sha3_process_block
Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender];
for (uint i = 0; i < 17; i++) {
c.A[i] ^= data[i];
}
Lib_Keccak256.sha3_xor_input(c, dat);
Lib_Keccak256.sha3_permutation(c);
largePreimageState[msg.sender] = c.A;
}
// TODO: input <136 bytes and do the end of hash | 0x01 / | 0x80
function AddLargePreimageFinal(uint64[17] calldata data) public view returns (bytes32) {
function AddLargePreimageFinal(bytes calldata dat) public view returns (bytes32) {
require(dat.length < 136, "final must be less than 136");
Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender];
// TODO: check data is valid as the final block
// maybe even modify it
for (uint i = 0; i < 17; i++) {
c.A[i] ^= data[i];
bytes memory fdat = new bytes(136);
for (uint i = 0; i < dat.length; i++) {
fdat[i] = dat[i];
}
fdat[135] = bytes1(uint8(0x80));
fdat[dat.length] |= bytes1(uint8(0x1));
Lib_Keccak256.sha3_xor_input(c, fdat);
Lib_Keccak256.sha3_permutation(c);
// TODO: do this properly and save the hash
......
......@@ -90,6 +90,20 @@ library Lib_Keccak256 {
}
}
function sha3_xor_input(CTX memory c, bytes memory dat) internal pure {
for (uint i = 0; i < 17; i++) {
uint bo = i*8;
c.A[i] ^= uint64(uint8(dat[bo+7])) << 56 |
uint64(uint8(dat[bo+6])) << 48 |
uint64(uint8(dat[bo+5])) << 40 |
uint64(uint8(dat[bo+4])) << 32 |
uint64(uint8(dat[bo+3])) << 24 |
uint64(uint8(dat[bo+2])) << 16 |
uint64(uint8(dat[bo+1])) << 8 |
uint64(uint8(dat[bo+0])) << 0;
}
}
function sha3_permutation(CTX memory c) internal pure {
uint round;
for (round = 0; round < 24; round++) {
......
const { keccak256 } = require("@ethersproject/keccak256");
const { expect } = require("chai");
const empty = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
const endEmpty = [0x1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"0x8000000000000000"];
describe("MIPSMemory contract", function () {
it("Keccak should work", async function () {
const [owner] = await ethers.getSigners();
......@@ -16,18 +13,26 @@ describe("MIPSMemory contract", function () {
console.log("preimage initted");
// empty
expect(await mm.AddLargePreimageFinal(endEmpty)).to.equal(keccak256(new Uint8Array(0)));
async function tl(n) {
const test = new Uint8Array(n)
for (var i = 0; i < n; i++) test[i] = 0x62;
console.log("test size", n)
expect(await mm.AddLargePreimageFinal(test)).to.equal(keccak256(test));
}
await tl(0)
await tl(100)
await tl(134)
await tl(135)
// block size is 136
await mm.AddLargePreimageUpdate(empty);
let dat = new Uint8Array(136)
dat[0] = 0x61
await mm.AddLargePreimageUpdate(dat);
const hash = await mm.AddLargePreimageFinal(endEmpty);
const hash = await mm.AddLargePreimageFinal([]);
console.log("preimage updated");
/*var tst1 = await mm.largePreimage(owner.address, 0);
console.log(tst);*/
const realhash = keccak256(new Uint8Array(136));
const realhash = keccak256(dat);
console.log("comp hash is", hash);
console.log("real hash is", realhash);
expect(hash).to.equal(realhash);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment