Commit e4dfa8ab authored by George Hotz's avatar George Hotz

move end logic into keccak256 solidity

parent a74814e7
...@@ -53,27 +53,30 @@ contract MIPSMemory { ...@@ -53,27 +53,30 @@ contract MIPSMemory {
// TODO: input 136 bytes, as many times as you'd like // TODO: input 136 bytes, as many times as you'd like
// Uses about 1M gas, 7352 gas/byte // 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 // sha3_process_block
Lib_Keccak256.CTX memory c; Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender]; c.A = largePreimageState[msg.sender];
for (uint i = 0; i < 17; i++) { Lib_Keccak256.sha3_xor_input(c, dat);
c.A[i] ^= data[i];
}
Lib_Keccak256.sha3_permutation(c); Lib_Keccak256.sha3_permutation(c);
largePreimageState[msg.sender] = c.A; largePreimageState[msg.sender] = c.A;
} }
// TODO: input <136 bytes and do the end of hash | 0x01 / | 0x80 // 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; Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender]; c.A = largePreimageState[msg.sender];
// TODO: check data is valid as the final block bytes memory fdat = new bytes(136);
// maybe even modify it for (uint i = 0; i < dat.length; i++) {
for (uint i = 0; i < 17; i++) { fdat[i] = dat[i];
c.A[i] ^= data[i];
} }
fdat[135] = bytes1(uint8(0x80));
fdat[dat.length] |= bytes1(uint8(0x1));
Lib_Keccak256.sha3_xor_input(c, fdat);
Lib_Keccak256.sha3_permutation(c); Lib_Keccak256.sha3_permutation(c);
// TODO: do this properly and save the hash // TODO: do this properly and save the hash
......
...@@ -90,6 +90,20 @@ library Lib_Keccak256 { ...@@ -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 { function sha3_permutation(CTX memory c) internal pure {
uint round; uint round;
for (round = 0; round < 24; round++) { for (round = 0; round < 24; round++) {
......
const { keccak256 } = require("@ethersproject/keccak256"); const { keccak256 } = require("@ethersproject/keccak256");
const { expect } = require("chai"); 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 () { describe("MIPSMemory contract", function () {
it("Keccak should work", async function () { it("Keccak should work", async function () {
const [owner] = await ethers.getSigners(); const [owner] = await ethers.getSigners();
...@@ -16,18 +13,26 @@ describe("MIPSMemory contract", function () { ...@@ -16,18 +13,26 @@ describe("MIPSMemory contract", function () {
console.log("preimage initted"); console.log("preimage initted");
// empty // 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 // 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"); console.log("preimage updated");
/*var tst1 = await mm.largePreimage(owner.address, 0); const realhash = keccak256(dat);
console.log(tst);*/
const realhash = keccak256(new Uint8Array(136));
console.log("comp hash is", hash); console.log("comp hash is", hash);
console.log("real hash is", realhash); console.log("real hash is", realhash);
expect(hash).to.equal(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