@@ -11,7 +11,7 @@ contract Step {
1111 }
1212
1313 // Executes a single RISC-V instruction, starting from
14- function step (bytes calldata stateData , bytes calldata proof ) public returns (bytes32 ) {
14+ function step (bytes calldata stateData , bytes calldata proof , bytes32 localContext ) public returns (bytes32 ) {
1515 assembly {
1616 function revertWithCode (code) {
1717 mstore (0 , code)
@@ -270,8 +270,8 @@ contract Step {
270270 // expected memory check: no allocated memory (start after scratch + free-mem-ptr + zero slot = 0x80)
271271 revert (0 , 0 )
272272 }
273- if iszero (eq (stateData.offset, 100 )) {
274- // 32*3 +4 = 100 expected state data offset
273+ if iszero (eq (stateData.offset, 132 )) {
274+ // 32*4 +4 = 132 expected state data offset
275275 revert (0 , 0 )
276276 }
277277 if iszero (eq (calldataload (sub (stateData.offset, 32 )), stateSize ())) {
@@ -283,11 +283,12 @@ contract Step {
283283 out := add (v, padding)
284284 }
285285 if iszero (eq (proof.offset, add (add (stateData.offset, paddedLen (stateSize ())), 32 ))) {
286- // 100 +stateSize+padding+32 = expected proof offset
286+ // 132 +stateSize+padding+32 = expected proof offset
287287 revert (0 , 0 )
288288 }
289289 function proofContentOffset () -> out { // since we can't reference proof.offset in functions, blame Yul
290- out := 516
290+ // 132+362+(32-362%32)+32=548
291+ out := 548
291292 }
292293 if iszero (eq (proof.offset, proofContentOffset ())) {
293294 revert (0 , 0 )
@@ -772,10 +773,28 @@ contract Step {
772773 revertWithCode (0xbadf00d0 )
773774 }
774775
775- function readPreimageValue (addr, count) -> out {
776+ function localize (preImageKey, localContext_) -> localizedKey {
777+ // TODO: deduplicate definition of localize using lib
778+ // Grab the current free memory pointer to restore later.
779+ let ptr := mload (0x40 )
780+ // Store the local data key and caller next to each other in memory for hashing.
781+ mstore (0 , preImageKey)
782+ mstore (0x20 , caller ())
783+ mstore (0x40 , localContext_)
784+ // Localize the key with the above `localize` operation.
785+ localizedKey := or (and (keccak256 (0 , 0x60 ), not (shl (248 , 0xFF ))), shl (248 , 1 ))
786+ // Restore the free memory pointer.
787+ mstore (0x40 , ptr)
788+ }
789+
790+ function readPreimageValue (addr, count, localContext_) -> out {
776791 let preImageKey := getPreimageKey ()
777792 let offset := getPreimageOffset ()
778-
793+ // If the preimage key is a local key, localize it in the context of the caller.
794+ let preImageKeyPrefix := shr (248 , preImageKey) // 256-8=248
795+ if eq (preImageKeyPrefix, 1 ) {
796+ preImageKey := localize (preImageKey, localContext_)
797+ }
779798 // make call to pre-image oracle contract
780799 let pdatB32, pdatlen := readPreimagePart (preImageKey, offset)
781800 if iszero64 (pdatlen) { // EOF
@@ -811,7 +830,7 @@ contract Step {
811830 //
812831 // Syscall handling
813832 //
814- function sysCall () {
833+ function sysCall (localContext_ ) {
815834 let a7 := getRegister (toU64 (17 ))
816835 switch a7
817836 case 93 { // exit the calling thread. No multi-thread support yet, so just exit.
@@ -872,7 +891,7 @@ contract Step {
872891 n := count
873892 errCode := toU64 (0 )
874893 } case 5 { // preimage read
875- n := readPreimageValue (addr, count)
894+ n := readPreimageValue (addr, count, localContext_ )
876895 errCode := toU64 (0 )
877896 } default {
878897 n := u64Mask () // -1 (reading error)
@@ -1275,7 +1294,7 @@ contract Step {
12751294 case 0 { // 000 = ECALL/EBREAK
12761295 switch shr64 (toU64 (20 ), instr) // I-type, top 12 bits
12771296 case 0 { // imm12 = 000000000000 ECALL
1278- sysCall ()
1297+ sysCall (localContext )
12791298 setPC (add64 (_pc, toU64 (4 )))
12801299 } default { // imm12 = 000000000001 EBREAK
12811300 setPC (add64 (_pc, toU64 (4 ))) // ignore breakpoint
0 commit comments