Commit 28920a00 authored by George Hotz's avatar George Hotz

large hash oracle works

parent e4dfa8ab
......@@ -39,16 +39,20 @@ contract MIPSMemory {
struct LargePreimage {
uint offset;
uint len;
uint32 data;
}
mapping(address => LargePreimage) public largePreimage;
// sadly due to soldiity limitations this can't be in the LargePreimage struct
mapping(address => uint64[25]) public largePreimageState;
function AddLargePreimageInit(uint offset) public {
require(offset & 3 == 0, "offset must be 32-bit aligned");
Lib_Keccak256.CTX memory c;
Lib_Keccak256.keccak_init(c);
largePreimageState[msg.sender] = c.A;
largePreimage[msg.sender].offset = offset;
largePreimage[msg.sender].len = 0;
}
// TODO: input 136 bytes, as many times as you'd like
......@@ -58,30 +62,66 @@ contract MIPSMemory {
// sha3_process_block
Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender];
int offset = int(largePreimage[msg.sender].offset) - int(largePreimage[msg.sender].len);
if (offset >= 0 && offset < 136) {
largePreimage[msg.sender].data =
uint32(uint8(dat[uint256(offset)+0])) << 24 |
uint32(uint8(dat[uint256(offset)+1])) << 16 |
uint32(uint8(dat[uint256(offset)+2])) << 8 |
uint32(uint8(dat[uint256(offset)+3])) << 0;
}
Lib_Keccak256.sha3_xor_input(c, dat);
Lib_Keccak256.sha3_permutation(c);
largePreimageState[msg.sender] = c.A;
largePreimage[msg.sender].len += 136;
}
// TODO: input <136 bytes and do the end of hash | 0x01 / | 0x80
function AddLargePreimageFinal(bytes calldata dat) public view returns (bytes32) {
require(dat.length < 136, "final must be less than 136");
function AddLargePreimageFinal(bytes calldata idat) public view returns (bytes32, uint, uint32) {
require(idat.length < 136, "final must be less than 136");
int offset = int(largePreimage[msg.sender].offset) - int(largePreimage[msg.sender].len);
require(offset < 136, "offset must be less than 136");
Lib_Keccak256.CTX memory c;
c.A = largePreimageState[msg.sender];
bytes memory fdat = new bytes(136);
for (uint i = 0; i < dat.length; i++) {
fdat[i] = dat[i];
console.log(idat.length);
bytes memory dat = new bytes(136);
for (uint i = 0; i < idat.length; i++) {
dat[i] = idat[i];
}
uint len = largePreimage[msg.sender].len + idat.length;
uint32 data = largePreimage[msg.sender].data;
if (offset >= 0) {
// comes from this block
data =
uint32(uint8(dat[uint256(offset)+0])) << 24 |
uint32(uint8(dat[uint256(offset)+1])) << 16 |
uint32(uint8(dat[uint256(offset)+2])) << 8 |
uint32(uint8(dat[uint256(offset)+3])) << 0;
}
fdat[135] = bytes1(uint8(0x80));
fdat[dat.length] |= bytes1(uint8(0x1));
dat[135] = bytes1(uint8(0x80));
dat[idat.length] |= bytes1(uint8(0x1));
Lib_Keccak256.sha3_xor_input(c, fdat);
Lib_Keccak256.sha3_xor_input(c, dat);
Lib_Keccak256.sha3_permutation(c);
// TODO: do this properly and save the hash
// when this is updated, it won't be "view"
return Lib_Keccak256.get_hash(c);
bytes32 outhash = Lib_Keccak256.get_hash(c);
return (outhash, len, data);
}
function AddLargePreimageFinalSaved(bytes calldata idat) public {
bytes32 outhash;
uint len;
uint32 data;
(outhash, len, data) = AddLargePreimageFinal(idat);
Preimage storage p = preimage[outhash];
require(p.length == 0 || p.length == len, "length is somehow wrong");
require(largePreimage[msg.sender].offset < len, "offset is beyond length");
p.length = len;
p.data[largePreimage[msg.sender].offset] = (1 << 32) | data;
}
function tb(uint32 dat) internal pure returns (bytes memory) {
......
......@@ -2,13 +2,12 @@ const { keccak256 } = require("@ethersproject/keccak256");
const { expect } = require("chai");
describe("MIPSMemory contract", function () {
it("Keccak should work", async function () {
const [owner] = await ethers.getSigners();
beforeEach(async function () {
const MIPSMemory = await ethers.getContractFactory("MIPSMemory");
const mm = await MIPSMemory.deploy();
console.log("deployed at", mm.address, "by", owner.address);
mm = await MIPSMemory.deploy();
console.log("deployed at", mm.address);
})
it("Keccak should work", async function () {
await mm.AddLargePreimageInit(0);
console.log("preimage initted");
......@@ -17,7 +16,7 @@ describe("MIPSMemory contract", function () {
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));
expect((await mm.AddLargePreimageFinal(test))[0]).to.equal(keccak256(test));
}
await tl(0)
await tl(100)
......@@ -29,7 +28,7 @@ describe("MIPSMemory contract", function () {
dat[0] = 0x61
await mm.AddLargePreimageUpdate(dat);
const hash = await mm.AddLargePreimageFinal([]);
const hash = (await mm.AddLargePreimageFinal([]))[0];
console.log("preimage updated");
const realhash = keccak256(dat);
......@@ -37,4 +36,16 @@ describe("MIPSMemory contract", function () {
console.log("real hash is", realhash);
expect(hash).to.equal(realhash);
});
it("oracle save should work", async function () {
await mm.AddLargePreimageInit(4)
let dat = new TextEncoder("utf-8").encode("hello world")
const tst = await mm.AddLargePreimageFinal(dat)
expect(tst[0]).to.equal(keccak256(dat))
expect(tst[1].toNumber()).to.equal(11)
expect(tst[2]).to.equal(0x6f20776f)
console.log(tst)
await mm.AddLargePreimageFinalSaved(dat)
})
});
\ No newline at end of file
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