diff --git a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bitwise-simplification.k b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bitwise-simplification.k index 0bf1c666b9..e98733be3a 100644 --- a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bitwise-simplification.k +++ b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bitwise-simplification.k @@ -79,4 +79,25 @@ module BITWISE-SIMPLIFICATION [symbolic] rule 0 <=Int (X < true requires 0 <=Int X andBool 0 <=Int Y [simplification] + // ########################################################################### + // bit-xor + // ########################################################################### + + // Simplifications for the OpenZeppelin ternary operator function + + rule [xorInt-ge-zero]: + 0 <=Int X xorInt Y => true + requires 0 <=Int X andBool 0 <=Int Y + [simplification] + + rule [xorInt-lt]: + X xorInt Y true + requires 0 <=Int X andBool 0 <=Int Y andBool 0 #if B #then Y #else X #fi + [simplification] + endmodule diff --git a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bytes-simplification.k b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bytes-simplification.k index c7098ad2f9..392a50c6e9 100644 --- a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bytes-simplification.k +++ b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/bytes-simplification.k @@ -34,6 +34,12 @@ module BYTES-SIMPLIFICATION [symbolic] rule [bytes-concat-right-assoc-symb-r]: (B1:Bytes +Bytes B2:Bytes) +Bytes B3:Bytes => B1 +Bytes (B2 +Bytes B3) [symbolic(B2), simplification(40)] rule [bytes-concat-left-assoc-conc]: B1:Bytes +Bytes (B2:Bytes +Bytes B3:Bytes) => (B1 +Bytes B2) +Bytes B3 [concrete(B1, B2), symbolic(B3), simplification(40)] + // Can ignore lower bytes for #asWord ( B1 ) b"" requires N ==Int 0 [simplification] diff --git a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/int-simplification.k b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/int-simplification.k index 265be3c071..30e5663c47 100644 --- a/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/int-simplification.k +++ b/kevm-pyk/src/kevm_pyk/kproj/evm-semantics/lemmas/int-simplification.k @@ -96,11 +96,17 @@ module INT-SIMPLIFICATION-HASKELL [symbolic] rule { A +Int B #Equals C +Int B } => { A #Equals C } [simplification(40)] rule { A +Int B #Equals C +Int D } => { A -Int C #Equals D -Int B } [simplification(45), symbolic(A, C), concrete(B, D)] + rule 0 B B <=Int A [simplification, symbolic(A, B)] + rule A -Int B A A <=Int B [simplification, symbolic(A, B)] + endmodule module INT-SIMPLIFICATION-COMMON imports INT imports BOOL + imports WORD // ########################################################################### // add, sub @@ -148,6 +154,24 @@ module INT-SIMPLIFICATION-COMMON rule (E *Int A) +Int B +Int C +Int D +Int (F *Int A) => ((E +Int F) *Int A) +Int B +Int C +Int D [simplification] + // Simplification of concrete multiplication + + rule A *Int B B B <=Int C /Int A + requires 0 C /Int A <=Int B + requires 0 C /Int A 0 + requires 0 <=Int A + andBool 0 false requires D false requires 0 <=Int A andBool B true requires 0 <=Int X andBool notBool (X ==Int 0) [simplification(60)] + + rule X <=Int maxUInt256 => X (notBool B) andBool A [simplification] + rule [notBool-or]: notBool ( A orBool B ) => ( notBool A ) andBool ( notBool B ) [simplification(60)] + rule [notBool-and]: notBool ( A andBool B ) => ( notBool A ) orBool ( notBool B ) [simplification(60)] + endmodule diff --git a/tests/specs/functional/lemmas-spec.k b/tests/specs/functional/lemmas-spec.k index f6e6be53aa..cd28848940 100644 --- a/tests/specs/functional/lemmas-spec.k +++ b/tests/specs/functional/lemmas-spec.k @@ -90,6 +90,27 @@ module LEMMAS-SPEC ) ... requires 0 <=Int X andBool X runLemma ( ( A /Int B ) /Int 1024 ) => doneLemma ( 0 ) ... + requires 0 <=Int A andBool 0 runLemma ( + notBool ( ( X doneLemma ( + ( notBool ( X + + claim [notBool-and]: + runLemma ( + notBool ( ( LOWER <=Int X ) andBool ( X doneLemma ( + ( notBool ( LOWER <=Int X ) ) orBool ( notBool ( X // Comparisons // ----------- @@ -130,6 +151,34 @@ module LEMMAS-SPEC ) ... + claim [zero-lt-sub]: runLemma ( 0 doneLemma ( B + claim [zero-le-sub]: runLemma ( 0 <=Int A -Int B ) => doneLemma ( B <=Int A ) ... + claim [zero-gt-sub]: runLemma ( 0 >Int A -Int B ) => doneLemma ( B >Int A ) ... + claim [zero-ge-sub]: runLemma ( 0 >=Int A -Int B ) => doneLemma ( B >=Int A ) ... + + claim [sub-gt-zero]: runLemma ( A -Int B >Int 0 ) => doneLemma ( A >Int B ) ... + claim [sub-ge-zero]: runLemma ( A -Int B >=Int 0 ) => doneLemma ( A >=Int B ) ... + claim [sub-lt-zero]: runLemma ( A -Int B doneLemma ( A + claim [sub-le-zero]: runLemma ( A -Int B <=Int 0 ) => doneLemma ( A <=Int B ) ... + + claim [mul-lt-const]: runLemma ( 36 *Int B doneLemma ( B + claim [mul-le-const]: runLemma ( 36 *Int B <=Int 1728 ) => doneLemma ( B <=Int 48 ) ... + claim [mul-gt-const]: runLemma ( 36 *Int B >Int 1728 ) => doneLemma ( B >Int 48 ) ... + claim [mul-ge-const]: runLemma ( 36 *Int B >=Int 1728 ) => doneLemma ( B >=Int 48 ) ... + + claim [const-gt-mul]: runLemma ( 1728 >Int 36 *Int B ) => doneLemma ( 48 >Int B ) ... + claim [const-ge-mul]: runLemma ( 1728 >=Int 36 *Int B ) => doneLemma ( 48 >=Int B ) ... + claim [const-lt-mul]: runLemma ( 1728 doneLemma ( 48 + claim [const-le-mul]: runLemma ( 1728 <=Int 36 *Int B ) => doneLemma ( 48 <=Int B ) ... + + claim [eq-neg]: runLemma ( A ==Int -1 ) => doneLemma ( false ) ... + requires 0 <=Int A + + claim [nonneg-and-nonzero]: runLemma ( 0 doneLemma ( true ) ... + requires 0 <=Int X andBool notBool ( X ==Int 0 ) + + claim [le-maxuint256]: runLemma ( X <=Int maxUInt256 ) => doneLemma ( X + // Sets // ---- @@ -657,6 +706,12 @@ module LEMMAS-SPEC claim [shift-range]: runLemma ( #rangeUInt ( 256 , X < doneLemma ( true ) ... requires #rangeUInt ( 16 , X ) claim [shift-mod]: runLemma ( ( X < doneLemma ( X < requires #rangeUInt ( 16 , X ) + // xor + // ----- + + claim [xorInt-range]: runLemma ( #rangeUInt ( 256 , X xorInt Y ) ) => doneLemma ( true ) ... requires #rangeUInt ( 256 , X ) andBool #rangeUInt ( 256 , Y ) + claim [xorInt-to-if]: runLemma ( A xorInt ( bool2Word ( A <=Int B ) *Int ( A xorInt B ) ) ) => doneLemma ( #if ( A <=Int B ) #then B #else A #fi ) ... + // concat // ------ @@ -769,6 +824,13 @@ module LEMMAS-SPEC requires #asWord ( BA3 ) ==Int X modInt ( 2 ^Int ( 8 *Int lengthBytes ( BA3 ) ) ) andBool 0 runLemma ( + #asWord ( B1 +Bytes b"\xde\xad\xbe\xef" ) doneLemma ( + #asWord ( B1 ) + // bool2Word // ---------