diff --git a/main/loadtx_rlp.zkasm b/main/loadtx_rlp.zkasm index 3956a107..eb57edfa 100644 --- a/main/loadtx_rlp.zkasm +++ b/main/loadtx_rlp.zkasm @@ -263,7 +263,7 @@ dataREAD: veryShortData: 1 :MSTORE(txCalldataLen) 31 => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(SP++) :JMP(endData) @@ -310,7 +310,7 @@ readDataFinal: C + D => C 32-D => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(SP) endData: diff --git a/main/opcodes.zkasm b/main/opcodes.zkasm index 46da18ec..bf5b184b 100644 --- a/main/opcodes.zkasm +++ b/main/opcodes.zkasm @@ -324,9 +324,8 @@ opBYTE: $ => B :MLOAD(SP--) $ => A :MLOAD(SP) 31 - B => D - ${A >> (D*8)} => B + :CALL(SHRarith) GAS-3 => GAS - B => A 255 => B $ :AND,MSTORE(SP++) :JMP(readCode) @@ -335,7 +334,14 @@ opSHR: SP - 1 => SP $ => D :MLOAD(SP--) $ => A :MLOAD(SP) + A => E + ${exp(2,D)} => B + ${B-1} => B + $ => C :AND + ${exp(2,D)} => B ${A >> D} => A + 0 => D + E :ARITH A :MSTORE(SP++) GAS-3 => GAS :JMP(readCode) @@ -344,8 +350,30 @@ opSHL: SP - 1 => SP $ => D :MLOAD(SP--) $ => A :MLOAD(SP) - ${A << D} => A - A :MSTORE(SP++) + ${A << D} => E + 256 - D => D :JMPC(SHL0) + ${exp(2,D)} => B + ${B-1} => B + $ => C :GT + 256 - D => D + ${exp(2,D)} => B + 0 - C :JMPC(SHLbig) + 0 => D,C + E :ARITH + :JMP(SHLfinal) +SHL0: + 0 :MSTORE(SP++) + GAS-3 => GAS + :JMP(readCode) +SHLbig: + 256 - D => D + ${exp(2,D)} => D + ${A/D} => D + 0 => C + E :ARITH + +SHLfinal: + E :MSTORE(SP++) GAS-3 => GAS :JMP(readCode) @@ -368,7 +396,8 @@ opSAR: $ => A :MLOAD(SP) :CALL(abs) ; if more than 32 set to 32 - ${A >> (D*8)} => C + :CALL(SHRarith) + A => C B => A 1 => B $ => B :XOR @@ -434,7 +463,7 @@ opSHA3Loop: opSHA3Final: :CALL(MLOADX) 32 - C => D - ${A >> (D*8)} => A + :CALL(SHRarith) $ => E :MLOAD(lastHashIdUsed) C => D A :HASHK(E) @@ -516,10 +545,11 @@ opCALLDATALOAD2: A => D 1024 + B => SP $ => A :MLOAD(SP++) - ${A << (D*8)} => B + :CALL(SHLarith) + A => B 32 - D => D $ => A :MLOAD(SP) - ${A >> (D*8)} => A + :CALL(SHRarith) C => SP B + A :MSTORE(SP++) GAS - 3 => GAS @@ -553,12 +583,13 @@ opCALLDATACOPYinit: $ => A :MLOAD(arithRes1) 1024 + A => SP $ => A :MLOAD(SP) - ${A << (D*8)} => C + :CALL(SHLarith) + A => C $ => A :MLOAD(arithRes1) 1024 + A + 1 => SP 32 - D => D $ => A :MLOAD(SP) - ${A >> (D*8)} => A + :CALL(SHRarith) A + C :MSTORE(bytesToStore) :CALL(MSTORE32) $ => SP :MLOAD(SPw) @@ -572,7 +603,7 @@ opCALLDATACOPYfinal: ${B%32} => D 1024 + ${B/32} => SP $ => A :MLOAD(SP) - ${A << (D*8)} => A + :CALL(SHLarith) $ => SP :MLOAD(SPw) $ => C :MLOAD(SP) ;length 1024 + ${B/32} + 1 => SP @@ -581,9 +612,9 @@ opCALLDATACOPYfinal: A => B $ => A :MLOAD(SP) 32 - D => D - ${A >> (D*8)} => A + :CALL(SHRarith) 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) B + A => A A :MSTORE(bytesToStore) :CALL(MSTOREX) @@ -591,8 +622,8 @@ opCALLDATACOPYfinal: opCALLDATACOPYxor: 32 - C => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + :CALL(SHRarith) + :CALL(SHLarith) A :MSTORE(bytesToStore) :CALL(MSTOREX) @@ -650,7 +681,7 @@ opCODECOPYinit: opCODECOPYfinal: ${getBytecode(A,B,C)} => A 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(bytesToStore) :CALL(MSTOREX) @@ -705,7 +736,7 @@ opEXTCODECOPYinit: opEXTCODECOPYfinal: ${getBytecode(A,B,C)} => A 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(bytesToStore) :CALL(MSTOREX) @@ -929,7 +960,7 @@ opMSTORE8: $ => A :MLOAD(SP) ;value 1 => C 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(bytesToStore) :CALL(MSTOREX) GAS - 3 => GAS @@ -1151,7 +1182,7 @@ opAuxPUSHC: D - E => D $ => B :MLOAD(SP) ${getByte(B,C,D)} => B - ${A >> (D*8)} => A + :CALL(SHRarith) $ => SP :MLOAD(SPw) A + B :MSTORE(SP++) GAS-3 => GAS diff --git a/main/precompiled/blake2f.zkasm b/main/precompiled/blake2f.zkasm index a3e264fd..1a948c59 100644 --- a/main/precompiled/blake2f.zkasm +++ b/main/precompiled/blake2f.zkasm @@ -17,7 +17,7 @@ BLAKE2FLoopData: BLAKE2FEndLoopData: $ => A :MLOAD(SP) 32 - B => D - ${A >> (D*8)} => A + :CALL(SHRarith) ${precompiled_blake2f_add(A, B)} BLAKE2FDigestReturn: diff --git a/main/precompiled/modexp.zkasm b/main/precompiled/modexp.zkasm index c0c1d084..51f645a0 100644 --- a/main/precompiled/modexp.zkasm +++ b/main/precompiled/modexp.zkasm @@ -32,7 +32,7 @@ MODEXP: ;ASSERT C == D ;Result of the computation, with the same number of bytes as M 32 - D => D - ${A << (D*8)} => A + :CALL(SHLarith) A :MSTORE(bytesToStore) C - 32 :JMPC(MODEXPstoreX) :CALL(MSTORE32) diff --git a/main/precompiled/ripemd160.zkasm b/main/precompiled/ripemd160.zkasm index 9c67bbd3..bdb7b28f 100644 --- a/main/precompiled/ripemd160.zkasm +++ b/main/precompiled/ripemd160.zkasm @@ -15,7 +15,7 @@ RIPEMD160LoopData: ; set array of bytes in RIPEMD160 RIPEMD160EndLoopData: $ => A :MLOAD(SP) 32 - B => D - ${A >> (D*8)} => A + :CALL(SHRarith) ${precompiled_ripemd160_add(A, B)} RIPEMD160DigestReturn: ; digest hash and prepare return diff --git a/main/precompiled/sha256.zkasm b/main/precompiled/sha256.zkasm index 168f293d..53bb91f0 100644 --- a/main/precompiled/sha256.zkasm +++ b/main/precompiled/sha256.zkasm @@ -15,7 +15,7 @@ SHA256LoopData: ; set array of bytes in sha256 SHA256EndLoopData: $ => A :MLOAD(SP) 32 - B => D - ${A >> (D*8)} => A + :CALL(SHRarith) ${precompiled_sha256_add(A, B)} SHA256DigestReturn: ; digest hash and prepare return diff --git a/main/process_tx.zkasm b/main/process_tx.zkasm index d1a51f27..862425d4 100644 --- a/main/process_tx.zkasm +++ b/main/process_tx.zkasm @@ -222,8 +222,8 @@ endContractAddress: HASHPOS :HASHKLEN(E) $ => A :HASHKDIGEST(E) 12 => D - ${A << (D*8)} => A - ${A >> (D*8)} => A + :CALL(SHLarith) + :CALL(SHRarith) A :MSTORE(createContractAddress) ; TODO: Check nonce != 0 OR already_bytecode ==> same behaviour as fail constructor ; TODO: check CREATE or deployment with constructor reverted @@ -255,7 +255,7 @@ loopCreate2: endloopCreate2: $ => A :MLOAD(SP) 32 - C => D - ${A >> (D*8)} => A + :CALL(SHRarith) C => D A :HASHK(E) @@ -280,8 +280,8 @@ create2end: HASHPOS :HASHKLEN(E) $ => A :HASHKDIGEST(E) 12 => D - ${A << (D*8)} => A ; // TODO: Could be replaced by a bitwise and: ${bitwise_and(A, 2**160 - 1) - ${A >> (D*8)} => A + :CALL(SHLarith) ; // TODO: Could be replaced by a bitwise and: ${bitwise_and(A, 2**160 - 1) + :CALL(SHRarith) A :MSTORE(createContractAddress) deploy: diff --git a/main/utils.zkasm b/main/utils.zkasm index 5345493c..26d01dd7 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -5,6 +5,11 @@ VAR GLOBAL tmpVarB VAR GLOBAL tmpVarC VAR GLOBAL tmpVarD VAR GLOBAL tmpVarE +VAR GLOBAL tmpVarA2 +VAR GLOBAL tmpVarB2 +VAR GLOBAL tmpVarC2 +VAR GLOBAL tmpVarD2 +VAR GLOBAL tmpVarE2 VAR GLOBAL arithA VAR GLOBAL arithB VAR GLOBAL arithRes1 @@ -35,6 +40,7 @@ endca2: ; @info copy MEM A to ctxB SP = 1024 ; TODO: copy + 32 bytes copySP: + RR :MSTORE(tmpZkPC) CTX :MSTORE(currentCTX) 1024 => SP ;destOffset = 0 $ => CTX :MLOAD(originCTX) @@ -56,8 +62,8 @@ copyInit: copyFinal: $ => A :MLOAD(MEM:E) 32 - C => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + zkPC+1 => RR :JMP(SHLarith) $ => CTX :MLOAD(currentCTX) A :MSTORE(SP++) :JMP(copyEnd) @@ -68,11 +74,12 @@ copyInit2: ${E%32} => D ${(E/32)*32} => E $ => A :MLOAD(MEM:E) - ${A << (D*8)} => B + :CALL(SHLarith) + A => B 32 - D => D E + 32 => E $ => A :MLOAD(MEM:E) - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) $ => CTX :MLOAD(currentCTX) A + B :MSTORE(SP++) $ => CTX :MLOAD(originCTX) @@ -85,8 +92,8 @@ copyFinal2: ${(E/32)*32} => E $ => A :MLOAD(MEM:E) 32 - C => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + :CALL(SHLarith) $ => CTX :MLOAD(currentCTX) A :MSTORE(SP++) :JMP(copyEnd) @@ -95,25 +102,28 @@ copyFinal22: ${E%32} => D ${(E/32)*32} => E $ => A :MLOAD(MEM:E) - ${A << (D*8)} => B + :CALL(SHLarith) + A => B E + 32 => E $ => A :MLOAD(MEM:E) C - 32 + D => D 32 - D => D - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) $ => CTX :MLOAD(currentCTX) A + B :MSTORE(SP++) copyEnd: $ => CTX :MLOAD(currentCTX) + $ => RR :MLOAD(tmpZkPC) :RETURN ; @info byte length of B ; @in B => number ; @out A => bytes length getLenBytes: + RR :MSTORE(tmpZkPC) B :MSTORE(tmpVarB) C :MSTORE(tmpVarC) 0 => C @@ -124,7 +134,7 @@ getLenBytesLoop: $ => B :EQ 0 - B :JMPC(getLenEnd) 1 => D - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) C + 1 => C :JMP(getLenBytesLoop) @@ -132,6 +142,7 @@ getLenEnd: C => A $ => B :MLOAD(tmpVarB) $ => C :MLOAD(tmpVarC) + $ => RR :MLOAD(tmpZkPC) :RETURN ; @info save value to memory 32 bytes with offset @@ -142,6 +153,7 @@ getLenEnd: VAR GLOBAL bytesToStore MSTORE32: + RR :MSTORE(tmpZkPC) A :MSTORE(tmpVarA) B :MSTORE(tmpVarB) C :MSTORE(tmpVarC) @@ -152,22 +164,22 @@ MSTORE32: ${(E/32)*32} => E $ => A :MLOAD(MEM:E) 32 - C => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + :CALL(SHLarith) A => B $ => A :MLOAD(bytesToStore) C => D - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) A + B :MSTORE(MEM:E) E + 32 => E ;new offset $ => A :MLOAD(MEM:E) C => D - ${A << (D*8)} => A - ${A >> (D*8)} => A + :CALL(SHLarith) + zkPC+1 => RR :JMP(SHRarith) A => B $ => A :MLOAD(bytesToStore) 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) A + B :MSTORE(MEM:E) $ => E :MLOAD(tmpVarE) E + 32 => E @@ -186,6 +198,7 @@ MSTORE322: ; @out E => new offset MSTOREX: + RR :MSTORE(tmpZkPC) A :MSTORE(tmpVarA) B :MSTORE(tmpVarB) C :MSTORE(tmpVarC) @@ -195,11 +208,12 @@ MSTOREX: ${E%32} => D ${(E/32)*32} => E $ => A :MLOAD(bytesToStore) - ${A >> (D*8)} => B + :CALL(SHRarith) + A => B $ => A :MLOAD(MEM:E) 32 - D => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + :CALL(SHLarith) A + B :MSTORE(MEM:E) $ => E :MLOAD(tmpVarE) E + C => E ;new offset @@ -209,18 +223,20 @@ MSTOREX2: ${E%32} => D ${(E/32)*32} => E $ => A :MLOAD(bytesToStore) - ${A >> (D*8)} => B + :CALL(SHRarith) + A => B $ => A :MLOAD(MEM:E) 32 - D => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + :CALL(SHLarith) A + B :MSTORE(MEM:E) E + 32 => E $ => A :MLOAD(bytesToStore) - ${A << (D*8)} => B + :CALL(SHLarith) + A => B $ => A :MLOAD(MEM:E) C - D => D - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) A + B :MSTORE(MEM:E) $ => E :MLOAD(tmpVarE) E + C => E ;new offset @@ -230,6 +246,7 @@ MSTOREend: $ => B :MLOAD(tmpVarB) $ => C :MLOAD(tmpVarC) $ => D :MLOAD(tmpVarD) + $ => RR :MLOAD(tmpZkPC) :RETURN @@ -239,10 +256,10 @@ MSTOREend: ; @out E => new offset MLOAD32: + RR :MSTORE(tmpZkPC) B :MSTORE(tmpVarB) C :MSTORE(tmpVarC) D :MSTORE(tmpVarD) - 32 => A ${E%A} => C ${E/A} => B @@ -265,11 +282,12 @@ MLOAD32: $ => A :MLOAD(MEM:E) C => D - ${A << (D*8)} => B + :CALL(SHLarith) + A => B 32 - C => D E + 32 => E $ => A :MLOAD(MEM:E) - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) A + B => A E + C => E ;new offset :JMP(MLOADend) @@ -286,6 +304,7 @@ MLOAD322: ; @out E => new offset MLOADX: + RR :MSTORE(tmpZkPC) B :MSTORE(tmpVarB) C :MSTORE(tmpVarC) D :MSTORE(tmpVarD) @@ -295,25 +314,26 @@ MLOADX: ${(E/32)*32} => E $ => A :MLOAD(MEM:E) B => D - ${A << (D*8)} => A + :CALL(SHLarith) 32 - C => D - ${A >> (D*8)} => A - ${A << (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) + :CALL(SHLarith) E + B + C => E ;new offset - :JMP(MLOADend) + :JMP(MLOADend) MLOADX2: ${E%32} => D ${(E/32)*32} => E $ => A :MLOAD(MEM:E) - ${A << (D*8)} => B + :CALL(SHLarith) + A => B E + 32 => E $ => A :MLOAD(MEM:E) C - 32 + D => D 32 - D => D - ${A >> (D*8)} => A + zkPC+1 => RR :JMP(SHRarith) 32 - C => D - ${A << (D*8)} => A + :CALL(SHLarith) A + B => A E :MLOAD(tmpVarE) E + C => E ;new offset @@ -322,6 +342,7 @@ MLOADend: $ => B :MLOAD(tmpVarB) $ => C :MLOAD(tmpVarC) $ => D :MLOAD(tmpVarD) + $ => RR :MLOAD(tmpZkPC) :RETURN ; @info check account is empty ( balance == nonce == code == 0x ) @@ -491,4 +512,81 @@ storeTmp: C :MSTORE(tmpVarC) D :MSTORE(tmpVarD) E :MSTORE(tmpVarE) - :JMP(RR) \ No newline at end of file + :JMP(RR) + +;@in A - (A >> D) +;@in D - (A >> D) +;@out A - A >> D => A +SHRarith: + B :MSTORE(tmpVarB2) + C :MSTORE(tmpVarC2) + D :MSTORE(tmpVarD2) + E :MSTORE(tmpVarE2) + 0 => B + $ => B :EQ + 0 - B :JMPC(SHRarithfinal) + A => E + ${exp(2,D*8)} => B + ${B-1} => B + $ => C :AND + ${exp(2,D*8)} => B + 0 => A + $ => B :EQ + 0 - B :JMPC(SHRarithfinal) + ${exp(2,D*8)} => B + ${E/B} => A + 0 => D + E :ARITH + +SHRarithfinal: + $ => B :MLOAD(tmpVarB2) + $ => C :MLOAD(tmpVarC2) + $ => D :MLOAD(tmpVarD2) + $ => E :MLOAD(tmpVarE2) + :JMP(RR) + +;@in A - (A << D) +;@in D - (A << D) +;@out A - A << D => A +SHLarith: + B :MSTORE(tmpVarB2) + C :MSTORE(tmpVarC2) + D :MSTORE(tmpVarD2) + E :MSTORE(tmpVarE2) + A => E + 0 => A + D => B + $ => B :EQ + 0 - B :JMPC(SHLarithfinal) + E => A + ${exp(2,D*8)} => B + ${A*B} => E + 32 - D => D :JMPC(SHLarith0) + ${exp(2,D*8)} => B + ${B-1} => B + $ => C :GT + 32 - D => D + ${exp(2,D*8)} => B + 0 - C :JMPC(SHLarithBig) + 0 => D,C + E :ARITH + :JMP(SHLarithfinal) + +SHLarith0: + 0 => E + :JMP(SHLarithfinal) + +SHLarithBig: + 32 - D => D + ${exp(2,D*8)} => D + ${A/D} => D + 0 => C + E :ARITH + +SHLarithfinal: + E => A + $ => B :MLOAD(tmpVarB2) + $ => C :MLOAD(tmpVarC2) + $ => D :MLOAD(tmpVarD2) + $ => E :MLOAD(tmpVarE2) + :JMP(RR) \ No newline at end of file