@@ -11,7 +11,7 @@ contract Step {
11
11
}
12
12
13
13
// 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 ) {
15
15
assembly {
16
16
function revertWithCode (code) {
17
17
mstore (0 , code)
@@ -270,8 +270,8 @@ contract Step {
270
270
// expected memory check: no allocated memory (start after scratch + free-mem-ptr + zero slot = 0x80)
271
271
revert (0 , 0 )
272
272
}
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
275
275
revert (0 , 0 )
276
276
}
277
277
if iszero (eq (calldataload (sub (stateData.offset, 32 )), stateSize ())) {
@@ -283,11 +283,12 @@ contract Step {
283
283
out := add (v, padding)
284
284
}
285
285
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
287
287
revert (0 , 0 )
288
288
}
289
289
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
291
292
}
292
293
if iszero (eq (proof.offset, proofContentOffset ())) {
293
294
revert (0 , 0 )
@@ -772,10 +773,28 @@ contract Step {
772
773
revertWithCode (0xbadf00d0 )
773
774
}
774
775
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 {
776
791
let preImageKey := getPreimageKey ()
777
792
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
+ }
779
798
// make call to pre-image oracle contract
780
799
let pdatB32, pdatlen := readPreimagePart (preImageKey, offset)
781
800
if iszero64 (pdatlen) { // EOF
@@ -811,7 +830,7 @@ contract Step {
811
830
//
812
831
// Syscall handling
813
832
//
814
- function sysCall () {
833
+ function sysCall (localContext_ ) {
815
834
let a7 := getRegister (toU64 (17 ))
816
835
switch a7
817
836
case 93 { // exit the calling thread. No multi-thread support yet, so just exit.
@@ -872,7 +891,7 @@ contract Step {
872
891
n := count
873
892
errCode := toU64 (0 )
874
893
} case 5 { // preimage read
875
- n := readPreimageValue (addr, count)
894
+ n := readPreimageValue (addr, count, localContext_ )
876
895
errCode := toU64 (0 )
877
896
} default {
878
897
n := u64Mask () // -1 (reading error)
@@ -1275,7 +1294,7 @@ contract Step {
1275
1294
case 0 { // 000 = ECALL/EBREAK
1276
1295
switch shr64 (toU64 (20 ), instr) // I-type, top 12 bits
1277
1296
case 0 { // imm12 = 000000000000 ECALL
1278
- sysCall ()
1297
+ sysCall (localContext )
1279
1298
setPC (add64 (_pc, toU64 (4 )))
1280
1299
} default { // imm12 = 000000000001 EBREAK
1281
1300
setPC (add64 (_pc, toU64 (4 ))) // ignore breakpoint
0 commit comments