ZKASM Proposals

inFREE0

$0{something} => A    ; A0 was a FF, A1..A7 = 0

verify_free_input

$ => C :MLOAD(myvar)
A + 3 * C => B 
; vs
A + 3 * myvar => B ; internament fa un MLOAD
A + 3 => myvar,B ; internament fa un MSTORE

useOpeAsParam & useConstAsParam

LT(constant), EQ(constant), ADD(constant), SUB(constant),

$ :EQ(0),JMPC(labelAis0)
$ :LT(100),JMPC(labelALT100)

OP_LT, OP_EQ, OP_SLT, OP_AND (only carry opretions)

D :OP_EQ(0),JMPC(labelDis0)
C :OP_LT(100),JMPC(labelCLT100)
D :OP_EQ,JMPC(labelDequalB)

carry operations: LT_OP, SLT_OP, EQ_OP, AND_OP

save_restore

fact:   
        :SAVE(B,C,D,RR)

        ; check if direct case (A == 1)
        1 => B
        $             :EQ,JMPC(fact_finish)

        ; store current value of A in C
        A => C

        ; call again to fact with A - 1
        $ => A        :SUB,CALL(fact)
        
        ; A * fact(A - 1)
        C => B
        0 => D,C
        ${A * B} => A :ARITH

fact_finish:        
        :RESTORE,RETURN

With this save and restore the return change because take next return address RR'. This means that something like it could be used.

$ => RR :MLOAD(tmpRR),RETURN

hash-bytes

        // hash 3 bytes of A
        3 => D
        A    :HASHK(E)
        
        // hash 1 byte of A
        A    :HASHK1(E)

        // hash-bytes static number of bytes
        A    :HASHK3(E)

        // with hash-bytes also continue using dynamic number of bytes
        4 => D
        A    :HASHK(E)

multi-indirection

In zkasm one address could be two parts, a static part and a dynamic or relative part. The ideas is that each instruction/part (mload/mstore, jmpAddr, elseAddr) has its own static part and has a flag to indicate if use relative part. If two instruction/part has same relative part they could share it. Also change ind and indE (flags to specify indirection) could be used as multiplier.

B :JMNZ(@label + 2*RR)
B :JMNZ(@label + RR)
B :JMPZ(labelZ, @labelNZ + E)  
B :JMPZ(@labelZ+ E, @labelNZ + E)  ; VALID, because the relative address is the same 
B :JMPZ(@labelZ+ 2*E, @labelNZ + E)  ; INVALID option, relative address isn't the same
B :JMPZ(@labelZ+ E, @labelNZ + RR)  ; INVALID options, relative address isn't the same
$ :HASHP(E), MLOAD(data)
$ :HASHP(E), MSTORE(data)
$ :HASHP(E), MLOAD(data), JMPZ(@label + RR, labelElse)
$ :MLOAD(matriz_20x30[E*30 + RR])

Also could be usefull the conditional calls.

other feature (evaluating)

  • free_bits
  • ASSERT_U32
  • LOOP_RR
  • MSET(fromAddr, toAddr, value)
  • MINC(constant_32bits)
  • MDEC(constant_32bits)
  • MCOPY(addr1, addr2) copy a word between positions