From fe12daa78b3b00862ce8d3ee98da7a38ca5937f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 24 Jan 2025 17:05:37 +0100 Subject: [PATCH 01/57] release: bump version to beta-v1.2.0-rc2 and update changelog --- CHANGELOG.md | 17 +++++++++++++++++ gradle.properties | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6e77c1650..39fb0fa82a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## beta-v1-2.0-rc2 +* Use both traceStartBlock method calls wherever suitable (#1711) +* Fix/refacto blockdata files (#1724) +* update `go-corset` to latest version (#1732) +* Update Linea Besu to 25.1-develop-448d1a9 (#1722) +* fix: update `go-corset` to latest (#1726) +* feat: go-corset front end integration (#1689) +* Improve the copy local Besu distribution archive when the download fails (#1720) +* Fix Java jars publication and remove redundant upload to Cloudsmith (#1716) +* Update actions/upload-artifact to v4 since v3 is deprecated and breaks CI (#1718) +* Tweak publish task (#1713) +* fix cloudsmith publish +* fix location of distribution for release (#1710) +* Add actions/checkout to release.yml (#1708) +* update `release` action to install `corset` (#1706) + + ## beta-v1.2.0-rc0 * Fix: ignore `Trace.java` files and `GlobalConstants.java` + recognize 'beta*' as release tag (#1703) * init chain id in zktracer. (#1702) diff --git a/gradle.properties b/gradle.properties index 8c7d78b9b5..a592e7c081 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -releaseVersion=beta-v1.2.0-rc0 +releaseVersion=beta-v1.2.0-rc2 besuVersion=25.1-develop-448d1a9 besuArtifactGroup=io.consensys.linea-besu distributionIdentifier=linea-tracer From 4dac4bcb4fa623bcddbd6c63eaf0da4b80586d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 5 Feb 2025 17:40:42 +0100 Subject: [PATCH 02/57] feat: "Happy Path" tests for SHA2/RIPE/ID --- .../InstructionDecoder.java | 2 +- .../callTests/Utilities.java | 72 +++++++++ .../callTests/prc/CallOffset.java | 21 +++ .../callTests/prc/CallSize.java | 21 +++ .../callTests/prc/HashPrecompile.java | 21 +++ .../callTests/prc/RelativeRangePosition.java | 20 +++ .../prc/sha2/OffsetHappyPathTests.java | 152 ++++++++++++++++++ 7 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallOffset.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallSize.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/RelativeRangePosition.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java index 0e35bc48f3..e1c7eed35d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java @@ -126,7 +126,7 @@ public void commit(List buffers) { traceStackSettings(op, trace); traceBillingSettings(op, trace); trace - .opcode(Bytes.ofUnsignedInt(i)) + .opcode(UnsignedByte.of(i)) .isPush(op.isPush()) .isJumpdest(op.isJumpDest()) .validateRow(); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 0a8251c20a..9768f52bd0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -15,8 +15,11 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests; import static com.google.common.base.Preconditions.checkArgument; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; +import java.util.List; + import net.consensys.linea.UnitTestWatcher; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.opcode.OpCode; @@ -124,4 +127,73 @@ public static void validEcrecoverData(BytecodeCompiler program) { .push(96) .op(MSTORE); } + + /** + * Populates memory with 6 words of data, namely + * + *

0x aa ... aa bb ... bb cc ... cc dd ... dd ee ... ee ff ... ff + * + *

starting at offset 0. This provides 192 = 6*32 nonzero bytes in RAM. + */ + public static void populateMemory(BytecodeCompiler program) { + populateMemory(program, 6, 0); + } + + public static void fullReturnDataCopyAt(BytecodeCompiler program, int targetOffset) { + program.op(RETURNDATASIZE).push(0).push(targetOffset); + } + + public static void partialReturnDataCopyAt(BytecodeCompiler program, int targetOffset) { + pushRdsOverArgOntoTheStack(program, 2); // source size ≡ rds/2 + pushRdsOverArgOntoTheStack(program, 3); // source offset ≡ rds/3 + program.push(targetOffset); + } + + public static void loadFirstReturnDataWordOntoStack(BytecodeCompiler program, int offset) { + squashMemoryWordAtOffset(program, offset); + pushMinOfRdsAnd32OntoStack(program); // leaves min(RDS, 32) on the stack + program.push(0).push(offset).op(RETURNDATACOPY).push(offset).op(MLOAD); + } + + public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { + program + .push(WORD_SIZE) + .op(RETURNDATASIZE) + .op(LT) // stack: [ c | ... [, where c ≡ [RDS < 32] + .op(DUP1) + .push(1) + .op(SUB) // stack: [ d | c | ... [, where d ≡ [RDS ≥ 32] + .push(WORD_SIZE) + .op(MUL) // stack: [ (d ? 32 : 0) | c | ... [ + .op(SWAP1) // stack: [ c | (d ? 32 : 0) | ... [ + .op(RETURNDATASIZE) + .op(MUL) // stack: [ (c ? RDS : 0) | (d ? 32 : 0) | ... [ + .op(ADD) // stack: [ min(RDS, 32) | ... [ + ; + } + + public static void squashMemoryWordAtOffset(BytecodeCompiler program, int offset) { + program.push(0).push(offset).op(MSTORE); + } + + public static void pushRdsOverArgOntoTheStack(BytecodeCompiler program, int arg) { + program.push(arg).op(RETURNDATASIZE).op(DIV); + } + + /** + * {@link #populateMemory} populates memory with nWords words chosen cyclically from 6 EVM + * words obtained by repeating the strings "aa", "bb", "cc", "dd", "ee", "ff" 32 times each. + * + * @param program + * @param nWords + */ + public static void populateMemory(BytecodeCompiler program, int nWords, int offset) { + List abcdef = List.of("aa", "bb", "cc", "dd", "ee", "ff"); + for (int i = 0; i < nWords; i++) { + program + .push(abcdef.get(i % abcdef.size()).repeat(WORD_SIZE)) // value, a 32 byte word + .push(offset + i * WORD_SIZE) // offset + .op(MSTORE); + } + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallOffset.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallOffset.java new file mode 100644 index 0000000000..cef68d6b2a --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallOffset.java @@ -0,0 +1,21 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum CallOffset { + ALIGNED, + MISALIGNED, + INFINITY +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallSize.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallSize.java new file mode 100644 index 0000000000..9a69a48d2c --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallSize.java @@ -0,0 +1,21 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum CallSize { + ZERO, + WORD, + OTHER +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java new file mode 100644 index 0000000000..80b1c5a6b2 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java @@ -0,0 +1,21 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum HashPrecompile { + SHA256, + RIPEMD160, + IDENTITY +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/RelativeRangePosition.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/RelativeRangePosition.java new file mode 100644 index 0000000000..a136a2da13 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/RelativeRangePosition.java @@ -0,0 +1,20 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum RelativeRangePosition { + DISJOINT, + OVERLAP +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java new file mode 100644 index 0000000000..b393e6b29c --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java @@ -0,0 +1,152 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.OVERLAP; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.accounts; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.testing.ToyAccount; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallOffset; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallSize; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.HashPrecompile; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +/** + * We test the interactions between the call data range, the return at range and + * return data ranges. For the present tests we will only consider the happy path i.e. + * + *

- always provide sufficient gas (thus ensuring scenario/PRC_SUCCESS) + * + *

- no REVERTs (so that value only matters in terms of pricing) + * + *

To avoid trivialities we make memory contain nonzero stuff. We will also include interactions + * between stack and memory. This will be done via RETURNDATA[SIZE/COPY] and MLOAD. We + * will consider both the disjoint case and the case where the call data range (CD0, CDS) and the + * "return at" range (R@O, R@C) overlap, as well as when the target range of the + * RETURNDATACOPY overlaps with these. + */ +public class OffsetHappyPathTests { + + @ParameterizedTest + @MethodSource("happyPathHashPrecompileParameters") + public void happyPathHashPrecompileTests( + OpCode callOpcode, + HashPrecompile precompile, + CallOffset cdo, + CallSize cds, + CallOffset rao, + CallSize rac, + RelativeRangePosition relPos) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + populateMemory(program); + appendHashPrecompileCall(program, callOpcode, precompile, cdo, cds, rao, rac, relPos); + partialReturnDataCopyAt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + BytecodeRunner.of(program.compile()).run(accounts); + } + + private static Stream happyPathHashPrecompileParameters() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + + List argumentsList = new ArrayList<>(); + for (CallSize rac : CallSize.values()) { + for (CallOffset rao : CallOffset.values()) { + for (CallSize cds : CallSize.values()) { + for (CallOffset cdo : CallOffset.values()) { + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + for (HashPrecompile precompile : HashPrecompile.values()) { + for (OpCode callOpcode : CallOpCodes) { + argumentsList.add( + Arguments.of( + callOpcode, precompile, cdo, cds, rao, rac, relPos)); + } + } + } + } + } + } + } + return argumentsList.stream(); + } + + public void appendHashPrecompileCall( + BytecodeCompiler program, + OpCode callOpcode, + HashPrecompile hashPrecompile, + CallOffset cdo, + CallSize cds, + CallOffset rao, + CallSize rac, + RelativeRangePosition relativeRangePosition) { + + // call data can occupy up to 52 bytes; it fits into the first 2 words + switch (cdo) { + case ALIGNED -> program.push(0); + case MISALIGNED -> program.push(13); + case INFINITY -> program.push("ff".repeat(32)); + } + + switch (cds) { + case ZERO -> program.push(0); + case WORD -> program.push(WORD_SIZE); + case OTHER -> program.push(39); + } + + // if DISJOINT the "return at range" lives among words 3 and 4 or RAM + switch (rao) { + case ALIGNED -> program.push(relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE); + case MISALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4); + case INFINITY -> program.push("ff".repeat(32)); + } + + switch (rac) { + case ZERO -> program.push(0); + case WORD -> program.push(WORD_SIZE); + case OTHER -> program.push(58); + } + + Address prcAddress = + switch (hashPrecompile) { + case SHA256 -> Address.SHA256; + case RIPEMD160 -> Address.RIPEMD160; + case IDENTITY -> Address.ID; + }; + program.push(prcAddress); + + if (callOpcode.callHasValueArgument()) { + program.push(1); + } + + program.op(GAS); + program.op(callOpcode); + } +} From 00ba52ed04d87fd894a54d49cbc57ebcf1fb2454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 5 Feb 2025 17:41:20 +0100 Subject: [PATCH 03/57] fix: constraints commit update --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index e0a8b82ef8..33578bedcf 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit e0a8b82ef8c43bff72c9924224b764398cc6ec3d +Subproject commit 33578bedcf1cd77b3ca59d8a0fdbbd3f897780e2 From 4e2b4856c41bb1e2be39bd0dd79b3ba1a7a43991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 5 Feb 2025 17:56:50 +0100 Subject: [PATCH 04/57] ras: documentation --- .../callTests/Utilities.java | 34 ++++++++++++++++--- .../prc/sha2/OffsetHappyPathTests.java | 4 +-- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 9768f52bd0..b626b113c0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -143,18 +143,34 @@ public static void fullReturnDataCopyAt(BytecodeCompiler program, int targetOffs program.op(RETURNDATASIZE).push(0).push(targetOffset); } - public static void partialReturnDataCopyAt(BytecodeCompiler program, int targetOffset) { + /** + * Copies 1 / 2 of the return data starting at offset RDS / 3 (internal to return data) into memory at targetOffset. + * @param program + * @param targetOffset + */ + public static void copyHalfOfReturnDataOmittingTheFirstThirdOfIt(BytecodeCompiler program, int targetOffset) { pushRdsOverArgOntoTheStack(program, 2); // source size ≡ rds/2 pushRdsOverArgOntoTheStack(program, 3); // source offset ≡ rds/3 program.push(targetOffset); } + /** + * Loads the (right 0 padded) first RDS ∧ 32 bytes from return data onto the stack. + * + *

Note. if RDS < 32. + * @param program + * @param offset + */ public static void loadFirstReturnDataWordOntoStack(BytecodeCompiler program, int offset) { squashMemoryWordAtOffset(program, offset); pushMinOfRdsAnd32OntoStack(program); // leaves min(RDS, 32) on the stack program.push(0).push(offset).op(RETURNDATACOPY).push(offset).op(MLOAD); } + /** + * Pushes the integer RDS ∧ 32 = min(RDS, 32) onto the stack. + * @param program + */ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { program .push(WORD_SIZE) @@ -162,7 +178,7 @@ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { .op(LT) // stack: [ c | ... [, where c ≡ [RDS < 32] .op(DUP1) .push(1) - .op(SUB) // stack: [ d | c | ... [, where d ≡ [RDS ≥ 32] + .op(SUB) // stack: [ d | c | ... [, where d ≡ ¬c ≡ [RDS ≥ 32] .push(WORD_SIZE) .op(MUL) // stack: [ (d ? 32 : 0) | c | ... [ .op(SWAP1) // stack: [ c | (d ? 32 : 0) | ... [ @@ -172,17 +188,27 @@ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { ; } + /** + * Squashes the word in memory at (byte)offset, i.e. replaces it with 0x 00 .. 00. + * @param program + * @param offset + */ public static void squashMemoryWordAtOffset(BytecodeCompiler program, int offset) { program.push(0).push(offset).op(MSTORE); } + /** + * Pushes RDS / arg onto the stack. + * @param program + * @param arg + */ public static void pushRdsOverArgOntoTheStack(BytecodeCompiler program, int arg) { program.push(arg).op(RETURNDATASIZE).op(DIV); } /** - * {@link #populateMemory} populates memory with nWords words chosen cyclically from 6 EVM - * words obtained by repeating the strings "aa", "bb", "cc", "dd", "ee", "ff" 32 times each. + * {@link #populateMemory} populates memory with nWords chosen cyclically from the set of 6 EVM + * words obtained by repeating the strings aa, bb, ..., ff 32 times. * * @param program * @param nWords diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java index b393e6b29c..5c03907fce 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java @@ -17,7 +17,6 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.OVERLAP; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.accounts; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -27,7 +26,6 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; -import net.consensys.linea.testing.ToyAccount; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallOffset; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallSize; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.HashPrecompile; @@ -69,7 +67,7 @@ public void happyPathHashPrecompileTests( populateMemory(program); appendHashPrecompileCall(program, callOpcode, precompile, cdo, cds, rao, rac, relPos); - partialReturnDataCopyAt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); BytecodeRunner.of(program.compile()).run(accounts); } From 9b3a5b4a1af6476a26fb8b892c222ce86e1ccf04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 5 Feb 2025 18:12:17 +0100 Subject: [PATCH 05/57] ras: documentation --- .../callTests/Utilities.java | 22 +++++++++---------- .../prc/sha2/OffsetHappyPathTests.java | 19 +++++++++------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index b626b113c0..90abf2b553 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -128,17 +128,6 @@ public static void validEcrecoverData(BytecodeCompiler program) { .op(MSTORE); } - /** - * Populates memory with 6 words of data, namely - * - *

0x aa ... aa bb ... bb cc ... cc dd ... dd ee ... ee ff ... ff - * - *

starting at offset 0. This provides 192 = 6*32 nonzero bytes in RAM. - */ - public static void populateMemory(BytecodeCompiler program) { - populateMemory(program, 6, 0); - } - public static void fullReturnDataCopyAt(BytecodeCompiler program, int targetOffset) { program.op(RETURNDATASIZE).push(0).push(targetOffset); } @@ -206,6 +195,17 @@ public static void pushRdsOverArgOntoTheStack(BytecodeCompiler program, int arg) program.push(arg).op(RETURNDATASIZE).op(DIV); } + /** + * Populates memory with 6 words of data, namely + * + *

0x aa ... aa bb ... bb cc ... cc dd ... dd ee ... ee ff ... ff + * + *

starting at offset 0. This provides 192 = 6*32 nonzero bytes in RAM. + */ + public static void populateMemory(BytecodeCompiler program) { + populateMemory(program, 6, 0); + } + /** * {@link #populateMemory} populates memory with nWords chosen cyclically from the set of 6 EVM * words obtained by repeating the strings aa, bb, ..., ff 32 times. diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java index 5c03907fce..5ce1cbf6b1 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java @@ -38,17 +38,21 @@ /** * We test the interactions between the call data range, the return at range and - * return data ranges. For the present tests we will only consider the happy path i.e. + * return data ranges for SHA2-256, RIPEMD-160 and IDENTITY. For the + * present tests we will only consider the happy path i.e. * *

- always provide sufficient gas (thus ensuring scenario/PRC_SUCCESS) * *

- no REVERTs (so that value only matters in terms of pricing) * - *

To avoid trivialities we make memory contain nonzero stuff. We will also include interactions - * between stack and memory. This will be done via RETURNDATA[SIZE/COPY] and MLOAD. We - * will consider both the disjoint case and the case where the call data range (CD0, CDS) and the - * "return at" range (R@O, R@C) overlap, as well as when the target range of the - * RETURNDATACOPY overlaps with these. + *

To avoid trivialities we pre-populate memory with nonzero values. We optionally force + * interactions between the call data range, the return at range and return + * data ranges. Indeed, we consider both the DISJOINT and the OVERLAP cases. I.e. + * the case where the call data range, the return at range as well as the return + * data overlaps with these. + * + *

We finally force interactions between stack and memory via RETURNDATA[SIZE/COPY] and + * MLOAD. */ public class OffsetHappyPathTests { @@ -84,8 +88,7 @@ private static Stream happyPathHashPrecompileParameters() { for (HashPrecompile precompile : HashPrecompile.values()) { for (OpCode callOpcode : CallOpCodes) { argumentsList.add( - Arguments.of( - callOpcode, precompile, cdo, cds, rao, rac, relPos)); + Arguments.of(callOpcode, precompile, cdo, cds, rao, rac, relPos)); } } } From 5810b58007ef2655b788de1d18cc92c2e0e2e9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 5 Feb 2025 18:29:43 +0100 Subject: [PATCH 06/57] ras: renaming + documentation --- ...java => HappyPathHashPrecompileTests.java} | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/{OffsetHappyPathTests.java => HappyPathHashPrecompileTests.java} (86%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java similarity index 86% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 5ce1cbf6b1..8c8621533e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/OffsetHappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -37,24 +37,21 @@ import org.junit.jupiter.params.provider.MethodSource; /** - * We test the interactions between the call data range, the return at range and - * return data ranges for SHA2-256, RIPEMD-160 and IDENTITY. For the - * present tests we will only consider the happy path i.e. + * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY, i.e. the + * present tests we will only consider calls to these precompiles where * - *

- always provide sufficient gas (thus ensuring scenario/PRC_SUCCESS) + *

- the precompile is provided with sufficient gas (ensuring scenario/PRC_SUCCESS) * - *

- no REVERTs (so that value only matters in terms of pricing) + *

- nothing REVERTs (thus value only matters in terms of pricing) * - *

To avoid trivialities we pre-populate memory with nonzero values. We optionally force + *

To avoid trivialities we pre-populate memory with nonzero values. We force * interactions between the call data range, the return at range and return - * data ranges. Indeed, we consider both the DISJOINT and the OVERLAP cases. I.e. - * the case where the call data range, the return at range as well as the return - * data overlaps with these. + * data ranges in the OVERLAP case. * - *

We finally force interactions between stack and memory via RETURNDATA[SIZE/COPY] and + *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and * MLOAD. */ -public class OffsetHappyPathTests { +public class HappyPathHashPrecompileTests { @ParameterizedTest @MethodSource("happyPathHashPrecompileParameters") From a6852844fb06191613b99eeab3976678a2190366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 6 Feb 2025 08:33:21 +0100 Subject: [PATCH 07/57] feat: the happy path tests now do more They now - produce return data via some precompile and play around with it - wipe said return data (and play around with it) - produce return data via some other precompile and play around with it --- .../callTests/prc/GasParameter.java | 23 ++++ .../callTests/prc/HashPrecompile.java | 37 +++++- .../sha2/HappyPathHashPrecompileTests.java | 120 +++++++++++++----- 3 files changed, 144 insertions(+), 36 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java new file mode 100644 index 0000000000..5fc59ec1a7 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java @@ -0,0 +1,23 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum GasParameter { + ZERO, + EXACT_MO, // MO ≡ minus one + EXACT, + EXACT_PO, // PO ≡ plus one + FULL, +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java index 80b1c5a6b2..cb82e972a0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java @@ -14,8 +14,43 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +import org.hyperledger.besu.datatypes.Address; + public enum HashPrecompile { SHA256, RIPEMD160, - IDENTITY + IDENTITY; + + public Address getAddress() { + Address address = switch (this) { + case SHA256 -> Address.SHA256; + case RIPEMD160 -> Address.RIPEMD160; + case IDENTITY -> Address.ID; + }; + return address; + } + + public HashPrecompile next() { + return switch (this) { + case SHA256 -> RIPEMD160; + case RIPEMD160 -> IDENTITY; + case IDENTITY -> SHA256; + }; + } + + public int smallOffset1() { + return switch (this) { + case SHA256 -> 1; + case RIPEMD160 -> 4; + case IDENTITY -> 2; + }; + } + + public int smallOffset2() { + return switch (this) { + case SHA256 -> 3; + case RIPEMD160 -> 8; + case IDENTITY -> 7; + }; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 8c8621533e..4d8233a950 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -14,9 +14,10 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; +import static com.google.common.base.Preconditions.checkArgument; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.OVERLAP; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.accounts; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -26,19 +27,17 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallOffset; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CallSize; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.HashPrecompile; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import net.consensys.linea.zktracer.opcode.OpCode; import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; /** - * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY, i.e. the - * present tests we will only consider calls to these precompiles where + * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY. The + * present tests pertain to precompile calls where * *

- the precompile is provided with sufficient gas (ensuring scenario/PRC_SUCCESS) * @@ -50,12 +49,16 @@ * *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and * MLOAD. + * + *

The tests do more: we then wipe the return data and start all over again with the next precompile. */ public class HappyPathHashPrecompileTests { + private final int otherCds = 39; + @ParameterizedTest @MethodSource("happyPathHashPrecompileParameters") - public void happyPathHashPrecompileTests( + public void happyPathWipeReturnDataHappyPathHashPrecompileTests( OpCode callOpcode, HashPrecompile precompile, CallOffset cdo, @@ -67,13 +70,31 @@ public void happyPathHashPrecompileTests( BytecodeCompiler program = BytecodeCompiler.newProgram(); populateMemory(program); - appendHashPrecompileCall(program, callOpcode, precompile, cdo, cds, rao, rac, relPos); + + // happy path 1 + appendHappyPathHashPrecompileCall(program, callOpcode, FULL, precompile, cdo, cds, rao, rac, relPos); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + + // return data wiping + appendInsufficientBalanceCall(program, callOpcode, 20_000, precompile.getAddress(), 1, 2, 3, 4); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + + // happy path 2 + appendHappyPathHashPrecompileCall(program, callOpcode, FULL, precompile.next(), cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - BytecodeRunner.of(program.compile()).run(accounts); + + BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); } - private static Stream happyPathHashPrecompileParameters() { + /** + * Generates test parameters for the happy path tests. + * + * @return Stream of test parameters + */ + public static Stream happyPathHashPrecompileParameters() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); @@ -96,9 +117,10 @@ private static Stream happyPathHashPrecompileParameters() { return argumentsList.stream(); } - public void appendHashPrecompileCall( + public void appendHappyPathHashPrecompileCall( BytecodeCompiler program, OpCode callOpcode, + GasParameter gasParameter, HashPrecompile hashPrecompile, CallOffset cdo, CallSize cds, @@ -106,45 +128,73 @@ public void appendHashPrecompileCall( CallSize rac, RelativeRangePosition relativeRangePosition) { - // call data can occupy up to 52 bytes; it fits into the first 2 words - switch (cdo) { - case ALIGNED -> program.push(0); - case MISALIGNED -> program.push(13); - case INFINITY -> program.push("ff".repeat(32)); - } - - switch (cds) { + // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM + switch (rac) { case ZERO -> program.push(0); case WORD -> program.push(WORD_SIZE); - case OTHER -> program.push(39); + case OTHER -> program.push(58); } - // if DISJOINT the "return at range" lives among words 3 and 4 or RAM switch (rao) { - case ALIGNED -> program.push(relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE); - case MISALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4); + case ALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + hashPrecompile.smallOffset1()); + case MISALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + hashPrecompile.smallOffset1()); case INFINITY -> program.push("ff".repeat(32)); } - switch (rac) { - case ZERO -> program.push(0); - case WORD -> program.push(WORD_SIZE); - case OTHER -> program.push(58); + // call data can occupy up to 52 bytes; it lives among words 0 and 1 of RAM + int callDataSize = + switch (cds) { + case ZERO -> 0; + case WORD -> WORD_SIZE; + case OTHER -> otherCds; + }; + program.push(callDataSize); + + switch (cdo) { + case ALIGNED -> program.push(0 + hashPrecompile.smallOffset2()); + case MISALIGNED -> program.push(13 + hashPrecompile.smallOffset2()); + case INFINITY -> program.push("ff".repeat(32)); } Address prcAddress = - switch (hashPrecompile) { - case SHA256 -> Address.SHA256; - case RIPEMD160 -> Address.RIPEMD160; - case IDENTITY -> Address.ID; - }; + switch (hashPrecompile) { + case SHA256 -> Address.SHA256; + case RIPEMD160 -> Address.RIPEMD160; + case IDENTITY -> Address.ID; + }; program.push(prcAddress); if (callOpcode.callHasValueArgument()) { program.push(1); } - program.op(GAS); + int cost = precompileCost(hashPrecompile, callDataSize); + switch (gasParameter) { + case ZERO -> program.push(0); + case EXACT_MO -> program.push( cost - 1); + case EXACT -> program.push(cost); + case EXACT_PO -> program.push(cost + 1); + case FULL -> program.op(GAS); + } + program.op(callOpcode); } + + private int precompileCost(HashPrecompile hashPrecompile, int callDataSize) { + int nWords = nWords(callDataSize); + return switch (hashPrecompile) { + case SHA256 -> 60 + 12 * nWords; + case RIPEMD160 -> 600 + 120 * nWords; + case IDENTITY -> 15 + 3 * nWords; + }; + } + + private int nWords(int sizeInBytes) { + checkArgument(sizeInBytes >= 0); + if (sizeInBytes == 0) { + return 0; + } else { + return (sizeInBytes + WORD_SIZE - 1) / WORD_SIZE; + } + } } From d256b86e4417a01a4f1c495cdc602c1102117c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 6 Feb 2025 08:53:20 +0100 Subject: [PATCH 08/57] ras: refactoring --- .../InstructionDecoder.java | 1 - .../callTests/Utilities.java | 17 ++-- .../callTests/prc/GasParameter.java | 10 +-- .../callTests/prc/HashPrecompile.java | 32 ++++++-- .../sha2/HappyPathHashPrecompileTests.java | 79 ++++++++----------- 5 files changed, 76 insertions(+), 63 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java index e1c7eed35d..947cbe4dd9 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/tables/instructionDecoder/InstructionDecoder.java @@ -28,7 +28,6 @@ import net.consensys.linea.zktracer.opcode.gas.BillingRate; import net.consensys.linea.zktracer.opcode.gas.MxpType; import net.consensys.linea.zktracer.types.UnsignedByte; -import org.apache.tuweni.bytes.Bytes; public final class InstructionDecoder implements Module { private static void traceFamily(OpCodeData op, Trace trace) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 90abf2b553..5d8091b86f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -133,11 +133,14 @@ public static void fullReturnDataCopyAt(BytecodeCompiler program, int targetOffs } /** - * Copies 1 / 2 of the return data starting at offset RDS / 3 (internal to return data) into memory at targetOffset. + * Copies 1 / 2 of the return data starting at offset RDS / 3 (internal to return + * data) into memory at targetOffset. + * * @param program * @param targetOffset */ - public static void copyHalfOfReturnDataOmittingTheFirstThirdOfIt(BytecodeCompiler program, int targetOffset) { + public static void copyHalfOfReturnDataOmittingTheFirstThirdOfIt( + BytecodeCompiler program, int targetOffset) { pushRdsOverArgOntoTheStack(program, 2); // source size ≡ rds/2 pushRdsOverArgOntoTheStack(program, 3); // source offset ≡ rds/3 program.push(targetOffset); @@ -146,7 +149,8 @@ public static void copyHalfOfReturnDataOmittingTheFirstThirdOfIt(BytecodeCompile /** * Loads the (right 0 padded) first RDS ∧ 32 bytes from return data onto the stack. * - *

Note. if RDS < 32. + *

Note. if RDS < 32. + * * @param program * @param offset */ @@ -158,6 +162,7 @@ public static void loadFirstReturnDataWordOntoStack(BytecodeCompiler program, in /** * Pushes the integer RDS ∧ 32 = min(RDS, 32) onto the stack. + * * @param program */ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { @@ -179,6 +184,7 @@ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { /** * Squashes the word in memory at (byte)offset, i.e. replaces it with 0x 00 .. 00. + * * @param program * @param offset */ @@ -188,6 +194,7 @@ public static void squashMemoryWordAtOffset(BytecodeCompiler program, int offset /** * Pushes RDS / arg onto the stack. + * * @param program * @param arg */ @@ -207,8 +214,8 @@ public static void populateMemory(BytecodeCompiler program) { } /** - * {@link #populateMemory} populates memory with nWords chosen cyclically from the set of 6 EVM - * words obtained by repeating the strings aa, bb, ..., ff 32 times. + * {@link #populateMemory} populates memory with nWords chosen cyclically from the set of 6 + * EVM words obtained by repeating the strings aa, bb, ..., ff 32 times. * * @param program * @param nWords diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java index 5fc59ec1a7..33d97a449a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java @@ -15,9 +15,9 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; public enum GasParameter { - ZERO, - EXACT_MO, // MO ≡ minus one - EXACT, - EXACT_PO, // PO ≡ plus one - FULL, + ZERO, + EXACT_MO, // MO ≡ minus one + EXACT, + EXACT_PO, // PO ≡ plus one + FULL, } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java index cb82e972a0..7400cdcde6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java @@ -14,6 +14,9 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +import static com.google.common.base.Preconditions.checkArgument; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + import org.hyperledger.besu.datatypes.Address; public enum HashPrecompile { @@ -22,11 +25,12 @@ public enum HashPrecompile { IDENTITY; public Address getAddress() { - Address address = switch (this) { - case SHA256 -> Address.SHA256; - case RIPEMD160 -> Address.RIPEMD160; - case IDENTITY -> Address.ID; - }; + Address address = + switch (this) { + case SHA256 -> Address.SHA256; + case RIPEMD160 -> Address.RIPEMD160; + case IDENTITY -> Address.ID; + }; return address; } @@ -53,4 +57,22 @@ public int smallOffset2() { case IDENTITY -> 7; }; } + + public int cost(int callDataSize) { + int nWords = nWords(callDataSize); + return switch (this) { + case SHA256 -> 60 + 12 * nWords; + case RIPEMD160 -> 600 + 120 * nWords; + case IDENTITY -> 15 + 3 * nWords; + }; + } + + private int nWords(int sizeInBytes) { + checkArgument(sizeInBytes >= 0); + if (sizeInBytes == 0) { + return 0; + } else { + return (sizeInBytes + WORD_SIZE - 1) / WORD_SIZE; + } + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 4d8233a950..b1b353e391 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -14,7 +14,6 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; -import static com.google.common.base.Preconditions.checkArgument; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; @@ -36,21 +35,21 @@ import org.junit.jupiter.params.provider.MethodSource; /** - * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY. The - * present tests pertain to precompile calls where + * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY. The present + * tests pertain to precompile calls where * *

- the precompile is provided with sufficient gas (ensuring scenario/PRC_SUCCESS) * *

- nothing REVERTs (thus value only matters in terms of pricing) * - *

To avoid trivialities we pre-populate memory with nonzero values. We force - * interactions between the call data range, the return at range and return - * data ranges in the OVERLAP case. + *

To avoid trivialities we pre-populate memory with nonzero values. We force interactions + * between the call data range, the return at range and return data ranges in + * the OVERLAP case. * - *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and - * MLOAD. + *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and MLOAD. * - *

The tests do more: we then wipe the return data and start all over again with the next precompile. + *

The tests do more: we then wipe the return data and start all over again with the next + * precompile. */ public class HappyPathHashPrecompileTests { @@ -72,7 +71,8 @@ public void happyPathWipeReturnDataHappyPathHashPrecompileTests( populateMemory(program); // happy path 1 - appendHappyPathHashPrecompileCall(program, callOpcode, FULL, precompile, cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall( + program, callOpcode, FULL, precompile, cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); @@ -82,7 +82,8 @@ public void happyPathWipeReturnDataHappyPathHashPrecompileTests( loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); // happy path 2 - appendHappyPathHashPrecompileCall(program, callOpcode, FULL, precompile.next(), cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall( + program, callOpcode, FULL, precompile.next(), cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); @@ -117,11 +118,11 @@ public static Stream happyPathHashPrecompileParameters() { return argumentsList.stream(); } - public void appendHappyPathHashPrecompileCall( + public void appendHappyPathPrecompileCall( BytecodeCompiler program, OpCode callOpcode, GasParameter gasParameter, - HashPrecompile hashPrecompile, + HashPrecompile precompile, CallOffset cdo, CallSize cds, CallOffset rao, @@ -136,42 +137,44 @@ public void appendHappyPathHashPrecompileCall( } switch (rao) { - case ALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + hashPrecompile.smallOffset1()); - case MISALIGNED -> program.push((relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + hashPrecompile.smallOffset1()); + case ALIGNED -> program.push( + (relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + precompile.smallOffset1()); + case MISALIGNED -> program.push( + (relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + precompile.smallOffset1()); case INFINITY -> program.push("ff".repeat(32)); } // call data can occupy up to 52 bytes; it lives among words 0 and 1 of RAM int callDataSize = - switch (cds) { - case ZERO -> 0; - case WORD -> WORD_SIZE; - case OTHER -> otherCds; - }; + switch (cds) { + case ZERO -> 0; + case WORD -> WORD_SIZE; + case OTHER -> otherCds; + }; program.push(callDataSize); switch (cdo) { - case ALIGNED -> program.push(0 + hashPrecompile.smallOffset2()); - case MISALIGNED -> program.push(13 + hashPrecompile.smallOffset2()); + case ALIGNED -> program.push(0 + precompile.smallOffset2()); + case MISALIGNED -> program.push(13 + precompile.smallOffset2()); case INFINITY -> program.push("ff".repeat(32)); } Address prcAddress = - switch (hashPrecompile) { - case SHA256 -> Address.SHA256; - case RIPEMD160 -> Address.RIPEMD160; - case IDENTITY -> Address.ID; - }; + switch (precompile) { + case SHA256 -> Address.SHA256; + case RIPEMD160 -> Address.RIPEMD160; + case IDENTITY -> Address.ID; + }; program.push(prcAddress); if (callOpcode.callHasValueArgument()) { program.push(1); } - int cost = precompileCost(hashPrecompile, callDataSize); + int cost = precompile.cost(callDataSize); switch (gasParameter) { case ZERO -> program.push(0); - case EXACT_MO -> program.push( cost - 1); + case EXACT_MO -> program.push(cost - 1); case EXACT -> program.push(cost); case EXACT_PO -> program.push(cost + 1); case FULL -> program.op(GAS); @@ -179,22 +182,4 @@ public void appendHappyPathHashPrecompileCall( program.op(callOpcode); } - - private int precompileCost(HashPrecompile hashPrecompile, int callDataSize) { - int nWords = nWords(callDataSize); - return switch (hashPrecompile) { - case SHA256 -> 60 + 12 * nWords; - case RIPEMD160 -> 600 + 120 * nWords; - case IDENTITY -> 15 + 3 * nWords; - }; - } - - private int nWords(int sizeInBytes) { - checkArgument(sizeInBytes >= 0); - if (sizeInBytes == 0) { - return 0; - } else { - return (sizeInBytes + WORD_SIZE - 1) / WORD_SIZE; - } - } } From 39178179e3459af3fadede59af1ccb6f0b4e3376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 6 Feb 2025 08:56:09 +0100 Subject: [PATCH 09/57] ras --- .../prc/sha2/HappyPathHashPrecompileTests.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index b1b353e391..63f9b1918b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -58,8 +58,8 @@ public class HappyPathHashPrecompileTests { @ParameterizedTest @MethodSource("happyPathHashPrecompileParameters") public void happyPathWipeReturnDataHappyPathHashPrecompileTests( - OpCode callOpcode, - HashPrecompile precompile, + OpCode call, + HashPrecompile prc, CallOffset cdo, CallSize cds, CallOffset rao, @@ -71,19 +71,17 @@ public void happyPathWipeReturnDataHappyPathHashPrecompileTests( populateMemory(program); // happy path 1 - appendHappyPathPrecompileCall( - program, callOpcode, FULL, precompile, cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall(program, call, FULL, prc, cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); // return data wiping - appendInsufficientBalanceCall(program, callOpcode, 20_000, precompile.getAddress(), 1, 2, 3, 4); + appendInsufficientBalanceCall(program, call, 20_000, prc.getAddress(), 1, 2, 3, 4); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); // happy path 2 - appendHappyPathPrecompileCall( - program, callOpcode, FULL, precompile.next(), cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall(program, call, FULL, prc.next(), cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); From 5668fc8f992868e786f5cb00c09014c7a1e5c465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 6 Feb 2025 08:59:00 +0100 Subject: [PATCH 10/57] ras --- .../prc/sha2/HappyPathHashPrecompileTests.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 63f9b1918b..8f971b9bfd 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -28,7 +28,6 @@ import net.consensys.linea.testing.BytecodeRunner; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import net.consensys.linea.zktracer.opcode.OpCode; -import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -125,7 +124,7 @@ public void appendHappyPathPrecompileCall( CallSize cds, CallOffset rao, CallSize rac, - RelativeRangePosition relativeRangePosition) { + RelativeRangePosition relPos) { // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM switch (rac) { @@ -136,9 +135,9 @@ public void appendHappyPathPrecompileCall( switch (rao) { case ALIGNED -> program.push( - (relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + precompile.smallOffset1()); + (relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + precompile.smallOffset1()); case MISALIGNED -> program.push( - (relativeRangePosition == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + precompile.smallOffset1()); + (relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + precompile.smallOffset1()); case INFINITY -> program.push("ff".repeat(32)); } @@ -157,18 +156,15 @@ public void appendHappyPathPrecompileCall( case INFINITY -> program.push("ff".repeat(32)); } - Address prcAddress = - switch (precompile) { - case SHA256 -> Address.SHA256; - case RIPEMD160 -> Address.RIPEMD160; - case IDENTITY -> Address.ID; - }; - program.push(prcAddress); + // push address + program.push(precompile.getAddress()); + // push value if required if (callOpcode.callHasValueArgument()) { program.push(1); } + // push gas parameter int cost = precompile.cost(callDataSize); switch (gasParameter) { case ZERO -> program.push(0); From 91aaaf895d42f516978af08b9ee2a03aeb9dd243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 6 Feb 2025 11:11:33 +0100 Subject: [PATCH 11/57] ras --- .../prc/sha2/HappyPathHashPrecompileTests.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 8f971b9bfd..0b946a88ad 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -69,8 +69,10 @@ public void happyPathWipeReturnDataHappyPathHashPrecompileTests( populateMemory(program); + // Note: we provide zero value, otherwise the precompile would receive a G_stipend = 2300 gas + // bonus, offsetting our gas cost computation // happy path 1 - appendHappyPathPrecompileCall(program, call, FULL, prc, cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall(program, call, FULL, 0, prc, cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); @@ -80,7 +82,7 @@ public void happyPathWipeReturnDataHappyPathHashPrecompileTests( loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); // happy path 2 - appendHappyPathPrecompileCall(program, call, FULL, prc.next(), cdo, cds, rao, rac, relPos); + appendHappyPathPrecompileCall(program, call, FULL, 0, prc.next(), cdo, cds, rao, rac, relPos); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); @@ -119,6 +121,7 @@ public void appendHappyPathPrecompileCall( BytecodeCompiler program, OpCode callOpcode, GasParameter gasParameter, + int value, HashPrecompile precompile, CallOffset cdo, CallSize cds, @@ -159,9 +162,8 @@ public void appendHappyPathPrecompileCall( // push address program.push(precompile.getAddress()); - // push value if required if (callOpcode.callHasValueArgument()) { - program.push(1); + program.push(value); } // push gas parameter From f2a2f5667194443a55c6172911f475ee09389c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 7 Feb 2025 00:43:22 +0100 Subject: [PATCH 12/57] feat: some refactoring --- .../prc/PrecompileCallParameters.java | 45 +++++ .../sha2/HappyPathHashPrecompileTests.java | 157 +++++++++++------- linea-constraints | 2 +- 3 files changed, 143 insertions(+), 61 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java new file mode 100644 index 0000000000..550d1267d6 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java @@ -0,0 +1,45 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +import net.consensys.linea.zktracer.opcode.OpCode; + +public class PrecompileCallParameters { + public final OpCode call; + public GasParameter gas; + public final HashPrecompile prc; + public int value; + public final CallOffset cdo; + public final CallSize cds; + public final CallOffset rao; + public final CallSize rac; + public final RelativeRangePosition relPos; + + public PrecompileCallParameters(OpCode call, GasParameter gas, HashPrecompile prc, int value, CallOffset cdo, CallSize cds, CallOffset rao, CallSize rac, RelativeRangePosition relPos) { + this.call = call; + this.gas = gas; + this.prc = prc; + this.value = value; + this.cdo = cdo; + this.cds = cds; + this.rao = rao; + this.rac = rac; + this.relPos = relPos; + } + + public PrecompileCallParameters next() { + return new PrecompileCallParameters(call, gas, prc.next(), value, cdo, cds, rao, rac, relPos); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 0b946a88ad..39e082687a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -17,6 +17,8 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -26,9 +28,12 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.testing.ToyTransaction; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; +import org.hyperledger.besu.ethereum.core.Transaction; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -49,44 +54,50 @@ * *

The tests do more: we then wipe the return data and start all over again with the next * precompile. + * + *

To give full details, we will test the following scenario which we call happy path + * precompile: + * + *

1. happy path precompile CALL + * + *

2. play with (precompile) return data + * + *

3. wipe return data + * + *

4. happy path + * + *

5. play with (precompile) return data + * + *

In various setups: in the root context of a MESSAGE_CALL_TRANSACTION or a + * CONTRACT_DEPLOYMENT_TRANSACTION, at depth 1 in a MESSAGE_CALL_FROM_ROOT, + * DURING_DEPLOYMENT or AFTER_DEPLOYMENT. */ public class HappyPathHashPrecompileTests { private final int otherCds = 39; + /** + * In the case where everything happens in the root context. + * + * @param params + */ @ParameterizedTest @MethodSource("happyPathHashPrecompileParameters") - public void happyPathWipeReturnDataHappyPathHashPrecompileTests( - OpCode call, - HashPrecompile prc, - CallOffset cdo, - CallSize cds, - CallOffset rao, - CallSize rac, - RelativeRangePosition relPos) { + public void happyPathPrecompileMessageCallTransactionTest(PrecompileCallParameters params) { - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - populateMemory(program); - - // Note: we provide zero value, otherwise the precompile would receive a G_stipend = 2300 gas - // bonus, offsetting our gas cost computation - // happy path 1 - appendHappyPathPrecompileCall(program, call, FULL, 0, prc, cdo, cds, rao, rac, relPos); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - - // return data wiping - appendInsufficientBalanceCall(program, call, 20_000, prc.getAddress(), 1, 2, 3, 4); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - - // happy path 2 - appendHappyPathPrecompileCall(program, call, FULL, 0, prc.next(), cdo, cds, rao, rac, relPos); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); + + Transaction deploymentTransaction = + ToyTransaction.builder() + .sender(userAccount) + .keyPair(keyPair) + .transactionType(TransactionType.FRONTIER) + .gasLimit(0xffffffL) + .payload(program.compile()) // init code + .value(Wei.of(1_000_000_000L)) + .build(); } /** @@ -98,15 +109,19 @@ public static Stream happyPathHashPrecompileParameters() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); - for (CallSize rac : CallSize.values()) { - for (CallOffset rao : CallOffset.values()) { - for (CallSize cds : CallSize.values()) { + for (OpCode callOpcode : CallOpCodes) { + for (GasParameter gas : GasParameter.values()) { + for (HashPrecompile precompile : HashPrecompile.values()) { for (CallOffset cdo : CallOffset.values()) { - for (RelativeRangePosition relPos : RelativeRangePosition.values()) { - for (HashPrecompile precompile : HashPrecompile.values()) { - for (OpCode callOpcode : CallOpCodes) { - argumentsList.add( - Arguments.of(callOpcode, precompile, cdo, cds, rao, rac, relPos)); + for (CallSize cds : CallSize.values()) { + for (CallOffset rao : CallOffset.values()) { + for (CallSize rac : CallSize.values()) { + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + argumentsList.add( + Arguments.of( + new PrecompileCallParameters( + callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos))); + } } } } @@ -118,57 +133,48 @@ public static Stream happyPathHashPrecompileParameters() { } public void appendHappyPathPrecompileCall( - BytecodeCompiler program, - OpCode callOpcode, - GasParameter gasParameter, - int value, - HashPrecompile precompile, - CallOffset cdo, - CallSize cds, - CallOffset rao, - CallSize rac, - RelativeRangePosition relPos) { + BytecodeCompiler program, PrecompileCallParameters params) { // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM - switch (rac) { + switch (params.rac) { case ZERO -> program.push(0); case WORD -> program.push(WORD_SIZE); case OTHER -> program.push(58); } - switch (rao) { + switch (params.rao) { case ALIGNED -> program.push( - (relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + precompile.smallOffset1()); + (params.relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + params.prc.smallOffset1()); case MISALIGNED -> program.push( - (relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + precompile.smallOffset1()); + (params.relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + params.prc.smallOffset1()); case INFINITY -> program.push("ff".repeat(32)); } // call data can occupy up to 52 bytes; it lives among words 0 and 1 of RAM int callDataSize = - switch (cds) { + switch (params.cds) { case ZERO -> 0; case WORD -> WORD_SIZE; case OTHER -> otherCds; }; program.push(callDataSize); - switch (cdo) { - case ALIGNED -> program.push(0 + precompile.smallOffset2()); - case MISALIGNED -> program.push(13 + precompile.smallOffset2()); + switch (params.cdo) { + case ALIGNED -> program.push(0 + params.prc.smallOffset2()); + case MISALIGNED -> program.push(13 + params.prc.smallOffset2()); case INFINITY -> program.push("ff".repeat(32)); } // push address - program.push(precompile.getAddress()); + program.push(params.prc.getAddress()); - if (callOpcode.callHasValueArgument()) { - program.push(value); + if (params.call.callHasValueArgument()) { + program.push(params.value); } // push gas parameter - int cost = precompile.cost(callDataSize); - switch (gasParameter) { + int cost = params.prc.cost(callDataSize); + switch (params.gas) { case ZERO -> program.push(0); case EXACT_MO -> program.push(cost - 1); case EXACT -> program.push(cost); @@ -176,6 +182,37 @@ public void appendHappyPathPrecompileCall( case FULL -> program.op(GAS); } - program.op(callOpcode); + program.op(params.call); + } + + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( + PrecompileCallParameters params) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + populateMemory(program); + + // Note: we provide zero value, otherwise the precompile would receive a G_stipend = 2300 gas + // bonus, offsetting our gas cost computation + // happy path 1 + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt( + program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + + // return data wiping + appendInsufficientBalanceCall( + program, params.call, 20_000, params.prc.getAddress(), 1, 2, 3, 4); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt( + program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + + // happy path 2 + appendHappyPathPrecompileCall(program, params.next()); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt( + program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); + loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); + + return program; } } diff --git a/linea-constraints b/linea-constraints index 33578bedcf..c2bf8fa169 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit 33578bedcf1cd77b3ca59d8a0fdbbd3f897780e2 +Subproject commit c2bf8fa169453319b753a8f1b4c06ef3ce30ba01 From 72a03dc02cab776c0657cad65e335825ecc09d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sun, 9 Feb 2025 19:10:27 +0100 Subject: [PATCH 13/57] ras: moved parameter generation + CONTRACT_DEPLOYMENT version of tests --- .../prc/PrecompileCallParameters.java | 31 +++++---- .../sha2/HappyPathHashPrecompileTests.java | 66 ++++++++----------- .../prc/sha2/ParameterGeneration.java | 61 +++++++++++++++++ 3 files changed, 109 insertions(+), 49 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java index 550d1267d6..656ee8540b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java @@ -27,17 +27,26 @@ public class PrecompileCallParameters { public final CallSize rac; public final RelativeRangePosition relPos; - public PrecompileCallParameters(OpCode call, GasParameter gas, HashPrecompile prc, int value, CallOffset cdo, CallSize cds, CallOffset rao, CallSize rac, RelativeRangePosition relPos) { - this.call = call; - this.gas = gas; - this.prc = prc; - this.value = value; - this.cdo = cdo; - this.cds = cds; - this.rao = rao; - this.rac = rac; - this.relPos = relPos; - } + public PrecompileCallParameters( + OpCode call, + GasParameter gas, + HashPrecompile prc, + int value, + CallOffset cdo, + CallSize cds, + CallOffset rao, + CallSize rac, + RelativeRangePosition relPos) { + this.call = call; + this.gas = gas; + this.prc = prc; + this.value = value; + this.cdo = cdo; + this.cds = cds; + this.rao = rao; + this.rac = rac; + this.relPos = relPos; + } public PrecompileCallParameters next() { return new PrecompileCallParameters(call, gas, prc.next(), value, cdo, cds, rao, rac, relPos); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 39e082687a..58d48476fd 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -15,25 +15,25 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2.ParameterGeneration.*; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; -import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.testing.ToyExecutionEnvironmentV2; import net.consensys.linea.testing.ToyTransaction; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.opcode.OpCode; import org.hyperledger.besu.datatypes.TransactionType; import org.hyperledger.besu.datatypes.Wei; import org.hyperledger.besu.ethereum.core.Transaction; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -76,19 +76,35 @@ public class HappyPathHashPrecompileTests { private final int otherCds = 39; + public static Stream happyPathHashPrecompileParameters() { + return ParameterGeneration.happyPathHashPrecompileParameters(); + } + /** - * In the case where everything happens in the root context. + * MESSAGE_CALL transaction case * * @param params */ @ParameterizedTest @MethodSource("happyPathHashPrecompileParameters") + @Tag("weekly") public void happyPathPrecompileMessageCallTransactionTest(PrecompileCallParameters params) { BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); + } + /** + * CONTRACT_DEPLOYMENT transaction case + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathHashPrecompileParameters") + @Tag("weekly") + public void happyPathPrecompileDeploymentTransactionTest(PrecompileCallParameters params) { + + BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); Transaction deploymentTransaction = ToyTransaction.builder() .sender(userAccount) @@ -98,38 +114,13 @@ public void happyPathPrecompileMessageCallTransactionTest(PrecompileCallParamete .payload(program.compile()) // init code .value(Wei.of(1_000_000_000L)) .build(); - } - /** - * Generates test parameters for the happy path tests. - * - * @return Stream of test parameters - */ - public static Stream happyPathHashPrecompileParameters() { - List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - - List argumentsList = new ArrayList<>(); - for (OpCode callOpcode : CallOpCodes) { - for (GasParameter gas : GasParameter.values()) { - for (HashPrecompile precompile : HashPrecompile.values()) { - for (CallOffset cdo : CallOffset.values()) { - for (CallSize cds : CallSize.values()) { - for (CallOffset rao : CallOffset.values()) { - for (CallSize rac : CallSize.values()) { - for (RelativeRangePosition relPos : RelativeRangePosition.values()) { - argumentsList.add( - Arguments.of( - new PrecompileCallParameters( - callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos))); - } - } - } - } - } - } - } - } - return argumentsList.stream(); + ToyExecutionEnvironmentV2.builder() + .transaction(deploymentTransaction) + .accounts(List.of(userAccount)) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); } public void appendHappyPathPrecompileCall( @@ -201,8 +192,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); // return data wiping - appendInsufficientBalanceCall( - program, params.call, 20_000, params.prc.getAddress(), 1, 2, 3, 4); + appendInsufficientBalanceCall(program, CALL, 20_000, params.prc.getAddress(), 1, 2, 3, 4); copyHalfOfReturnDataOmittingTheFirstThirdOfIt( program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java new file mode 100644 index 0000000000..edb2aa97d2 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java @@ -0,0 +1,61 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; + +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + +public class ParameterGeneration { + + /** + * Generates test parameters for the happy path tests. + * + * @return Stream of test parameters + */ + public static Stream happyPathHashPrecompileParameters() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + + List argumentsList = new ArrayList<>(); + for (OpCode callOpcode : CallOpCodes) { + for (GasParameter gas : GasParameter.values()) { + for (HashPrecompile precompile : HashPrecompile.values()) { + for (CallOffset cdo : CallOffset.values()) { + for (CallSize cds : CallSize.values()) { + for (CallOffset rao : CallOffset.values()) { + for (CallSize rac : CallSize.values()) { + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + argumentsList.add( + Arguments.of( + new PrecompileCallParameters( + callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos))); + } + } + } + } + } + } + } + } + return argumentsList.stream(); + } +} From 2969e20f2f1f5520065d22d2acd682f179a11270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Mon, 10 Feb 2025 18:54:18 +0100 Subject: [PATCH 14/57] feat: more tests --- .../callTests/Utilities.java | 74 +++++++ .../prc/PrecompileCallParameters.java | 7 +- .../sha2/HappyPathHashPrecompileTests.java | 198 ++++++++++++++---- .../prc/sha2/ParameterGeneration.java | 10 +- 4 files changed, 242 insertions(+), 47 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 5d8091b86f..60adbb71a1 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -229,4 +229,78 @@ public static void populateMemory(BytecodeCompiler program, int nWords, int offs .op(MSTORE); } } + + /** + * Appends byte code to the {@code program} that loads the first word of call data onto the stack + * and interprets it as an address like so: + * + *

[address | xx ... xx] + * + *

It then calls into this address. + * + * @param program + * @param callOpCode + */ + public static void appendCallToAddressInCallData(BytecodeCompiler program, OpCode callOpCode) { + checkArgument(callOpCode.isCall()); + + pushSeveral(program, 0, 0, 0, 0); + if (callOpCode.callHasValueArgument()) { + program.push(256); // value + } + callDataLoadFrom(program, 0); // [address | 00 ... 00], 12 zero bytes at the end + rightShiftTopOfStackToProduceAddress(program); // address + program.op(GAS).op(callOpCode); + } + + public static void copyForeignCodeAndRunItAsInitCode(BytecodeCompiler program, Address foreignAddress) { + + program.push(foreignAddress).op(EXTCODESIZE); // ] EXTCS ] + pushSeveral(program, 0, 0); // ] EXTCS | 0 | 0 ] + program.push(foreignAddress); // ] EXTCS | 0 | 0 | foreignAddress ] + program.op(EXTCODECOPY); + program.op(MSIZE); + pushSeveral(program, 0, 0); // ] MSIZE | 0 | 0 ] + program.op(CREATE); + } + + /** + * EXTCODECOPY's all of {@code foreignAddress}'s byte code and returns it. + * + * @param program + * @param foreignAddress + */ + public static void deployForeignCode(BytecodeCompiler program, Address foreignAddress) { + program.push(foreignAddress).op(EXTCODESIZE); // ] EXTCS ] + pushSeveral(program, 0, 0); + program.push(foreignAddress); // ] EXTCS | 0 | 0 | foreignAddress ] + program.op(EXTCODECOPY); // full copy of foreign code + program.op(MSIZE).push(0).op(RETURN); // return memory in full + } + + public static void sstoreTopOfStackTo(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(MSTORE); + } + + public static void sloadFrom(BytecodeCompiler program, int storageKey) { + program.push(storageKey).op(SLOAD); + } + + public static void rightShiftTopOfStackToProduceAddress(BytecodeCompiler program) { + program.push(8 * 12).op(SHR); + } + + public static void revertWith(BytecodeCompiler program, int offset, int size) { + program.push(size).push(offset).op(REVERT); + } + + public static void callDataLoadFrom(BytecodeCompiler program, int offset) { + program.push(offset).op(CALLDATALOAD); + } + + public static void pushSeveral(BytecodeCompiler program, int... values) { + for (int value : values) { + program.push(value); + } + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java index 656ee8540b..80c299c257 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java @@ -26,6 +26,7 @@ public class PrecompileCallParameters { public final CallOffset rao; public final CallSize rac; public final RelativeRangePosition relPos; + public final boolean willRevert; public PrecompileCallParameters( OpCode call, @@ -36,7 +37,8 @@ public PrecompileCallParameters( CallSize cds, CallOffset rao, CallSize rac, - RelativeRangePosition relPos) { + RelativeRangePosition relPos, + boolean willRevert) { this.call = call; this.gas = gas; this.prc = prc; @@ -46,9 +48,10 @@ public PrecompileCallParameters( this.rao = rao; this.rac = rac; this.relPos = relPos; + this.willRevert = willRevert; } public PrecompileCallParameters next() { - return new PrecompileCallParameters(call, gas, prc.next(), value, cdo, cds, rao, rac, relPos); + return new PrecompileCallParameters(call, gas, prc.next(), value, cdo, cds, rao, rac, relPos, willRevert); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 58d48476fd..b880c0d832 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -16,23 +16,19 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2.ParameterGeneration.*; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER; import java.util.List; import java.util.stream.Stream; -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.testing.BytecodeRunner; -import net.consensys.linea.testing.ToyExecutionEnvironmentV2; -import net.consensys.linea.testing.ToyTransaction; +import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import org.hyperledger.besu.datatypes.TransactionType; +import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; -import org.hyperledger.besu.ethereum.core.Transaction; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -58,26 +54,63 @@ *

To give full details, we will test the following scenario which we call happy path * precompile: * - *

1. happy path precompile CALL + *

- happy path precompile CALL * - *

2. play with (precompile) return data + *

- play with (precompile) return data * - *

3. wipe return data + *

- wipe return data * - *

4. happy path + *

- (different) happy path precompile CALL * - *

5. play with (precompile) return data + *

- play with (precompile) return data * - *

In various setups: in the root context of a MESSAGE_CALL_TRANSACTION or a - * CONTRACT_DEPLOYMENT_TRANSACTION, at depth 1 in a MESSAGE_CALL_FROM_ROOT, - * DURING_DEPLOYMENT or AFTER_DEPLOYMENT. + *

In various setups: + * + *

- at depth 0 in the root context of a MESSAGE_CALL_TRANSACTION + * + *

- at depth 0 in the root context of a CONTRACT_DEPLOYMENT_TRANSACTION + * + *

- at depth 1 in a MESSAGE_CALL_FROM_ROOT + * + *

- at depth 1 in a DURING_DEPLOYMENT + * + *

- at depth 1 in a AFTER_DEPLOYMENT */ public class HappyPathHashPrecompileTests { + final Address rootAddress = Address.fromHexString("7007"); + final ToyAccount.ToyAccountBuilder root = + ToyAccount.builder() + .address(rootAddress) + .balance(Wei.of(65536L)) + .nonce(1865); + + final Address chadPrcEnjoyerAddress = Address.fromHexString("cbad"); + final ToyAccount.ToyAccountBuilder chadPrcEnjoyer = + ToyAccount.builder() + .address(chadPrcEnjoyerAddress) + .balance(Wei.of(1024L)) + .nonce(64); + + final Address initCodeHolderAddress = Address.fromHexString("f00d"); + final ToyAccount.ToyAccountBuilder initCodeHolder = ToyAccount.builder() + .address(initCodeHolderAddress) + .balance(Wei.of(0x1337L)) + .nonce(127); + + final ToyTransaction.ToyTransactionBuilder transaction = + ToyTransaction.builder() + .sender(userAccount) + .keyPair(keyPair) + .transactionType(FRONTIER) + .gasLimit(0xffffffL) + .value(Wei.of(1_000_000_000L)); + + private final int otherCds = 39; - public static Stream happyPathHashPrecompileParameters() { - return ParameterGeneration.happyPathHashPrecompileParameters(); + public static Stream happyPathHashPrecompileParameterGeneration() { + return ParameterGeneration.happyPathHashPrecompileParameterGeneration(); } /** @@ -86,12 +119,12 @@ public static Stream happyPathHashPrecompileParameters() { * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameters") - @Tag("weekly") - public void happyPathPrecompileMessageCallTransactionTest(PrecompileCallParameters params) { - - BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); + @MethodSource("happyPathHashPrecompileParameterGeneration") + public void messageCallTransactionTest(PrecompileCallParameters params) { + if (!params.willRevert) { + BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); + BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); + } } /** @@ -100,29 +133,112 @@ public void happyPathPrecompileMessageCallTransactionTest(PrecompileCallParamete * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameters") - @Tag("weekly") - public void happyPathPrecompileDeploymentTransactionTest(PrecompileCallParameters params) { - - BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); - Transaction deploymentTransaction = - ToyTransaction.builder() - .sender(userAccount) - .keyPair(keyPair) - .transactionType(TransactionType.FRONTIER) - .gasLimit(0xffffffL) - .payload(program.compile()) // init code - .value(Wei.of(1_000_000_000L)) - .build(); + @MethodSource("happyPathHashPrecompileParameterGeneration") + public void deploymentTransactionTest(PrecompileCallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 0); + + transaction.payload(txInitCode.compile()); // init code ToyExecutionEnvironmentV2.builder() - .transaction(deploymentTransaction) + .transaction(transaction.build()) .accounts(List.of(userAccount)) .zkTracerValidator(zkTracer -> {}) .build() .run(); } + /** + * MESSAGE_CALL_FROM_ROOT case: + *

- the transaction is a MESSAGE_CALL targeting {@code callDataAddressCaller} + *

- the ROOT contract is therefore {@code callDataAddressCaller} + *

- the ROOT calls the {@code chadPrcEnjoyer} contract which executes the happy path + *

- the ROOT optionally reverts + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathHashPrecompileParameterGeneration") + public void messageCallFromRootTest(PrecompileCallParameters params) { + + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + appendCallToAddressInCallData(rootCode, CALL); + if (params.willRevert) revertWith(rootCode, 0, 0); // we let the ROOT revert + + root.code(rootCode.compile()); + + BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); + chadPrcEnjoyer.code(chadPrcEnjoyerCode.compile()); + + transaction + .to(root.build()) + .payload(chadPrcEnjoyerAddress); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + /** + * The {@link #root} contract fully copies the code of the account whose address is in the {@link #transaction} call data. + * This account is the {@link #chadPrcEnjoyer}. That code is then used as the initialization code of a CREATE. + * The whole operation optionally REVERT's. + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathHashPrecompileParameterGeneration") + public void happyPathDuringCreate(PrecompileCallParameters params) { + + BytecodeCompiler useForeignCodeAsInitCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(useForeignCodeAsInitCode, chadPrcEnjoyerAddress); + if (params.willRevert) revertWith(useForeignCodeAsInitCode, 0, 0); + + root.code(useForeignCodeAsInitCode.compile()); + + chadPrcEnjoyer.code(happyPathWipeReturnDataHappyPathProgram(params).compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + @ParameterizedTest + @MethodSource("happyPathHashPrecompileParameterGeneration") + public void happyPathAfterCreate(PrecompileCallParameters params) { + + chadPrcEnjoyer.code(happyPathWipeReturnDataHappyPathProgram(params).compile()); + + BytecodeCompiler foreignByteCodeDeployer = BytecodeCompiler.newProgram(); + deployForeignCode(foreignByteCodeDeployer, chadPrcEnjoyerAddress); + initCodeHolder.code(foreignByteCodeDeployer.compile()); + + int key = 65537; // 0x 01 00 01 + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(rootCode, initCodeHolderAddress); + sstoreTopOfStackTo(rootCode, key); // store deployment address + pushSeveral(rootCode, 0, 0, 0, 0, 1); + sloadFrom(rootCode, key); + rootCode.op(GAS).op(CALL); // call the deployed contract + if (params.willRevert) revertWith(rootCode, 0, 0); + + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build(), initCodeHolder.build())) + .transaction(transaction.build()) + .build() + .run(); + } + public void appendHappyPathPrecompileCall( BytecodeCompiler program, PrecompileCallParameters params) { @@ -156,13 +272,13 @@ public void appendHappyPathPrecompileCall( case INFINITY -> program.push("ff".repeat(32)); } - // push address - program.push(params.prc.getAddress()); - if (params.call.callHasValueArgument()) { program.push(params.value); } + // push address + program.push(params.prc.getAddress()); + // push gas parameter int cost = params.prc.cost(callDataSize); switch (params.gas) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java index edb2aa97d2..9f614c7b38 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java @@ -32,7 +32,7 @@ public class ParameterGeneration { * * @return Stream of test parameters */ - public static Stream happyPathHashPrecompileParameters() { + public static Stream happyPathHashPrecompileParameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); @@ -45,9 +45,11 @@ public static Stream happyPathHashPrecompileParameters() { for (CallSize rac : CallSize.values()) { for (RelativeRangePosition relPos : RelativeRangePosition.values()) { argumentsList.add( - Arguments.of( - new PrecompileCallParameters( - callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos))); + Arguments.of( + new PrecompileCallParameters( + callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos, true), + new PrecompileCallParameters( + callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos, false))); } } } From 605fb382d9bcb8ca60e172c31070f92a9dde454d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 11 Feb 2025 15:50:11 +0100 Subject: [PATCH 15/57] feat: extracted methods for running code by different means These means are: - as init code of a MESSAGE_CALL transaction - as init code of a CONTRACT_DEPLOYMENT transaction - as a message call emanating from ROOT - as the init code of a CREATE launched from the ROOT - as the deployed code of a deployment done by ROOT --- .../callTests/Utilities.java | 19 +- .../prc/PrecompileCallParameters.java | 13 +- .../callTests/prc/ValueParameter.java | 21 ++ .../sha2/HappyPathHashPrecompileTests.java | 263 +++++++++++------- .../prc/sha2/ParameterGeneration.java | 36 ++- 5 files changed, 233 insertions(+), 119 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ValueParameter.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 60adbb71a1..98ab7bf36e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -241,22 +241,27 @@ public static void populateMemory(BytecodeCompiler program, int nWords, int offs * @param program * @param callOpCode */ - public static void appendCallToAddressInCallData(BytecodeCompiler program, OpCode callOpCode) { + public static void appendCallTo(BytecodeCompiler program, OpCode callOpCode, Address address) { checkArgument(callOpCode.isCall()); pushSeveral(program, 0, 0, 0, 0); if (callOpCode.callHasValueArgument()) { program.push(256); // value } - callDataLoadFrom(program, 0); // [address | 00 ... 00], 12 zero bytes at the end - rightShiftTopOfStackToProduceAddress(program); // address - program.op(GAS).op(callOpCode); + program.push(address).op(GAS).op(callOpCode); } - public static void copyForeignCodeAndRunItAsInitCode(BytecodeCompiler program, Address foreignAddress) { + /** + * Performs a full copy of the code at {@code foreignAddress} and runs it as initialization code. + * + * @param program + * @param foreignAddress + */ + public static void copyForeignCodeAndRunItAsInitCode( + BytecodeCompiler program, Address foreignAddress) { program.push(foreignAddress).op(EXTCODESIZE); // ] EXTCS ] - pushSeveral(program, 0, 0); // ] EXTCS | 0 | 0 ] + pushSeveral(program, 0, 0); program.push(foreignAddress); // ] EXTCS | 0 | 0 | foreignAddress ] program.op(EXTCODECOPY); program.op(MSIZE); @@ -270,7 +275,7 @@ public static void copyForeignCodeAndRunItAsInitCode(BytecodeCompiler program, A * @param program * @param foreignAddress */ - public static void deployForeignCode(BytecodeCompiler program, Address foreignAddress) { + public static void copyForeignCodeAndReturnIt(BytecodeCompiler program, Address foreignAddress) { program.push(foreignAddress).op(EXTCODESIZE); // ] EXTCS ] pushSeveral(program, 0, 0); program.push(foreignAddress); // ] EXTCS | 0 | 0 | foreignAddress ] diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java index 80c299c257..6edfe80466 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java @@ -20,7 +20,7 @@ public class PrecompileCallParameters { public final OpCode call; public GasParameter gas; public final HashPrecompile prc; - public int value; + public ValueParameter value; public final CallOffset cdo; public final CallSize cds; public final CallOffset rao; @@ -32,7 +32,7 @@ public PrecompileCallParameters( OpCode call, GasParameter gas, HashPrecompile prc, - int value, + ValueParameter value, CallOffset cdo, CallSize cds, CallOffset rao, @@ -52,6 +52,13 @@ public PrecompileCallParameters( } public PrecompileCallParameters next() { - return new PrecompileCallParameters(call, gas, prc.next(), value, cdo, cds, rao, rac, relPos, willRevert); + return new PrecompileCallParameters( + call, gas, prc.next(), value, cdo, cds, rao, rac, relPos, willRevert); + } + + public final boolean willMxpx() { + final boolean callDataMxpx = (cds != CallSize.ZERO) && (cdo == CallOffset.INFINITY); + final boolean returnAtMxpx = (rac != CallSize.ZERO) && (rao == CallOffset.INFINITY); + return callDataMxpx || returnAtMxpx; } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ValueParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ValueParameter.java new file mode 100644 index 0000000000..fc82d57ecd --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ValueParameter.java @@ -0,0 +1,21 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum ValueParameter { + ZERO, + ONE, + VALUE +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index b880c0d832..29ab98e8f0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -29,7 +29,6 @@ import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -80,37 +79,30 @@ public class HappyPathHashPrecompileTests { final Address rootAddress = Address.fromHexString("7007"); final ToyAccount.ToyAccountBuilder root = - ToyAccount.builder() - .address(rootAddress) - .balance(Wei.of(65536L)) - .nonce(1865); + ToyAccount.builder().address(rootAddress).balance(Wei.of(65536L)).nonce(1865); final Address chadPrcEnjoyerAddress = Address.fromHexString("cbad"); final ToyAccount.ToyAccountBuilder chadPrcEnjoyer = - ToyAccount.builder() - .address(chadPrcEnjoyerAddress) - .balance(Wei.of(1024L)) - .nonce(64); + ToyAccount.builder().address(chadPrcEnjoyerAddress).balance(Wei.of(1024L)).nonce(64); - final Address initCodeHolderAddress = Address.fromHexString("f00d"); - final ToyAccount.ToyAccountBuilder initCodeHolder = ToyAccount.builder() - .address(initCodeHolderAddress) - .balance(Wei.of(0x1337L)) - .nonce(127); - - final ToyTransaction.ToyTransactionBuilder transaction = - ToyTransaction.builder() - .sender(userAccount) - .keyPair(keyPair) - .transactionType(FRONTIER) - .gasLimit(0xffffffL) - .value(Wei.of(1_000_000_000L)); + final Address initCodeOwnerAddress = Address.fromHexString("1717"); + final ToyAccount.ToyAccountBuilder initCodeOwner = + ToyAccount.builder().address(initCodeOwnerAddress).balance(Wei.of(0x1337L)).nonce(127); + final Address foreignCodeOwnerAddress = Address.fromHexString("f00d"); + final ToyAccount.ToyAccountBuilder foreignCodeOwner = + ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); - private final int otherCds = 39; - - public static Stream happyPathHashPrecompileParameterGeneration() { - return ParameterGeneration.happyPathHashPrecompileParameterGeneration(); + final ToyTransaction.ToyTransactionBuilder transaction = + ToyTransaction.builder() + .sender(userAccount) + .keyPair(keyPair) + .transactionType(FRONTIER) + .gasLimit(0xffffffL) + .value(Wei.of(1_000_000_000L)); + + public static Stream happyPathParameterGeneration() { + return ParameterGeneration.happyPathParameterGeneration(); } /** @@ -119,11 +111,11 @@ public static Stream happyPathHashPrecompileParameterGeneration() { * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameterGeneration") + @MethodSource("happyPathParameterGeneration") public void messageCallTransactionTest(PrecompileCallParameters params) { if (!params.willRevert) { - BytecodeCompiler program = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(program.compile()).run(Wei.fromEth(1), 61_000_000L); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + BytecodeRunner.of(rootCode.compile()).run(Wei.fromEth(1), 61_000_000L); } } @@ -133,110 +125,60 @@ public void messageCallTransactionTest(PrecompileCallParameters params) { * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameterGeneration") + @MethodSource("happyPathParameterGeneration") public void deploymentTransactionTest(PrecompileCallParameters params) { BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); if (params.willRevert) revertWith(txInitCode, 0, 0); - transaction.payload(txInitCode.compile()); // init code - - ToyExecutionEnvironmentV2.builder() - .transaction(transaction.build()) - .accounts(List.of(userAccount)) - .zkTracerValidator(zkTracer -> {}) - .build() - .run(); + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); } /** * MESSAGE_CALL_FROM_ROOT case: + * *

- the transaction is a MESSAGE_CALL targeting {@code callDataAddressCaller} + * *

- the ROOT contract is therefore {@code callDataAddressCaller} + * *

- the ROOT calls the {@code chadPrcEnjoyer} contract which executes the happy path + * *

- the ROOT optionally reverts * * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameterGeneration") + @MethodSource("happyPathParameterGeneration") public void messageCallFromRootTest(PrecompileCallParameters params) { - - BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); - appendCallToAddressInCallData(rootCode, CALL); - if (params.willRevert) revertWith(rootCode, 0, 0); // we let the ROOT revert - - root.code(rootCode.compile()); - BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); - chadPrcEnjoyer.code(chadPrcEnjoyerCode.compile()); - - transaction - .to(root.build()) - .payload(chadPrcEnjoyerAddress); - - ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) - .transaction(transaction.build()) - .build() - .run(); + runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); } /** - * The {@link #root} contract fully copies the code of the account whose address is in the {@link #transaction} call data. - * This account is the {@link #chadPrcEnjoyer}. That code is then used as the initialization code of a CREATE. - * The whole operation optionally REVERT's. + * The {@link #root} contract fully copies the code of the account whose address is in the {@link + * #transaction} call data. This account is the {@link #chadPrcEnjoyer}. That code is then used as + * the initialization code of a CREATE. The whole operation optionally REVERT's. + * * @param params */ @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameterGeneration") + @MethodSource("happyPathParameterGeneration") public void happyPathDuringCreate(PrecompileCallParameters params) { - BytecodeCompiler useForeignCodeAsInitCode = BytecodeCompiler.newProgram(); - copyForeignCodeAndRunItAsInitCode(useForeignCodeAsInitCode, chadPrcEnjoyerAddress); - if (params.willRevert) revertWith(useForeignCodeAsInitCode, 0, 0); - - root.code(useForeignCodeAsInitCode.compile()); - - chadPrcEnjoyer.code(happyPathWipeReturnDataHappyPathProgram(params).compile()); - - transaction.to(root.build()); - - ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) - .transaction(transaction.build()) - .build() - .run(); + if (!params.willMxpx()) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + } } @ParameterizedTest - @MethodSource("happyPathHashPrecompileParameterGeneration") + @MethodSource("happyPathParameterGeneration") public void happyPathAfterCreate(PrecompileCallParameters params) { - chadPrcEnjoyer.code(happyPathWipeReturnDataHappyPathProgram(params).compile()); - - BytecodeCompiler foreignByteCodeDeployer = BytecodeCompiler.newProgram(); - deployForeignCode(foreignByteCodeDeployer, chadPrcEnjoyerAddress); - initCodeHolder.code(foreignByteCodeDeployer.compile()); - - int key = 65537; // 0x 01 00 01 - BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); - copyForeignCodeAndRunItAsInitCode(rootCode, initCodeHolderAddress); - sstoreTopOfStackTo(rootCode, key); // store deployment address - pushSeveral(rootCode, 0, 0, 0, 0, 1); - sloadFrom(rootCode, key); - rootCode.op(GAS).op(CALL); // call the deployed contract - if (params.willRevert) revertWith(rootCode, 0, 0); - - root.code(rootCode.compile()); - - transaction.to(root.build()); - - ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build(), initCodeHolder.build())) - .transaction(transaction.build()) - .build() - .run(); + if (!params.willMxpx()) { + BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(chadPrcEnjoyerCode, params.willRevert); + } } public void appendHappyPathPrecompileCall( @@ -262,7 +204,7 @@ public void appendHappyPathPrecompileCall( switch (params.cds) { case ZERO -> 0; case WORD -> WORD_SIZE; - case OTHER -> otherCds; + case OTHER -> 43; }; program.push(callDataSize); @@ -273,7 +215,11 @@ public void appendHappyPathPrecompileCall( } if (params.call.callHasValueArgument()) { - program.push(params.value); + switch (params.value) { + case ZERO -> program.push(0); + case ONE -> program.push(1); + case VALUE -> program.push("69"); + } } // push address @@ -321,4 +267,115 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( return program; } + + public void runDeploymentTransactionWithProvidedCodeAsInitCode( + BytecodeCompiler transactionInitCode) { + + transaction.payload(transactionInitCode.compile()); // init code + + ToyExecutionEnvironmentV2.builder() + .transaction(transaction.build()) + .accounts(List.of(userAccount)) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); + } + + /** + * We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code. We provide + * {@link #root} with byte code that copies the code of {@link #foreignCodeOwnerAddress} and runs + * it as initialization code. {@link #root} optionally reverts. + * + * @param foreignCode + * @param embedRevertIntoInitCode + */ + public void runForeignByteCodeAsInitCode( + BytecodeCompiler foreignCode, boolean embedRevertIntoInitCode) { + + foreignCodeOwner.code(foreignCode.compile()); + + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(rootCode, foreignCodeOwnerAddress); + if (embedRevertIntoInitCode) revertWith(rootCode, 0, 0); + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), foreignCodeOwner.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + /** + * {@link #chadPrcEnjoyer} is given {@code providedCode} as its byte code. The {@code root} of the + * transaction calls {@link #chadPrcEnjoyer}. It then optionally reverts. + * + * @param providedCode + * @param revertRoot + */ + public void runMessageCallToAccountEndowedWithProvidedCode( + BytecodeCompiler providedCode, boolean revertRoot) { + + chadPrcEnjoyer.code(providedCode.compile()); + + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + appendCallTo(rootCode, CALL, chadPrcEnjoyerAddress); + if (revertRoot) revertWith(rootCode, 0, 0); // we let the ROOT revert + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + /** + * - We provide {@link #root} with byte code that (a) copies {@link #initCodeOwner}'s code + * and runs it as the init code of a CREATE (b) CALL's into the newly + * deployed contract (c) and optionally reverts. + * + *

- We provide {@link #initCodeOwner} with byte code that copies the code of {@link + * #foreignCodeOwnerAddress} and RETURN's it. + * + *

- We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code. + * + * @param foreignCode + * @param rootReverts + */ + public void runCreateDeployingForeignCodeAndCallIntoIt( + BytecodeCompiler foreignCode, boolean rootReverts) { + + // ROOT code + int key = 65537; // 0x 01 00 01 + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(rootCode, initCodeOwnerAddress); + sstoreTopOfStackTo(rootCode, key); // store deployment address + pushSeveral(rootCode, 0, 0, 0, 0, 0); // zero value + sloadFrom(rootCode, key); + rootCode.op(GAS).op(CALL); // call the deployed contract + if (rootReverts) revertWith(rootCode, 0, 0); + root.code(rootCode.compile()); + + // init code owner code + BytecodeCompiler initCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndReturnIt(initCode, foreignCodeOwnerAddress); + initCodeOwner.code(initCode.compile()); + + // foreign code owner code + foreignCodeOwner.code(foreignCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts( + List.of(userAccount, root.build(), foreignCodeOwner.build(), initCodeOwner.build())) + .transaction(transaction.build()) + .build() + .run(); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java index 9f614c7b38..525744ce99 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java @@ -30,9 +30,11 @@ public class ParameterGeneration { /** * Generates test parameters for the happy path tests. * + *

Note. We provide zero value. We thus avoid having to account for the G_callstipend. + * * @return Stream of test parameters */ - public static Stream happyPathHashPrecompileParameterGeneration() { + public static Stream happyPathParameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); @@ -44,12 +46,34 @@ public static Stream happyPathHashPrecompileParameterGeneration() { for (CallOffset rao : CallOffset.values()) { for (CallSize rac : CallSize.values()) { for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + + // adding PrecompileCallParameters + argumentsList.add( + Arguments.of( + new PrecompileCallParameters( + callOpcode, + gas, + precompile, + ValueParameter.ZERO, + cdo, + cds, + rao, + rac, + relPos, + true))); argumentsList.add( - Arguments.of( - new PrecompileCallParameters( - callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos, true), - new PrecompileCallParameters( - callOpcode, gas, precompile, 1, cdo, cds, rao, rac, relPos, false))); + Arguments.of( + new PrecompileCallParameters( + callOpcode, + gas, + precompile, + ValueParameter.ZERO, + cdo, + cds, + rao, + rac, + relPos, + false))); } } } From 93ea5daa97cc2587714f0c0c9db1ec8f7407b707 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 11 Feb 2025 16:06:25 +0100 Subject: [PATCH 16/57] ras --- .../sha2/HappyPathHashPrecompileTests.java | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java index 29ab98e8f0..4052570bc4 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java @@ -135,15 +135,7 @@ public void deploymentTransactionTest(PrecompileCallParameters params) { } /** - * MESSAGE_CALL_FROM_ROOT case: - * - *

- the transaction is a MESSAGE_CALL targeting {@code callDataAddressCaller} - * - *

- the ROOT contract is therefore {@code callDataAddressCaller} - * - *

- the ROOT calls the {@code chadPrcEnjoyer} contract which executes the happy path - * - *

- the ROOT optionally reverts + * MESSAGE_CALL_FROM_ROOT case. * * @param params */ @@ -209,7 +201,7 @@ public void appendHappyPathPrecompileCall( program.push(callDataSize); switch (params.cdo) { - case ALIGNED -> program.push(0 + params.prc.smallOffset2()); + case ALIGNED -> program.push(params.prc.smallOffset2()); case MISALIGNED -> program.push(13 + params.prc.smallOffset2()); case INFINITY -> program.push("ff".repeat(32)); } @@ -282,9 +274,11 @@ public void runDeploymentTransactionWithProvidedCodeAsInitCode( } /** - * We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code. We provide - * {@link #root} with byte code that copies the code of {@link #foreignCodeOwnerAddress} and runs - * it as initialization code. {@link #root} optionally reverts. + * - We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code + * + *

- We provide {@link #root} with byte code that (a) copies the code of {@link + * #foreignCodeOwner} to RAM, (b) runs it as the init code of a CREATE and + * (c) optionally reverts. * * @param foreignCode * @param embedRevertIntoInitCode @@ -309,8 +303,10 @@ public void runForeignByteCodeAsInitCode( } /** - * {@link #chadPrcEnjoyer} is given {@code providedCode} as its byte code. The {@code root} of the - * transaction calls {@link #chadPrcEnjoyer}. It then optionally reverts. + * - We provide {@link #chadPrcEnjoyer} with {@code providedCode} as its byte code + * + *

- We provide {@code root} with byte code that calls {@link #chadPrcEnjoyer} and optionally + * reverts. * * @param providedCode * @param revertRoot @@ -335,9 +331,9 @@ public void runMessageCallToAccountEndowedWithProvidedCode( } /** - * - We provide {@link #root} with byte code that (a) copies {@link #initCodeOwner}'s code - * and runs it as the init code of a CREATE (b) CALL's into the newly - * deployed contract (c) and optionally reverts. + * - We provide {@link #root} with byte code that (a) copies {@link #initCodeOwner}'s code + * and runs it as the init code of a CREATE (b) CALL's into the newly + * deployed contract (c) and optionally reverts. * *

- We provide {@link #initCodeOwner} with byte code that copies the code of {@link * #foreignCodeOwnerAddress} and RETURN's it. From 2ccdfbc5b5bcd34f8bcb598420e0c8fe4070394f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 11 Feb 2025 16:33:36 +0100 Subject: [PATCH 17/57] ras: some refactoring and method extraction --- .../callTests/prc/CodeExecutionMethods.java | 196 ++++++++++++++++++ .../prc/{sha2 => hash}/GasTests.java | 2 +- .../HappyPathHashPrecompileTests.java | 166 +-------------- .../{sha2 => hash}/ParameterGeneration.java | 2 +- 4 files changed, 204 insertions(+), 162 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{sha2 => hash}/GasTests.java (99%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{sha2 => hash}/HappyPathHashPrecompileTests.java (56%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{sha2 => hash}/ParameterGeneration.java (99%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java new file mode 100644 index 0000000000..9fb3488e47 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -0,0 +1,196 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.copyForeignCodeAndReturnIt; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; +import static net.consensys.linea.zktracer.opcode.OpCode.CALL; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; +import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER; + +import java.util.List; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.ToyAccount; +import net.consensys.linea.testing.ToyExecutionEnvironmentV2; +import net.consensys.linea.testing.ToyTransaction; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; + +/** + * The following class provides methods to run code in the following contexts: + * + *

- at depth 0 in the root context of a MESSAGE_CALL_TRANSACTION + * + *

- at depth 0 in the root context of a CONTRACT_DEPLOYMENT_TRANSACTION + * + *

- at depth 1 in a MESSAGE_CALL_FROM_ROOT, i.e. as code executed in a CALL + * + *

- at depth 1 in a DURING_DEPLOYMENT, i.e. as the init code of a CREATE + * + *

- at depth 1 in a AFTER_DEPLOYMENT, i.e. after deploying it with a CREATE and + * calling the newly deployed contract + */ +public class CodeExecutionMethods { + + public static final Address rootAddress = Address.fromHexString("7007"); + public static final ToyAccount.ToyAccountBuilder root = + ToyAccount.builder().address(rootAddress).balance(Wei.of(65536L)).nonce(1865); + + public static final Address chadPrcEnjoyerAddress = Address.fromHexString("cbad"); + public static final ToyAccount.ToyAccountBuilder chadPrcEnjoyer = + ToyAccount.builder().address(chadPrcEnjoyerAddress).balance(Wei.of(1024L)).nonce(64); + + public static final Address initCodeOwnerAddress = Address.fromHexString("1717"); + public static final ToyAccount.ToyAccountBuilder initCodeOwner = + ToyAccount.builder().address(initCodeOwnerAddress).balance(Wei.of(0x1337L)).nonce(127); + + public static final Address foreignCodeOwnerAddress = Address.fromHexString("f00d"); + public static final ToyAccount.ToyAccountBuilder foreignCodeOwner = + ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); + + public static final ToyTransaction.ToyTransactionBuilder transaction = + ToyTransaction.builder() + .sender(userAccount) + .keyPair(keyPair) + .transactionType(FRONTIER) + .gasLimit(0xffffffL) + .value(Wei.of(1_000_000_000L)); + + /** + * Construct transaction with {@code transactionInitCode} as its init code. + * + * @param transactionInitCode + */ + public static void runDeploymentTransactionWithProvidedCodeAsInitCode( + BytecodeCompiler transactionInitCode) { + + transaction.payload(transactionInitCode.compile()); // init code + + ToyExecutionEnvironmentV2.builder() + .transaction(transaction.build()) + .accounts(List.of(userAccount)) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); + } + + /** + * - We provide {@link CodeExecutionMethods#foreignCodeOwner} with {@code foreignCode} as its byte + * code + * + *

- We provide {@link CodeExecutionMethods#root} with byte code that (a) copies the + * code of {@link CodeExecutionMethods#foreignCodeOwner} to RAM, (b) runs it as the init + * code of a CREATE and (c) optionally reverts. + * + * @param foreignCode + * @param embedRevertIntoInitCode + */ + public static void runForeignByteCodeAsInitCode( + BytecodeCompiler foreignCode, boolean embedRevertIntoInitCode) { + + foreignCodeOwner.code(foreignCode.compile()); + + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(rootCode, foreignCodeOwnerAddress); + if (embedRevertIntoInitCode) revertWith(rootCode, 0, 0); + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), foreignCodeOwner.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + /** + * - We provide {@link CodeExecutionMethods#chadPrcEnjoyer} with {@code providedCode} as its byte + * code + * + *

- We provide {@code root} with byte code that calls {@link + * CodeExecutionMethods#chadPrcEnjoyer} and optionally reverts. + * + * @param providedCode + * @param revertRoot + */ + public static void runMessageCallToAccountEndowedWithProvidedCode( + BytecodeCompiler providedCode, boolean revertRoot) { + + chadPrcEnjoyer.code(providedCode.compile()); + + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + appendCallTo(rootCode, CALL, chadPrcEnjoyerAddress); + if (revertRoot) revertWith(rootCode, 0, 0); // we let the ROOT revert + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) + .transaction(transaction.build()) + .build() + .run(); + } + + /** + * - We provide {@link CodeExecutionMethods#root} with byte code that (a) copies {@link + * CodeExecutionMethods#initCodeOwner}'s code and runs it as the init code of a CREATE + * (b) CALL's into the newly deployed contract (c) and optionally reverts. + * + *

- We provide {@link CodeExecutionMethods#initCodeOwner} with byte code that copies the code + * of {@link CodeExecutionMethods#foreignCodeOwnerAddress} and RETURN's it. + * + *

- We provide {@link CodeExecutionMethods#foreignCodeOwner} with {@code foreignCode} as its + * byte code. + * + * @param foreignCode + * @param rootReverts + */ + public static void runCreateDeployingForeignCodeAndCallIntoIt( + BytecodeCompiler foreignCode, boolean rootReverts) { + + // ROOT code + int key = 65537; // 0x 01 00 01 + BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndRunItAsInitCode(rootCode, initCodeOwnerAddress); + sstoreTopOfStackTo(rootCode, key); // store deployment address + pushSeveral(rootCode, 0, 0, 0, 0, 0); // zero value + sloadFrom(rootCode, key); + rootCode.op(GAS).op(CALL); // call the deployed contract + if (rootReverts) revertWith(rootCode, 0, 0); + root.code(rootCode.compile()); + + // init code owner code + BytecodeCompiler initCode = BytecodeCompiler.newProgram(); + copyForeignCodeAndReturnIt(initCode, foreignCodeOwnerAddress); + initCodeOwner.code(initCode.compile()); + + // foreign code owner code + foreignCodeOwner.code(foreignCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .accounts( + List.of(userAccount, root.build(), foreignCodeOwner.build(), initCodeOwner.build())) + .transaction(transaction.build()) + .build() + .run(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/GasTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/GasTests.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/GasTests.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/GasTests.java index cbcb9c7e7a..6819d93e0d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/GasTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/GasTests.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; import static net.consensys.linea.zktracer.instructionprocessing.utilities.Calls.appendCall; import static net.consensys.linea.zktracer.instructionprocessing.utilities.Calls.appendRevert; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java similarity index 56% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java index 4052570bc4..20e2233acc 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java @@ -12,22 +12,18 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; -import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER; -import java.util.List; import java.util.stream.Stream; import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -62,45 +58,9 @@ *

- (different) happy path precompile CALL * *

- play with (precompile) return data - * - *

In various setups: - * - *

- at depth 0 in the root context of a MESSAGE_CALL_TRANSACTION - * - *

- at depth 0 in the root context of a CONTRACT_DEPLOYMENT_TRANSACTION - * - *

- at depth 1 in a MESSAGE_CALL_FROM_ROOT - * - *

- at depth 1 in a DURING_DEPLOYMENT - * - *

- at depth 1 in a AFTER_DEPLOYMENT */ public class HappyPathHashPrecompileTests { - final Address rootAddress = Address.fromHexString("7007"); - final ToyAccount.ToyAccountBuilder root = - ToyAccount.builder().address(rootAddress).balance(Wei.of(65536L)).nonce(1865); - - final Address chadPrcEnjoyerAddress = Address.fromHexString("cbad"); - final ToyAccount.ToyAccountBuilder chadPrcEnjoyer = - ToyAccount.builder().address(chadPrcEnjoyerAddress).balance(Wei.of(1024L)).nonce(64); - - final Address initCodeOwnerAddress = Address.fromHexString("1717"); - final ToyAccount.ToyAccountBuilder initCodeOwner = - ToyAccount.builder().address(initCodeOwnerAddress).balance(Wei.of(0x1337L)).nonce(127); - - final Address foreignCodeOwnerAddress = Address.fromHexString("f00d"); - final ToyAccount.ToyAccountBuilder foreignCodeOwner = - ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); - - final ToyTransaction.ToyTransactionBuilder transaction = - ToyTransaction.builder() - .sender(userAccount) - .keyPair(keyPair) - .transactionType(FRONTIER) - .gasLimit(0xffffffL) - .value(Wei.of(1_000_000_000L)); - public static Stream happyPathParameterGeneration() { return ParameterGeneration.happyPathParameterGeneration(); } @@ -147,9 +107,10 @@ public void messageCallFromRootTest(PrecompileCallParameters params) { } /** - * The {@link #root} contract fully copies the code of the account whose address is in the {@link - * #transaction} call data. This account is the {@link #chadPrcEnjoyer}. That code is then used as - * the initialization code of a CREATE. The whole operation optionally REVERT's. + * The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. * * @param params */ @@ -259,119 +220,4 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( return program; } - - public void runDeploymentTransactionWithProvidedCodeAsInitCode( - BytecodeCompiler transactionInitCode) { - - transaction.payload(transactionInitCode.compile()); // init code - - ToyExecutionEnvironmentV2.builder() - .transaction(transaction.build()) - .accounts(List.of(userAccount)) - .zkTracerValidator(zkTracer -> {}) - .build() - .run(); - } - - /** - * - We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code - * - *

- We provide {@link #root} with byte code that (a) copies the code of {@link - * #foreignCodeOwner} to RAM, (b) runs it as the init code of a CREATE and - * (c) optionally reverts. - * - * @param foreignCode - * @param embedRevertIntoInitCode - */ - public void runForeignByteCodeAsInitCode( - BytecodeCompiler foreignCode, boolean embedRevertIntoInitCode) { - - foreignCodeOwner.code(foreignCode.compile()); - - BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); - copyForeignCodeAndRunItAsInitCode(rootCode, foreignCodeOwnerAddress); - if (embedRevertIntoInitCode) revertWith(rootCode, 0, 0); - root.code(rootCode.compile()); - - transaction.to(root.build()); - - ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), foreignCodeOwner.build())) - .transaction(transaction.build()) - .build() - .run(); - } - - /** - * - We provide {@link #chadPrcEnjoyer} with {@code providedCode} as its byte code - * - *

- We provide {@code root} with byte code that calls {@link #chadPrcEnjoyer} and optionally - * reverts. - * - * @param providedCode - * @param revertRoot - */ - public void runMessageCallToAccountEndowedWithProvidedCode( - BytecodeCompiler providedCode, boolean revertRoot) { - - chadPrcEnjoyer.code(providedCode.compile()); - - BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); - appendCallTo(rootCode, CALL, chadPrcEnjoyerAddress); - if (revertRoot) revertWith(rootCode, 0, 0); // we let the ROOT revert - root.code(rootCode.compile()); - - transaction.to(root.build()); - - ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) - .transaction(transaction.build()) - .build() - .run(); - } - - /** - * - We provide {@link #root} with byte code that (a) copies {@link #initCodeOwner}'s code - * and runs it as the init code of a CREATE (b) CALL's into the newly - * deployed contract (c) and optionally reverts. - * - *

- We provide {@link #initCodeOwner} with byte code that copies the code of {@link - * #foreignCodeOwnerAddress} and RETURN's it. - * - *

- We provide {@link #foreignCodeOwner} with {@code foreignCode} as its byte code. - * - * @param foreignCode - * @param rootReverts - */ - public void runCreateDeployingForeignCodeAndCallIntoIt( - BytecodeCompiler foreignCode, boolean rootReverts) { - - // ROOT code - int key = 65537; // 0x 01 00 01 - BytecodeCompiler rootCode = BytecodeCompiler.newProgram(); - copyForeignCodeAndRunItAsInitCode(rootCode, initCodeOwnerAddress); - sstoreTopOfStackTo(rootCode, key); // store deployment address - pushSeveral(rootCode, 0, 0, 0, 0, 0); // zero value - sloadFrom(rootCode, key); - rootCode.op(GAS).op(CALL); // call the deployed contract - if (rootReverts) revertWith(rootCode, 0, 0); - root.code(rootCode.compile()); - - // init code owner code - BytecodeCompiler initCode = BytecodeCompiler.newProgram(); - copyForeignCodeAndReturnIt(initCode, foreignCodeOwnerAddress); - initCodeOwner.code(initCode.compile()); - - // foreign code owner code - foreignCodeOwner.code(foreignCode.compile()); - - transaction.to(root.build()); - - ToyExecutionEnvironmentV2.builder() - .accounts( - List.of(userAccount, root.build(), foreignCodeOwner.build(), initCodeOwner.build())) - .transaction(transaction.build()) - .build() - .run(); - } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java index 525744ce99..60c894b787 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/sha2/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.sha2; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; import static net.consensys.linea.zktracer.opcode.OpCode.*; import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; From 2a714856baf8bc34a68eb6fa80743ba90a1028c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 11 Feb 2025 16:35:08 +0100 Subject: [PATCH 18/57] ras --- .../callTests/prc/CodeExecutionMethods.java | 1 - 1 file changed, 1 deletion(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index 9fb3488e47..7234ce8885 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -15,7 +15,6 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.copyForeignCodeAndReturnIt; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; import static net.consensys.linea.zktracer.opcode.OpCode.CALL; From 794ae98b43c95cd87144196766a07c559d8a665c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 11 Feb 2025 17:24:15 +0100 Subject: [PATCH 19/57] feat: MODEXP parameter generation wip --- .../callTests/prc/ByteSizeParameter.java | 22 +++++ .../callTests/prc/CallDataParameter.java | 31 +++++++ ...java => HashPrecompileCallParameters.java} | 8 +- .../prc/ModexpCallDataSizeParameter.java | 27 ++++++ .../callTests/prc/ModexpCallParameters.java | 42 +++++++++ .../callTests/prc/ReturnAtParameter.java | 34 +++++++ ...ecompileTests.java => HappyPathTests.java} | 16 ++-- .../prc/hash/ParameterGeneration.java | 7 +- .../callTests/prc/modexp/HappyPathTests.java | 17 ++++ .../prc/modexp/ParameterGeneration.java | 93 +++++++++++++++++++ 10 files changed, 282 insertions(+), 15 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{PrecompileCallParameters.java => HashPrecompileCallParameters.java} (91%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ReturnAtParameter.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/{HappyPathHashPrecompileTests.java => HappyPathTests.java} (93%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java new file mode 100644 index 0000000000..2e16bfeb19 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java @@ -0,0 +1,22 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum ByteSizeParameter { + ZERO, + ONE, + TWELVE, + MAX; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java new file mode 100644 index 0000000000..84050422ec --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java @@ -0,0 +1,31 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +import net.consensys.linea.zktracer.instructionprocessing.createTests.SizeParameter; + +public class CallDataParameter { + final ByteSizeParameter bbs; + final ByteSizeParameter ebs; + final ByteSizeParameter mbs; + final ModexpCallDataSizeParameter cds; + + public CallDataParameter(ByteSizeParameter bbs, ByteSizeParameter ebs, ByteSizeParameter mbs, ModexpCallDataSizeParameter cds) { + this.bbs = bbs; + this.ebs = ebs; + this.mbs = mbs; + this.cds = cds; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java similarity index 91% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java index 6edfe80466..6c96066803 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/PrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java @@ -16,7 +16,7 @@ import net.consensys.linea.zktracer.opcode.OpCode; -public class PrecompileCallParameters { +public class HashPrecompileCallParameters { public final OpCode call; public GasParameter gas; public final HashPrecompile prc; @@ -28,7 +28,7 @@ public class PrecompileCallParameters { public final RelativeRangePosition relPos; public final boolean willRevert; - public PrecompileCallParameters( + public HashPrecompileCallParameters( OpCode call, GasParameter gas, HashPrecompile prc, @@ -51,8 +51,8 @@ public PrecompileCallParameters( this.willRevert = willRevert; } - public PrecompileCallParameters next() { - return new PrecompileCallParameters( + public HashPrecompileCallParameters next() { + return new HashPrecompileCallParameters( call, gas, prc.next(), value, cdo, cds, rao, rac, relPos, willRevert); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java new file mode 100644 index 0000000000..6836c64246 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java @@ -0,0 +1,27 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +public enum ModexpCallDataSizeParameter { + ZERO, + BBS, + EBS, + MBS, + BASE, + EXPONENT, + MODULUS_PARTIAL, + MODULUS, + LARGE; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java new file mode 100644 index 0000000000..4e65bdeca6 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java @@ -0,0 +1,42 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +import net.consensys.linea.zktracer.opcode.OpCode; + +public class ModexpCallParameters { + + public final OpCode call; + public final GasParameter gas; + public final CallDataParameter callData; + public final ReturnAtParameter returnAt; + public final RelativeRangePosition relPos; + public final boolean willRevert; + + public ModexpCallParameters( + OpCode call, + GasParameter gas, + CallDataParameter callData, + ReturnAtParameter returnAt, + RelativeRangePosition relPos, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.callData = callData; + this.returnAt = returnAt; + this.relPos = relPos; + this.willRevert = willRevert; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ReturnAtParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ReturnAtParameter.java new file mode 100644 index 0000000000..5f5295559d --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ReturnAtParameter.java @@ -0,0 +1,34 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +/** + * {@link ReturnAtParameter} is an enum which describes the types of return at memory range. + * For MODEXP the interpretation is as follows: + * + *

- {@link #EMPTY} is clear + * + *

- {@link #PARTIAL} represents a fraction of the mbs (modulus byte size) + * + *

- {@link #FULL} represents the whole return data range size (mbs) + * + *

- {@link #LARGE} is larger than mbs + */ +public enum ReturnAtParameter { + EMPTY, + PARTIAL, + FULL, + LARGE; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java similarity index 93% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java index 20e2233acc..b497e015a0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathHashPrecompileTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java @@ -59,7 +59,7 @@ * *

- play with (precompile) return data */ -public class HappyPathHashPrecompileTests { +public class HappyPathTests { public static Stream happyPathParameterGeneration() { return ParameterGeneration.happyPathParameterGeneration(); @@ -72,7 +72,7 @@ public static Stream happyPathParameterGeneration() { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(PrecompileCallParameters params) { + public void messageCallTransactionTest(HashPrecompileCallParameters params) { if (!params.willRevert) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); BytecodeRunner.of(rootCode.compile()).run(Wei.fromEth(1), 61_000_000L); @@ -86,7 +86,7 @@ public void messageCallTransactionTest(PrecompileCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(PrecompileCallParameters params) { + public void deploymentTransactionTest(HashPrecompileCallParameters params) { BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); if (params.willRevert) revertWith(txInitCode, 0, 0); @@ -101,7 +101,7 @@ public void deploymentTransactionTest(PrecompileCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(PrecompileCallParameters params) { + public void messageCallFromRootTest(HashPrecompileCallParameters params) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); } @@ -116,7 +116,7 @@ public void messageCallFromRootTest(PrecompileCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(PrecompileCallParameters params) { + public void happyPathDuringCreate(HashPrecompileCallParameters params) { if (!params.willMxpx()) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); @@ -126,7 +126,7 @@ public void happyPathDuringCreate(PrecompileCallParameters params) { @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(PrecompileCallParameters params) { + public void happyPathAfterCreate(HashPrecompileCallParameters params) { if (!params.willMxpx()) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); @@ -135,7 +135,7 @@ public void happyPathAfterCreate(PrecompileCallParameters params) { } public void appendHappyPathPrecompileCall( - BytecodeCompiler program, PrecompileCallParameters params) { + BytecodeCompiler program, HashPrecompileCallParameters params) { // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM switch (params.rac) { @@ -192,7 +192,7 @@ public void appendHappyPathPrecompileCall( } private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( - PrecompileCallParameters params) { + HashPrecompileCallParameters params) { BytecodeCompiler program = BytecodeCompiler.newProgram(); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java index 60c894b787..645a1d2c4a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java @@ -28,7 +28,8 @@ public class ParameterGeneration { /** - * Generates test parameters for the happy path tests. + * Generates test parameters for the happy path tests of hash precompiles, that is + * RIPEMD160, SHA256, and IDENTITY. * *

Note. We provide zero value. We thus avoid having to account for the G_callstipend. * @@ -50,7 +51,7 @@ public static Stream happyPathParameterGeneration() { // adding PrecompileCallParameters argumentsList.add( Arguments.of( - new PrecompileCallParameters( + new HashPrecompileCallParameters( callOpcode, gas, precompile, @@ -63,7 +64,7 @@ public static Stream happyPathParameterGeneration() { true))); argumentsList.add( Arguments.of( - new PrecompileCallParameters( + new HashPrecompileCallParameters( callOpcode, gas, precompile, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java new file mode 100644 index 0000000000..6e272f5fae --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; + +public class HappyPathTests {} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java new file mode 100644 index 0000000000..0fe0201252 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -0,0 +1,93 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; + +public class ParameterGeneration { + + /** + * Generates test parameters for the happy path tests of MODEXP. + * + * @return Stream of test parameters + */ + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { + for (GasParameter gas : GasParameter.values()) { + for (ByteSizeParameter bbs : ByteSizeParameter.values()) { + for (ByteSizeParameter ebs : ByteSizeParameter.values()) { + for (ByteSizeParameter mbs : ByteSizeParameter.values()) { + for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { + for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new CallDataParameter( + bbs, + ebs, + mbs, + cds + ), + returnAt, + relPos, + false + ) + ) + ); + + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new CallDataParameter( + bbs, + ebs, + mbs, + cds + ), + returnAt, + relPos, + false + ) + ) + ); + } + } + } + } + } + } + } + } + return argumentsList.stream(); + } +} From 2bb41d7ba611cca99602c526b43b9fb0023f58cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 00:00:23 +0100 Subject: [PATCH 20/57] feat: more MODEXP wip --- .../callTests/Utilities.java | 6 +- .../callTests/prc/ByteSizeParameter.java | 8 +- .../callTests/prc/CallDataParameter.java | 31 ----- .../callTests/prc/CodeExecutionMethods.java | 8 ++ .../prc/ModexpCallDataParameters.java | 105 ++++++++++++++ .../prc/ModexpCallDataSizeParameter.java | 42 ++++-- .../callTests/prc/ModexpCallParameters.java | 4 +- .../callTests/prc/hash/HappyPathTests.java | 2 +- .../callTests/prc/modexp/HappyPathTests.java | 128 +++++++++++++++++- .../prc/modexp/ParameterGeneration.java | 106 ++++++--------- 10 files changed, 330 insertions(+), 110 deletions(-) delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 98ab7bf36e..5dc269a56c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -276,11 +276,15 @@ public static void copyForeignCodeAndRunItAsInitCode( * @param foreignAddress */ public static void copyForeignCodeAndReturnIt(BytecodeCompiler program, Address foreignAddress) { + copyForeignCodeToRam(program, foreignAddress); + program.op(MSIZE).push(0).op(RETURN); // return memory in full + } + + public static void copyForeignCodeToRam(BytecodeCompiler program, Address foreignAddress) { program.push(foreignAddress).op(EXTCODESIZE); // ] EXTCS ] pushSeveral(program, 0, 0); program.push(foreignAddress); // ] EXTCS | 0 | 0 | foreignAddress ] program.op(EXTCODECOPY); // full copy of foreign code - program.op(MSIZE).push(0).op(RETURN); // return memory in full } public static void sstoreTopOfStackTo(BytecodeCompiler program, int storageKey) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java index 2e16bfeb19..cf4d4c60de 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java @@ -15,8 +15,8 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; public enum ByteSizeParameter { - ZERO, - ONE, - TWELVE, - MAX; + ZERO, + ONE, + SMALL, + MAX; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java deleted file mode 100644 index 84050422ec..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParameter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; - -import net.consensys.linea.zktracer.instructionprocessing.createTests.SizeParameter; - -public class CallDataParameter { - final ByteSizeParameter bbs; - final ByteSizeParameter ebs; - final ByteSizeParameter mbs; - final ModexpCallDataSizeParameter cds; - - public CallDataParameter(ByteSizeParameter bbs, ByteSizeParameter ebs, ByteSizeParameter mbs, ModexpCallDataSizeParameter cds) { - this.bbs = bbs; - this.ebs = ebs; - this.mbs = mbs; - this.cds = cds; - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index 7234ce8885..fa770b2f13 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -62,6 +62,14 @@ public class CodeExecutionMethods { public static final ToyAccount.ToyAccountBuilder foreignCodeOwner = ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); + public static final Address modexpMemoryHolderAddress1 = Address.fromHexString("d00d"); + public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder1 = + ToyAccount.builder().address(modexpMemoryHolderAddress1).balance(Wei.of(0x2025)).nonce(0x11aaff); + + public static final Address modexpMemoryHolderAddress2 = Address.fromHexString("d00d"); + public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder2 = + ToyAccount.builder().address(modexpMemoryHolderAddress2).balance(Wei.of(0x2025)).nonce(0x11aaff); + public static final ToyTransaction.ToyTransactionBuilder transaction = ToyTransaction.builder() .sender(userAccount) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java new file mode 100644 index 0000000000..564f27fba5 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java @@ -0,0 +1,105 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; + +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +public class ModexpCallDataParameters { + public final ByteSizeParameter bbs; + public final ByteSizeParameter ebs; + public final ByteSizeParameter mbs; + public final ModexpCallDataSizeParameter cds; + + public ModexpCallDataParameters( + ByteSizeParameter bbs, + ByteSizeParameter ebs, + ByteSizeParameter mbs, + ModexpCallDataSizeParameter cds) { + this.bbs = bbs; + this.ebs = ebs; + this.mbs = mbs; + this.cds = cds; + } + + public int memorySize(boolean variant) { + return 3 * WORD_SIZE + this.bbsShort(variant) + this.ebsShort(variant) + this.mbsShort(variant); + } + + public String codeWhichWillBecomeMemoryOfModexpCall(boolean variant) { + + String memoryContents = this.bbs(variant) + this.ebs(variant) + this.mbs(variant); + + return memoryContents + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.bbsShort(variant)) + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.ebsShort(variant)) + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.mbsShort(variant)); + } + + private short bbsShort(boolean variant) { + return switch (this.bbs) { + case ZERO -> 0; + case ONE -> 1; + case SMALL -> (short) (variant ? 0x01a3 : 0x0101); + case MAX -> 0x0200; + }; + } + + private short ebsShort(boolean variant) { + return switch (this.ebs) { + case ZERO -> 0; + case ONE -> 1; + case SMALL -> (short) (variant ? 0xf1 : 0x012a); + case MAX -> 0x0200; + }; + } + + private short mbsShort(boolean variant) { + return switch (this.mbs) { + case ZERO -> 0; + case ONE -> 1; + case SMALL -> (short) (variant ? 0x012f : 0xd1); + case MAX -> 0x0200; + }; + } + + private String bbs(boolean variant) { + return Bytes32.leftPad(Bytes.ofUnsignedShort(bbsShort(variant))).toString(); + } + + private String ebs(boolean variant) { + return Bytes32.leftPad(Bytes.ofUnsignedShort(ebsShort(variant))).toString(); + } + + private String mbs(boolean variant) { + return Bytes32.leftPad(Bytes.ofUnsignedShort(mbsShort(variant))).toString(); + } + + static String BASE_512_a = + "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; + static String EXPN_512_a = + "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; + static String MDLS_512_a = + "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; + + static String BASE_512_b = + "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; + static String EXPN_512_b = + "0254e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + static String MDLS_512_b = + "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java index 6836c64246..47e1d3819f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java @@ -14,14 +14,38 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +/** + * {@link ModexpCallDataSizeParameter} represents different call data sizes for CALL's to the + * MODEXP precompile. The interpretation goes as follows: + * + *

- {@link #EMPTY} for empty call data (cds ≡ 0) + * + *

- {@link #BBS} for call data containing only bbs (cds ≡ 32) + * + *

- {@link #EBS} for call data containing everything up to and including ebs (cds ≡ 64) + * + *

- {@link #MBS} for call data containing everything up to and including mbs (cds ≡ 96) + * + *

- {@link #BASE} for call data containing the byte sizes and the BASE (cds ≡ 96 + bbs) + * + *

- {@link #EXPONENT} for call data containing everything up to the EXPONENT (cds ≡ 96 + + * bbs + ebs) + * + *

- {@link #MODULUS_PART} for call data containing the byte sizes and parts of the + * MODULUS (cds ≡ 96 + bbs + bbs + x) with 0 < x < mbs + * + *

- {@link #MODULUS_FULL} for well-formed call data MODULUS (cds ≡ 96 + bbs + bbs + mbs) + * + *

- {@link #LARGE} for call data larger than required (cds > 96 + bbs + bbs + mbs) + */ public enum ModexpCallDataSizeParameter { - ZERO, - BBS, - EBS, - MBS, - BASE, - EXPONENT, - MODULUS_PARTIAL, - MODULUS, - LARGE; + EMPTY, + BBS, + EBS, + MBS, + BASE, + EXPONENT, + MODULUS_PART, + MODULUS_FULL, + LARGE; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java index 4e65bdeca6..f0edfe460f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java @@ -20,7 +20,7 @@ public class ModexpCallParameters { public final OpCode call; public final GasParameter gas; - public final CallDataParameter callData; + public final ModexpCallDataParameters callData; public final ReturnAtParameter returnAt; public final RelativeRangePosition relPos; public final boolean willRevert; @@ -28,7 +28,7 @@ public class ModexpCallParameters { public ModexpCallParameters( OpCode call, GasParameter gas, - CallDataParameter callData, + ModexpCallDataParameters callData, ReturnAtParameter returnAt, RelativeRangePosition relPos, boolean willRevert) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java index b497e015a0..deb9ee2b77 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java @@ -75,7 +75,7 @@ public static Stream happyPathParameterGeneration() { public void messageCallTransactionTest(HashPrecompileCallParameters params) { if (!params.willRevert) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(rootCode.compile()).run(Wei.fromEth(1), 61_000_000L); + BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 6e272f5fae..523b2be1ef 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -14,4 +14,130 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; -public class HappyPathTests {} +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.opcode.OpCode.CALL; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.testing.BytecodeRunner; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ModexpCallParameters; +import org.apache.tuweni.bytes.Bytes; +import org.hyperledger.besu.datatypes.Address; +import org.hyperledger.besu.datatypes.Wei; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class HappyPathTests { + + private final boolean variant1 = true; + private final boolean variant2 = false; + + /** + * MESSAGE_CALL transaction case + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallTransactionTest(ModexpCallParameters params) { + populateCodeOfMemoryHolderAccounts(params); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); + } + + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParameters params) { + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first MODEXP call + copyForeignCodeToRam(program, modexpMemoryHolderAddress1); + + // happy path 1 + appendHappyPathPrecompileCall(program, params, variant1); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("c0ffee69"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second MODEXP call + copyForeignCodeToRam(program, modexpMemoryHolderAddress2); + + // happy path 2 + appendHappyPathPrecompileCall(program, params, variant2); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + return program; + } + + private void populateCodeOfMemoryHolderAccounts(ModexpCallParameters params) { + + String code1 = params.callData.codeWhichWillBecomeMemoryOfModexpCall(variant1); + String code2 = params.callData.codeWhichWillBecomeMemoryOfModexpCall(variant2); + + modexpMemoryHolder1.code(Bytes.fromHexString(code1)); + modexpMemoryHolder2.code(Bytes.fromHexString(code2)); + } + + public static Stream happyPathParameterGeneration() { + return ParameterGeneration.happyPathParameterGeneration(); + } + + public void appendHappyPathPrecompileCall( + BytecodeCompiler program, ModexpCallParameters params, boolean variant) { + + int cds = params.callData.memorySize(variant); + + // pushing r@c onto the stack + int rac = + switch (params.returnAt) { + case EMPTY -> 0; + case PARTIAL -> cds / 2; + case FULL -> cds; + case LARGE -> cds + 256; + }; + program.push(rac); + + // pushing r@o onto the stack + int rao = + switch (params.relPos) { + case DISJOINT -> cds; + case OVERLAP -> 0; + }; + program.push(rao); + + // pushing cds onto the stack + program.push(cds); + + // pushing cdo onto the stack + program.push(0); + + // pushing zero value onto the stack + if (params.call.callHasValueArgument()) { + program.push(0); + } + + // pushing MODEXP address onto the stack + program.push(Address.MODEXP); + + // TODO: replace with actual gas price + int cost = 10_000; + + // pushing gas onto the stack + switch (params.gas) { + case ZERO -> program.push(0); + case EXACT_MO -> program.push(cost - 1); + case EXACT -> program.push(cost); + case EXACT_PO -> program.push(cost + 1); + case FULL -> program.op(GAS); + } + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 0fe0201252..7aa5b6c62a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -14,80 +14,64 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.opcode.OpCode; -import org.junit.jupiter.params.provider.Arguments; +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; -import static net.consensys.linea.zktracer.opcode.OpCode.*; -import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; public class ParameterGeneration { - /** - * Generates test parameters for the happy path tests of MODEXP. - * - * @return Stream of test parameters - */ - public static Stream happyPathParameterGeneration() { - List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + /** + * Generates test parameters for the happy path tests of MODEXP. + * + * @return Stream of test parameters + */ + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - List argumentsList = new ArrayList<>(); + List argumentsList = new ArrayList<>(); - for (OpCode opCode : CallOpCodes) { - for (GasParameter gas : GasParameter.values()) { - for (ByteSizeParameter bbs : ByteSizeParameter.values()) { - for (ByteSizeParameter ebs : ByteSizeParameter.values()) { - for (ByteSizeParameter mbs : ByteSizeParameter.values()) { - for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { - for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { - for (RelativeRangePosition relPos : RelativeRangePosition.values()) { - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - gas, - new CallDataParameter( - bbs, - ebs, - mbs, - cds - ), - returnAt, - relPos, - false - ) - ) - ); + for (OpCode opCode : CallOpCodes) { + for (GasParameter gas : GasParameter.values()) { + for (ByteSizeParameter bbs : ByteSizeParameter.values()) { + for (ByteSizeParameter ebs : ByteSizeParameter.values()) { + for (ByteSizeParameter mbs : ByteSizeParameter.values()) { + for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { + for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new ModexpCallDataParameters(bbs, ebs, mbs, cds), + returnAt, + relPos, + false))); - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - gas, - new CallDataParameter( - bbs, - ebs, - mbs, - cds - ), - returnAt, - relPos, - false - ) - ) - ); - } - } - } - } - } + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new ModexpCallDataParameters(bbs, ebs, mbs, cds), + returnAt, + relPos, + false))); + } } + } } + } } - return argumentsList.stream(); + } } + return argumentsList.stream(); + } } From 3e393b3b1f38f68674b031ed7da7667e8bce93f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 00:02:01 +0100 Subject: [PATCH 21/57] spotless --- .../callTests/prc/CodeExecutionMethods.java | 10 ++++++++-- .../callTests/prc/ModexpCallDataParameters.java | 14 +++++++------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index fa770b2f13..eabe65f527 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -64,11 +64,17 @@ public class CodeExecutionMethods { public static final Address modexpMemoryHolderAddress1 = Address.fromHexString("d00d"); public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder1 = - ToyAccount.builder().address(modexpMemoryHolderAddress1).balance(Wei.of(0x2025)).nonce(0x11aaff); + ToyAccount.builder() + .address(modexpMemoryHolderAddress1) + .balance(Wei.of(0x2025)) + .nonce(0x11aaff); public static final Address modexpMemoryHolderAddress2 = Address.fromHexString("d00d"); public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder2 = - ToyAccount.builder().address(modexpMemoryHolderAddress2).balance(Wei.of(0x2025)).nonce(0x11aaff); + ToyAccount.builder() + .address(modexpMemoryHolderAddress2) + .balance(Wei.of(0x2025)) + .nonce(0x11aaff); public static final ToyTransaction.ToyTransactionBuilder transaction = ToyTransaction.builder() diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java index 564f27fba5..931c26359e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java @@ -44,10 +44,10 @@ public String codeWhichWillBecomeMemoryOfModexpCall(boolean variant) { String memoryContents = this.bbs(variant) + this.ebs(variant) + this.mbs(variant); - return memoryContents - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.bbsShort(variant)) - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.ebsShort(variant)) - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.mbsShort(variant)); + return memoryContents + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.bbsShort(variant)) + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.ebsShort(variant)) + + (variant ? BASE_512_a : BASE_512_b).substring(0, this.mbsShort(variant)); } private short bbsShort(boolean variant) { @@ -97,9 +97,9 @@ private String mbs(boolean variant) { "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; static String BASE_512_b = - "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; + "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; static String EXPN_512_b = - "0254e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + "0254e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; static String MDLS_512_b = - "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; + "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; } From 24705ce64452358f62ab44f0f8c1e1779fd50c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 02:25:19 +0100 Subject: [PATCH 22/57] ras: get tests to run --- .../prc/ModexpCallDataParameters.java | 16 +++--- .../prc/modexp/ParameterGeneration.java | 54 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java index 931c26359e..4b1137ecfd 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java @@ -42,12 +42,12 @@ public int memorySize(boolean variant) { public String codeWhichWillBecomeMemoryOfModexpCall(boolean variant) { - String memoryContents = this.bbs(variant) + this.ebs(variant) + this.mbs(variant); + String memoryContents = this.bbs(variant).substring(2) + this.ebs(variant).substring(2) + this.mbs(variant).substring(2); return memoryContents - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.bbsShort(variant)) - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.ebsShort(variant)) - + (variant ? BASE_512_a : BASE_512_b).substring(0, this.mbsShort(variant)); + + (variant ? BASE_512_a : BASE_512_b).substring(0, 2 * this.bbsShort(variant)) + + (variant ? EXPN_512_a : EXPN_512_b).substring(0, 2 * this.ebsShort(variant)) + + (variant ? MDLS_512_a : MDLS_512_b).substring(0, 2 * this.mbsShort(variant)); } private short bbsShort(boolean variant) { @@ -61,8 +61,8 @@ private short bbsShort(boolean variant) { private short ebsShort(boolean variant) { return switch (this.ebs) { - case ZERO -> 0; - case ONE -> 1; + case ZERO -> 0x00; + case ONE -> 0x01; case SMALL -> (short) (variant ? 0xf1 : 0x012a); case MAX -> 0x0200; }; @@ -70,8 +70,8 @@ private short ebsShort(boolean variant) { private short mbsShort(boolean variant) { return switch (this.mbs) { - case ZERO -> 0; - case ONE -> 1; + case ZERO -> 0x00; + case ONE -> 0x01; case SMALL -> (short) (variant ? 0x012f : 0xd1); case MAX -> 0x0200; }; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 7aa5b6c62a..f363886cc2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -37,34 +37,33 @@ public static Stream happyPathParameterGeneration() { List argumentsList = new ArrayList<>(); - for (OpCode opCode : CallOpCodes) { - for (GasParameter gas : GasParameter.values()) { - for (ByteSizeParameter bbs : ByteSizeParameter.values()) { - for (ByteSizeParameter ebs : ByteSizeParameter.values()) { - for (ByteSizeParameter mbs : ByteSizeParameter.values()) { - for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { - for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { - for (RelativeRangePosition relPos : RelativeRangePosition.values()) { - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - gas, - new ModexpCallDataParameters(bbs, ebs, mbs, cds), - returnAt, - relPos, - false))); + for (OpCode opCode : CallOpCodes) { // 4 + // for (GasParameter gas : GasParameter.values()) { // 5 + for (ByteSizeParameter bbs : ByteSizeParameter.values()) { // 4 + for (ByteSizeParameter ebs : ByteSizeParameter.values()) { // 4 + for (ByteSizeParameter mbs : ByteSizeParameter.values()) { // 4 + for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { // 9 + for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { // 4 + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + GasParameter.FULL, + new ModexpCallDataParameters(bbs, ebs, mbs, cds), + returnAt, + relPos, + false))); - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - gas, - new ModexpCallDataParameters(bbs, ebs, mbs, cds), - returnAt, - relPos, - false))); - } + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + GasParameter.FULL, + new ModexpCallDataParameters(bbs, ebs, mbs, cds), + returnAt, + relPos, + false))); } } } @@ -72,6 +71,7 @@ public static Stream happyPathParameterGeneration() { } } } + // } return argumentsList.stream(); } } From 1b5d22278aafdd6e42f7177ec504d13d0357036a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 13:08:58 +0100 Subject: [PATCH 23/57] ras: documentation + single parameter test for MODEXP --- .../callTests/prc/modexp/HappyPathTests.java | 28 ++++++++++++++++++- .../prc/modexp/ParameterGeneration.java | 19 +++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 523b2be1ef..8451584783 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -23,10 +23,11 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.testing.BytecodeRunner; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ModexpCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Wei; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -49,6 +50,31 @@ public void messageCallTransactionTest(ModexpCallParameters params) { BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); } + /** + * Non-parametric test to make sure things are working as expected. + */ + @Test + public void singleMessageCallTransactionTest() { + + ModexpCallDataParameters callDataParameters = new ModexpCallDataParameters( + ByteSizeParameter.SMALL, // bbs + ByteSizeParameter.SMALL, // ebs + ByteSizeParameter.MAX, // mbs + ModexpCallDataSizeParameter.MODULUS_FULL // cds + ); + ModexpCallParameters params = new ModexpCallParameters( + CALL, + GasParameter.FULL, + callDataParameters, + ReturnAtParameter.FULL, + RelativeRangePosition.OVERLAP, + true + ); + populateCodeOfMemoryHolderAccounts(params); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); + } + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParameters params) { BytecodeCompiler program = BytecodeCompiler.newProgram(); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index f363886cc2..1e36936400 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -30,6 +30,25 @@ public class ParameterGeneration { /** * Generates test parameters for the happy path tests of MODEXP. * + *

- {@code opCode} is one of the CALL-type {@link OpCode}'s + * + *

- {@code gas} is one of the {@link GasParameter} values (currently defaults to {@link + * GasParameter#FULL}) + * + *

- {@code bbs}, {@code ebs}, {@code mbs} are {@link ByteSizeParameter} values for + * MODEXP, either 0, 1, something small, or the maximum (512) + * + *

- {@code cds} is one of the {@link ModexpCallDataSizeParameter} values, which dictates how + * much of the parameters in RAM (bbs, ebs, mbs, BASE, EXPONENT + * and MODULUS) actually get passed down to MODEXP + * + *

- {@code returnAt} is one of the {@link ReturnAtParameter} values, which dictates how much + * of the return data will be written to RAM, it can be EMPTY, PARTIAL or + * FULL in terms of the modulus byte size (mbs) + * + *

- {@code relPos} is one of the {@link RelativeRangePosition} values, which dictates whether + * the various memory ranges for call data / return at etc ... ovrlap or not. + * * @return Stream of test parameters */ public static Stream happyPathParameterGeneration() { From 388c1f3f198a28e586402378ad0c5374bd283982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 19:23:52 +0100 Subject: [PATCH 24/57] fix: type error in ModexpLeadOobCall --- .../imc/oob/precompiles/ModexpLeadOobCall.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/oob/precompiles/ModexpLeadOobCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/oob/precompiles/ModexpLeadOobCall.java index 714ae96ea7..4bcd321ab0 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/oob/precompiles/ModexpLeadOobCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/oob/precompiles/ModexpLeadOobCall.java @@ -53,9 +53,9 @@ public net.consensys.linea.zktracer.module.oob.Trace trace( .data3(bigIntegerToBytes(ebs)) .data4(booleanToBytes(loadLead)) .data5(ZERO) - .data6(Bytes.of(cdsCutoff)) - .data7(Bytes.of(ebsCutoff)) - .data8(Bytes.of(subEbs32)) + .data6(Bytes.ofUnsignedInt(cdsCutoff)) + .data7(Bytes.ofUnsignedInt(ebsCutoff)) + .data8(Bytes.ofUnsignedInt(subEbs32)) .data9(ZERO); } @@ -69,9 +69,9 @@ public Trace trace(Trace trace) { .pMiscOobData3(bigIntegerToBytes(ebs)) .pMiscOobData4(booleanToBytes(loadLead)) .pMiscOobData5(ZERO) - .pMiscOobData6(Bytes.of(cdsCutoff)) - .pMiscOobData7(Bytes.of(ebsCutoff)) - .pMiscOobData8(Bytes.of(subEbs32)) + .pMiscOobData6(Bytes.ofUnsignedInt(cdsCutoff)) + .pMiscOobData7(Bytes.ofUnsignedInt(ebsCutoff)) + .pMiscOobData8(Bytes.ofUnsignedInt(subEbs32)) .pMiscOobData9(ZERO); } } From 6afdd655a2719ded05fd73f71dd0e53089529958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 19:24:07 +0100 Subject: [PATCH 25/57] fix: remove obsolete columns from RomLex --- .../java/net/consensys/linea/zktracer/module/romlex/RomLex.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java index 02d00cef7e..4438d5e3f4 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomLex.java @@ -272,10 +272,8 @@ private void traceOperation( .codeSize(operation.byteCode().size()) .addressHi(highPart(operation.metadata().address())) .addressLo(lowPart(operation.metadata().address())) - .commitToState(operation.commitToTheState()) .deploymentNumber(operation.metadata().deploymentNumber()) .deploymentStatus(operation.metadata().underDeployment()) - .readFromState(operation.readFromTheState()) .codeHashHi(codeHash.slice(0, LLARGE)) .codeHashLo(codeHash.slice(LLARGE, LLARGE)) .validateRow(); From 95440359c636743e7cc4cc4f1c87159b9e328818 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 19:24:31 +0100 Subject: [PATCH 26/57] feat: more wip on MODEXP testing --- .../callTests/Utilities.java | 2 +- ....java => CallDataParametersForModexp.java} | 22 +++- ...ters.java => CallParametersForModexp.java} | 8 +- .../callTests/prc/CodeExecutionMethods.java | 57 +++++++--- .../callTests/prc/hash/HappyPathTests.java | 16 ++- .../callTests/prc/modexp/HappyPathTests.java | 106 ++++++++++++++---- .../prc/modexp/ParameterGeneration.java | 8 +- 7 files changed, 163 insertions(+), 56 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ModexpCallDataParameters.java => CallDataParametersForModexp.java} (92%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ModexpCallParameters.java => CallParametersForModexp.java} (88%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index 5dc269a56c..cee6aa1c36 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -99,7 +99,7 @@ public static void appendInsufficientBalanceCall( .push(rao) .push(cds) .push(cdo) - .op(BALANCE) + .op(SELFBALANCE) .push(1) .op(ADD) // puts balance + 1 on the stack .push(to) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java similarity index 92% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java index 4b1137ecfd..e0cb7c9291 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java @@ -19,13 +19,13 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -public class ModexpCallDataParameters { +public class CallDataParametersForModexp { public final ByteSizeParameter bbs; public final ByteSizeParameter ebs; public final ByteSizeParameter mbs; public final ModexpCallDataSizeParameter cds; - public ModexpCallDataParameters( + public CallDataParametersForModexp( ByteSizeParameter bbs, ByteSizeParameter ebs, ByteSizeParameter mbs, @@ -40,9 +40,21 @@ public int memorySize(boolean variant) { return 3 * WORD_SIZE + this.bbsShort(variant) + this.ebsShort(variant) + this.mbsShort(variant); } - public String codeWhichWillBecomeMemoryOfModexpCall(boolean variant) { - - String memoryContents = this.bbs(variant).substring(2) + this.ebs(variant).substring(2) + this.mbs(variant).substring(2); + /** + * Constructs a byte string of the form + *

[ bbs | ebs | mbs | BASE | EXPN | MDLS ] + *

where BASE, EXPN and MDLS are the base, exponent and modulus respectively, + * measure bbs, ebs and mbs bytes respectively, and + * bbs, ebs and mbs are 32-byte integers (which the arithmetization + * requires to be ≤ 512 = 0x0200.) + * @return + */ + public String wellFormedCallDataForModexpCall(boolean variant) { + + String memoryContents = + this.bbs(variant).substring(2) + + this.ebs(variant).substring(2) + + this.mbs(variant).substring(2); return memoryContents + (variant ? BASE_512_a : BASE_512_b).substring(0, 2 * this.bbsShort(variant)) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java similarity index 88% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java index f0edfe460f..6880dd5265 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java @@ -16,19 +16,19 @@ import net.consensys.linea.zktracer.opcode.OpCode; -public class ModexpCallParameters { +public class CallParametersForModexp { public final OpCode call; public final GasParameter gas; - public final ModexpCallDataParameters callData; + public final CallDataParametersForModexp callData; public final ReturnAtParameter returnAt; public final RelativeRangePosition relPos; public final boolean willRevert; - public ModexpCallParameters( + public CallParametersForModexp( OpCode call, GasParameter gas, - ModexpCallDataParameters callData, + CallDataParametersForModexp callData, ReturnAtParameter returnAt, RelativeRangePosition relPos, boolean willRevert) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index eabe65f527..b1d2d0e342 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -15,8 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.keyPair; -import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.userAccount; +import static net.consensys.linea.zktracer.instructionprocessing.utilities.MonoOpCodeSmcs.*; import static net.consensys.linea.zktracer.opcode.OpCode.CALL; import static net.consensys.linea.zktracer.opcode.OpCode.GAS; import static org.hyperledger.besu.datatypes.TransactionType.FRONTIER; @@ -33,16 +32,16 @@ /** * The following class provides methods to run code in the following contexts: * - *

- at depth 0 in the root context of a MESSAGE_CALL_TRANSACTION + *

- MESSAGE_CALL_TRANSACTION: at depth 0 in the root context of a * - *

- at depth 0 in the root context of a CONTRACT_DEPLOYMENT_TRANSACTION + *

- CONTRACT_DEPLOYMENT_TRANSACTION: at depth 0 in the root context of a * - *

- at depth 1 in a MESSAGE_CALL_FROM_ROOT, i.e. as code executed in a CALL + *

- MESSAGE_CALL_FROM_ROOT: at depth 1 as the byte code executed in a CALL * - *

- at depth 1 in a DURING_DEPLOYMENT, i.e. as the init code of a CREATE + *

- DURING_DEPLOYMENT: at depth 1 as the init code of a CREATE * - *

- at depth 1 in a AFTER_DEPLOYMENT, i.e. after deploying it with a CREATE and - * calling the newly deployed contract + *

- AFTER_DEPLOYMENT: at depth 1, after deploying it with a CREATE, as the byte code + * executed in a CALL to the newly deployed contract */ public class CodeExecutionMethods { @@ -69,7 +68,7 @@ public class CodeExecutionMethods { .balance(Wei.of(0x2025)) .nonce(0x11aaff); - public static final Address modexpMemoryHolderAddress2 = Address.fromHexString("d00d"); + public static final Address modexpMemoryHolderAddress2 = Address.fromHexString("dada"); public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder2 = ToyAccount.builder() .address(modexpMemoryHolderAddress2) @@ -84,6 +83,26 @@ public class CodeExecutionMethods { .gasLimit(0xffffffL) .value(Wei.of(1_000_000_000L)); + /** + * Construct transaction with {@code transactionInitCode} as its init code. + * + * @param rootCode + */ + public static void runMessageCallTransactionWithProvidedCodeAsRootCode( + BytecodeCompiler rootCode) { + + root.code(rootCode.compile()); + + transaction.to(root.build()); + + ToyExecutionEnvironmentV2.builder() + .transaction(transaction.build()) + .accounts(listOfAccounts()) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); + } + /** * Construct transaction with {@code transactionInitCode} as its init code. * @@ -96,7 +115,7 @@ public static void runDeploymentTransactionWithProvidedCodeAsInitCode( ToyExecutionEnvironmentV2.builder() .transaction(transaction.build()) - .accounts(List.of(userAccount)) + .accounts(listOfAccounts()) .zkTracerValidator(zkTracer -> {}) .build() .run(); @@ -126,7 +145,7 @@ public static void runForeignByteCodeAsInitCode( transaction.to(root.build()); ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), foreignCodeOwner.build())) + .accounts(listOfAccounts()) .transaction(transaction.build()) .build() .run(); @@ -155,7 +174,7 @@ public static void runMessageCallToAccountEndowedWithProvidedCode( transaction.to(root.build()); ToyExecutionEnvironmentV2.builder() - .accounts(List.of(userAccount, root.build(), chadPrcEnjoyer.build())) + .accounts(listOfAccounts()) .transaction(transaction.build()) .build() .run(); @@ -200,10 +219,20 @@ public static void runCreateDeployingForeignCodeAndCallIntoIt( transaction.to(root.build()); ToyExecutionEnvironmentV2.builder() - .accounts( - List.of(userAccount, root.build(), foreignCodeOwner.build(), initCodeOwner.build())) + .accounts(listOfAccounts()) .transaction(transaction.build()) .build() .run(); } + + private static List listOfAccounts() { + return List.of( + userAccount, + root.build(), + initCodeOwner.build(), + foreignCodeOwner.build(), + chadPrcEnjoyer.build(), + modexpMemoryHolder1.build(), + modexpMemoryHolder2.build()); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java index deb9ee2b77..65baa64576 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java @@ -25,6 +25,7 @@ import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import org.hyperledger.besu.datatypes.Wei; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -59,6 +60,7 @@ * *

- play with (precompile) return data */ +@Tag("weekly") public class HappyPathTests { public static Stream happyPathParameterGeneration() { @@ -66,7 +68,9 @@ public static Stream happyPathParameterGeneration() { } /** - * MESSAGE_CALL transaction case + * MESSAGE_CALL_TRANSACTION case. + *

See {@link CodeExecutionMethods} for + * documentation and context. * * @param params */ @@ -75,12 +79,14 @@ public static Stream happyPathParameterGeneration() { public void messageCallTransactionTest(HashPrecompileCallParameters params) { if (!params.willRevert) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } } /** - * CONTRACT_DEPLOYMENT transaction case + * CONTRACT_DEPLOYMENT_TRANSACTION case. + *

See {@link CodeExecutionMethods} for + * documentation and context. * * @param params */ @@ -95,7 +101,9 @@ public void deploymentTransactionTest(HashPrecompileCallParameters params) { } /** - * MESSAGE_CALL_FROM_ROOT case. + * MESSAGE_CALL_FROM_ROOT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. * * @param params */ diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 8451584783..d69f721752 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -16,73 +16,116 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.opcode.OpCode.CALL; -import static net.consensys.linea.zktracer.opcode.OpCode.GAS; +import static net.consensys.linea.zktracer.opcode.OpCode.*; import java.util.stream.Stream; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.testing.BytecodeRunner; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; -import org.hyperledger.besu.datatypes.Wei; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +@Tag("weekly") public class HappyPathTests { private final boolean variant1 = true; private final boolean variant2 = false; /** - * MESSAGE_CALL transaction case + * MESSAGE_CALL_TRANSACTION case. + *

See {@link CodeExecutionMethods} for + * documentation and context. * * @param params */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(ModexpCallParameters params) { - populateCodeOfMemoryHolderAccounts(params); + public void messageCallTransactionTest(CallParametersForModexp params) { + setCodeOfHolderAccounts(params); BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } /** - * Non-parametric test to make sure things are working as expected. + * CONTRACT_DEPLOYMENT_TRANSACTION case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void deploymentTransactionTest(CallParametersForModexp params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 0); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * MESSAGE_CALL_FROM_ROOT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + * + * @param params */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallFromRootTest(CallParametersForModexp params) { + BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); + runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); + } + + /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest() { - ModexpCallDataParameters callDataParameters = new ModexpCallDataParameters( + CallDataParametersForModexp callDataParameters = + new CallDataParametersForModexp( ByteSizeParameter.SMALL, // bbs ByteSizeParameter.SMALL, // ebs ByteSizeParameter.MAX, // mbs ModexpCallDataSizeParameter.MODULUS_FULL // cds - ); - ModexpCallParameters params = new ModexpCallParameters( - CALL, + ); + CallParametersForModexp params = + new CallParametersForModexp( + STATICCALL, GasParameter.FULL, callDataParameters, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, - true - ); - populateCodeOfMemoryHolderAccounts(params); + true); + setCodeOfHolderAccounts(params); BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - BytecodeRunner.of(rootCode).run(Wei.fromEth(1), 61_000_000L); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParameters params) { + /** + * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy path + * testing of MODEXP. This code does the following: + * + *

- populate memory with the data for first MODEXP call + *

- perform first MODEXP call and play around with its return data + *

- wipe return data + *

- populate memory with the data for second MODEXP call + *

- perform second MODEXP call and play around with its return data + * @param params + * @return + */ + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParametersForModexp params) { BytecodeCompiler program = BytecodeCompiler.newProgram(); // populate memory with the data for first MODEXP call copyForeignCodeToRam(program, modexpMemoryHolderAddress1); - // happy path 1 + // happy path: first MODEXP call appendHappyPathPrecompileCall(program, params, variant1); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); loadFirstReturnDataWordOntoStack(program, 0x02ff); @@ -96,7 +139,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParam // populate memory with the data for second MODEXP call copyForeignCodeToRam(program, modexpMemoryHolderAddress2); - // happy path 2 + // happy path: second MODEXP call appendHappyPathPrecompileCall(program, params, variant2); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); loadFirstReturnDataWordOntoStack(program, 0x02ff); @@ -104,10 +147,17 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParam return program; } - private void populateCodeOfMemoryHolderAccounts(ModexpCallParameters params) { + /** + * Populate the byte code of {@link CodeExecutionMethods#modexpMemoryHolder1} and {@link + * CodeExecutionMethods#modexpMemoryHolder2} with "byte code" that is well-formed data for a + * MODEXP call. + * + * @param params + */ + private void setCodeOfHolderAccounts(CallParametersForModexp params) { - String code1 = params.callData.codeWhichWillBecomeMemoryOfModexpCall(variant1); - String code2 = params.callData.codeWhichWillBecomeMemoryOfModexpCall(variant2); + String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); + String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); modexpMemoryHolder1.code(Bytes.fromHexString(code1)); modexpMemoryHolder2.code(Bytes.fromHexString(code2)); @@ -117,8 +167,14 @@ public static Stream happyPathParameterGeneration() { return ParameterGeneration.happyPathParameterGeneration(); } + /** + * Constructs a CALL to the MODEXP precompile in terms of {@link CallParametersForModexp}. + * @param program + * @param params + * @param variant + */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, ModexpCallParameters params, boolean variant) { + BytecodeCompiler program, CallParametersForModexp params, boolean variant) { int cds = params.callData.memorySize(variant); @@ -165,5 +221,7 @@ public void appendHappyPathPrecompileCall( case EXACT_PO -> program.push(cost + 1); case FULL -> program.op(GAS); } + + program.op(params.call); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 1e36936400..822d71ec1a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -66,20 +66,20 @@ public static Stream happyPathParameterGeneration() { for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 argumentsList.add( Arguments.of( - new ModexpCallParameters( + new CallParametersForModexp( opCode, GasParameter.FULL, - new ModexpCallDataParameters(bbs, ebs, mbs, cds), + new CallDataParametersForModexp(bbs, ebs, mbs, cds), returnAt, relPos, false))); argumentsList.add( Arguments.of( - new ModexpCallParameters( + new CallParametersForModexp( opCode, GasParameter.FULL, - new ModexpCallDataParameters(bbs, ebs, mbs, cds), + new CallDataParametersForModexp(bbs, ebs, mbs, cds), returnAt, relPos, false))); From 7d750711daaac00671b24ea51bdec6d07f0af247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 19:24:47 +0100 Subject: [PATCH 27/57] constraints commit update --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index c2bf8fa169..a783218d21 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit c2bf8fa169453319b753a8f1b4c06ef3ce30ba01 +Subproject commit a783218d21af58957b7b3d9ac714da2c57dc3a18 From 44730216fdb108f3acdf02d8da031b4708ef7e69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 19:25:14 +0100 Subject: [PATCH 28/57] feat: @amkCha's gradle dependency fix --- gradle/dependency-management.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gradle/dependency-management.gradle b/gradle/dependency-management.gradle index 66c4c7f0ca..1bbb380c70 100644 --- a/gradle/dependency-management.gradle +++ b/gradle/dependency-management.gradle @@ -32,6 +32,13 @@ repositories { apply plugin: 'io.spring.dependency-management' +dependencies { + constraints { + // Temporarily locking in to avoid https://github.com/netplex/json-smart-v2/issues/240 + api 'net.minidev:json-smart:2.4.2' + } +} + dependencyManagement { applyMavenExclusions = false generatedPomCustomization { From a0db68a8554fa9b9c27d8bbe3e4d3486c1f1975e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 12 Feb 2025 21:06:17 +0100 Subject: [PATCH 29/57] ras: more wip --- .../callTests/prc/ByteSizeParameter.java | 2 +- .../prc/CallDataParametersForModexp.java | 8 +-- ...rModexp.java => ModexpCallParameters.java} | 4 +- .../callTests/prc/hash/HappyPathTests.java | 15 +++-- .../callTests/prc/modexp/HappyPathTests.java | 58 ++++++++++++++----- .../prc/modexp/ParameterGeneration.java | 4 +- 6 files changed, 64 insertions(+), 27 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{CallParametersForModexp.java => ModexpCallParameters.java} (94%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java index cf4d4c60de..a647bb6129 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java @@ -17,6 +17,6 @@ public enum ByteSizeParameter { ZERO, ONE, - SMALL, + MODERATE, MAX; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java index e0cb7c9291..602993c272 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java @@ -66,7 +66,7 @@ private short bbsShort(boolean variant) { return switch (this.bbs) { case ZERO -> 0; case ONE -> 1; - case SMALL -> (short) (variant ? 0x01a3 : 0x0101); + case MODERATE -> (short) (variant ? 0x01a3 : 0x0101); case MAX -> 0x0200; }; } @@ -75,7 +75,7 @@ private short ebsShort(boolean variant) { return switch (this.ebs) { case ZERO -> 0x00; case ONE -> 0x01; - case SMALL -> (short) (variant ? 0xf1 : 0x012a); + case MODERATE -> (short) (variant ? 0xf1 : 0x012a); case MAX -> 0x0200; }; } @@ -84,7 +84,7 @@ private short mbsShort(boolean variant) { return switch (this.mbs) { case ZERO -> 0x00; case ONE -> 0x01; - case SMALL -> (short) (variant ? 0x012f : 0xd1); + case MODERATE -> (short) (variant ? 0x016f : 0xd1); case MAX -> 0x0200; }; } @@ -114,4 +114,4 @@ private String mbs(boolean variant) { "0254e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; static String MDLS_512_b = "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; -} +} \ No newline at end of file diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java similarity index 94% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java index 6880dd5265..533264caa0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallParametersForModexp.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java @@ -16,7 +16,7 @@ import net.consensys.linea.zktracer.opcode.OpCode; -public class CallParametersForModexp { +public class ModexpCallParameters { public final OpCode call; public final GasParameter gas; @@ -25,7 +25,7 @@ public class CallParametersForModexp { public final RelativeRangePosition relPos; public final boolean willRevert; - public CallParametersForModexp( + public ModexpCallParameters( OpCode call, GasParameter gas, CallDataParametersForModexp callData, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java index 65baa64576..61a56963ee 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java @@ -104,8 +104,6 @@ public void deploymentTransactionTest(HashPrecompileCallParameters params) { * MESSAGE_CALL_FROM_ROOT case. *

See {@link CodeExecutionMethods} for * documentation and context. - * - * @param params */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -115,7 +113,11 @@ public void messageCallFromRootTest(HashPrecompileCallParameters params) { } /** - * The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * DURING_DEPLOYMENT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code * of a CREATE. The whole operation optionally REVERT's. @@ -125,17 +127,20 @@ public void messageCallFromRootTest(HashPrecompileCallParameters params) { @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void happyPathDuringCreate(HashPrecompileCallParameters params) { - if (!params.willMxpx()) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); runForeignByteCodeAsInitCode(foreignCode, params.willRevert); } } + /** + * AFTER_DEPLOYMENT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void happyPathAfterCreate(HashPrecompileCallParameters params) { - if (!params.willMxpx()) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); runCreateDeployingForeignCodeAndCallIntoIt(chadPrcEnjoyerCode, params.willRevert); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index d69f721752..84063831c6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -30,7 +30,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -@Tag("weekly") +// @Tag("weekly") public class HappyPathTests { private final boolean variant1 = true; @@ -45,8 +45,7 @@ public class HappyPathTests { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParametersForModexp params) { - setCodeOfHolderAccounts(params); + public void messageCallTransactionTest(ModexpCallParameters params) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } @@ -60,7 +59,7 @@ public void messageCallTransactionTest(CallParametersForModexp params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParametersForModexp params) { + public void deploymentTransactionTest(ModexpCallParameters params) { BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); if (params.willRevert) revertWith(txInitCode, 0, 0); @@ -77,24 +76,55 @@ public void deploymentTransactionTest(CallParametersForModexp params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParametersForModexp params) { + public void messageCallFromRootTest(ModexpCallParameters params) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); } + /** + * DURING_DEPLOYMENT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathDuringCreate(ModexpCallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + } + + /** + * AFTER_DEPLOYMENT case. + *

See {@link CodeExecutionMethods} for + * documentation and context. + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathAfterCreate(ModexpCallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); + } + /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest() { CallDataParametersForModexp callDataParameters = new CallDataParametersForModexp( - ByteSizeParameter.SMALL, // bbs - ByteSizeParameter.SMALL, // ebs + ByteSizeParameter.MODERATE, // bbs + ByteSizeParameter.MODERATE, // ebs ByteSizeParameter.MAX, // mbs ModexpCallDataSizeParameter.MODULUS_FULL // cds ); - CallParametersForModexp params = - new CallParametersForModexp( + ModexpCallParameters params = + new ModexpCallParameters( STATICCALL, GasParameter.FULL, callDataParameters, @@ -118,7 +148,9 @@ public void singleMessageCallTransactionTest() { * @param params * @return */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParametersForModexp params) { + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParameters params) { + + setCodeOfHolderAccounts(params); BytecodeCompiler program = BytecodeCompiler.newProgram(); @@ -154,7 +186,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParametersF * * @param params */ - private void setCodeOfHolderAccounts(CallParametersForModexp params) { + private void setCodeOfHolderAccounts(ModexpCallParameters params) { String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); @@ -168,13 +200,13 @@ public static Stream happyPathParameterGeneration() { } /** - * Constructs a CALL to the MODEXP precompile in terms of {@link CallParametersForModexp}. + * Constructs a CALL to the MODEXP precompile in terms of {@link ModexpCallParameters}. * @param program * @param params * @param variant */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, CallParametersForModexp params, boolean variant) { + BytecodeCompiler program, ModexpCallParameters params, boolean variant) { int cds = params.callData.memorySize(variant); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 822d71ec1a..b0bbe320a9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -66,7 +66,7 @@ public static Stream happyPathParameterGeneration() { for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 argumentsList.add( Arguments.of( - new CallParametersForModexp( + new ModexpCallParameters( opCode, GasParameter.FULL, new CallDataParametersForModexp(bbs, ebs, mbs, cds), @@ -76,7 +76,7 @@ public static Stream happyPathParameterGeneration() { argumentsList.add( Arguments.of( - new CallParametersForModexp( + new ModexpCallParameters( opCode, GasParameter.FULL, new CallDataParametersForModexp(bbs, ebs, mbs, cds), From 5dfec53b9e2cf908527bf13f3c9bbb3cca52b27a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 13 Feb 2025 12:20:45 +0100 Subject: [PATCH 30/57] ras --- .../callTests/prc/modexp/HappyPathTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 84063831c6..1fee02d383 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -30,7 +30,7 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -// @Tag("weekly") +@Tag("weekly") public class HappyPathTests { private final boolean variant1 = true; From d8cd30bf0697d7ba35ac4951ea1f66931a4dca38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 13 Feb 2025 15:36:09 +0100 Subject: [PATCH 31/57] feat: exact cost of MODEXP --- .../callTests/prc/ByteSizeParameter.java | 7 ++ .../prc/CallDataParametersForModexp.java | 84 +++++++++++++++--- .../callTests/prc/CodeExecutionMethods.java | 16 ++-- .../callTests/prc/GasParameter.java | 7 +- .../callTests/prc/hash/HappyPathTests.java | 27 +++--- .../callTests/prc/modexp/HappyPathTests.java | 88 +++++++++++++------ .../prc/modexp/ParameterGeneration.java | 52 +++++------ 7 files changed, 192 insertions(+), 89 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java index a647bb6129..7274a73944 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java @@ -17,6 +17,13 @@ public enum ByteSizeParameter { ZERO, ONE, + /** + * {@link #SHORT} stands for a {@link ByteSizeParameter} that is shorter than 32 bytes. + * This is interesting in particular for the exponent byte size (ebs): pricing necessitates + * extracting the leading word from the exponent, which is poses extra difficulties when the + * exponent is {@link #SHORT}. + */ + SHORT, MODERATE, MAX; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java index 602993c272..a4d91e8544 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java @@ -14,15 +14,25 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +import static com.google.common.base.Preconditions.checkState; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import java.math.BigInteger; + import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; public class CallDataParametersForModexp { + /** base byte size. */ public final ByteSizeParameter bbs; + + /** exponent byte size. */ public final ByteSizeParameter ebs; + + /** modulus byte size. */ public final ByteSizeParameter mbs; + + /** call data size. */ public final ModexpCallDataSizeParameter cds; public CallDataParametersForModexp( @@ -36,36 +46,86 @@ public CallDataParametersForModexp( this.cds = cds; } + public int gasCost(boolean variant) { + return gasCost( + this.bbsShort(variant), this.ebsShort(variant), this.mbsShort(variant), expn(variant)); + } + + /** + * @param bbs + * @param ebs + * @param mbs + * @param Exponent must be a hex string without the 0x prefix + * @return + */ + private int gasCost(short bbs, short ebs, short mbs, String Exponent) { + + int maxBbsMbs = Math.max(bbs, mbs); + int fOfMax = f(maxBbsMbs); + + String leadingWord = + (ebs <= WORD_SIZE) ? Exponent.substring(0, 2 * ebs) : Exponent.substring(0, 2 * WORD_SIZE); + BigInteger leadingWordBigInt = new BigInteger(leadingWord, 16); + checkState(leadingWordBigInt.signum() >= 0, "Leading word must be non-negative"); + int floorOfLog = leadingWordBigInt.bitLength() == 0 ? 0 : leadingWordBigInt.bitLength() - 1; + int lEprime = (ebs <= WORD_SIZE) ? floorOfLog : floorOfLog + 8 * (ebs - WORD_SIZE); + int maxLEprimeOne = Math.max(lEprime, 1); + + return Math.max(200, (fOfMax * maxLEprimeOne) / 3); + } + + private int f(int x) { + int ceil = (x + 7) / 8; + return ceil * ceil; + } + public int memorySize(boolean variant) { return 3 * WORD_SIZE + this.bbsShort(variant) + this.ebsShort(variant) + this.mbsShort(variant); } /** - * Constructs a byte string of the form - *

[ bbs | ebs | mbs | BASE | EXPN | MDLS ] - *

where BASE, EXPN and MDLS are the base, exponent and modulus respectively, - * measure bbs, ebs and mbs bytes respectively, and - * bbs, ebs and mbs are 32-byte integers (which the arithmetization - * requires to be ≤ 512 = 0x0200.) + * Constructs a well-formed a byte string of the form + * + *

[ bbs | ebs | mbs | BASE | EXPN | MDLS ] + * + *

where the base BASE, exponent EXPN and modulus MDLS measure bbs, + * ebs and mbs bytes respectively, and bbs, ebs and mbs are + * 32-byte integers (required to be ≤ 512 = 0x0200 by the arithmetization.) + * * @return */ public String wellFormedCallDataForModexpCall(boolean variant) { + // starting at index 2 eliminates the 0x prefix String memoryContents = this.bbs(variant).substring(2) + this.ebs(variant).substring(2) + this.mbs(variant).substring(2); + // every byte is represented by two hexadecimal characters, whence the factor of 2 return memoryContents - + (variant ? BASE_512_a : BASE_512_b).substring(0, 2 * this.bbsShort(variant)) - + (variant ? EXPN_512_a : EXPN_512_b).substring(0, 2 * this.ebsShort(variant)) - + (variant ? MDLS_512_a : MDLS_512_b).substring(0, 2 * this.mbsShort(variant)); + + base(variant).substring(0, 2 * this.bbsShort(variant)) + + expn(variant).substring(0, 2 * this.ebsShort(variant)) + + mdls(variant).substring(0, 2 * this.mbsShort(variant)); + } + + private String base(boolean variant) { + return variant ? BASE_512_a : BASE_512_b; + } + + private String expn(boolean variant) { + return variant ? EXPN_512_a : EXPN_512_b; + } + + private String mdls(boolean variant) { + return variant ? MDLS_512_a : MDLS_512_b; } private short bbsShort(boolean variant) { return switch (this.bbs) { case ZERO -> 0; case ONE -> 1; + case SHORT -> 0x1f; case MODERATE -> (short) (variant ? 0x01a3 : 0x0101); case MAX -> 0x0200; }; @@ -75,6 +135,7 @@ private short ebsShort(boolean variant) { return switch (this.ebs) { case ZERO -> 0x00; case ONE -> 0x01; + case SHORT -> 0x12; case MODERATE -> (short) (variant ? 0xf1 : 0x012a); case MAX -> 0x0200; }; @@ -84,6 +145,7 @@ private short mbsShort(boolean variant) { return switch (this.mbs) { case ZERO -> 0x00; case ONE -> 0x01; + case SHORT -> 0x0d; case MODERATE -> (short) (variant ? 0x016f : 0xd1); case MAX -> 0x0200; }; @@ -111,7 +173,7 @@ private String mbs(boolean variant) { static String BASE_512_b = "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; static String EXPN_512_b = - "0254e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; static String MDLS_512_b = "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; -} \ No newline at end of file +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index b1d2d0e342..8770b5a215 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -40,8 +40,8 @@ * *

- DURING_DEPLOYMENT: at depth 1 as the init code of a CREATE * - *

- AFTER_DEPLOYMENT: at depth 1, after deploying it with a CREATE, as the byte code - * executed in a CALL to the newly deployed contract + *

- AFTER_DEPLOYMENT: at depth 1, after deploying it with a CREATE, as the byte + * code executed in a CALL to the newly deployed contract */ public class CodeExecutionMethods { @@ -89,18 +89,18 @@ public class CodeExecutionMethods { * @param rootCode */ public static void runMessageCallTransactionWithProvidedCodeAsRootCode( - BytecodeCompiler rootCode) { + BytecodeCompiler rootCode) { root.code(rootCode.compile()); transaction.to(root.build()); ToyExecutionEnvironmentV2.builder() - .transaction(transaction.build()) - .accounts(listOfAccounts()) - .zkTracerValidator(zkTracer -> {}) - .build() - .run(); + .transaction(transaction.build()) + .accounts(listOfAccounts()) + .zkTracerValidator(zkTracer -> {}) + .build() + .run(); } /** diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java index 33d97a449a..c8765f2006 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java @@ -14,10 +14,11 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +/** Enumerates the different gas parameters for a precompile call. */ public enum GasParameter { ZERO, - EXACT_MO, // MO ≡ minus one - EXACT, - EXACT_PO, // PO ≡ plus one + COST_MO, // MO ≡ minus one + COST, FULL, + MAX } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java index 61a56963ee..bb31cb6818 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java @@ -24,7 +24,6 @@ import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import org.hyperledger.besu.datatypes.Wei; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -69,8 +68,8 @@ public static Stream happyPathParameterGeneration() { /** * MESSAGE_CALL_TRANSACTION case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * * @param params */ @@ -85,8 +84,8 @@ public void messageCallTransactionTest(HashPrecompileCallParameters params) { /** * CONTRACT_DEPLOYMENT_TRANSACTION case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * * @param params */ @@ -102,8 +101,8 @@ public void deploymentTransactionTest(HashPrecompileCallParameters params) { /** * MESSAGE_CALL_FROM_ROOT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -114,8 +113,8 @@ public void messageCallFromRootTest(HashPrecompileCallParameters params) { /** * DURING_DEPLOYMENT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the @@ -135,8 +134,8 @@ public void happyPathDuringCreate(HashPrecompileCallParameters params) { /** * AFTER_DEPLOYMENT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -195,10 +194,10 @@ public void appendHappyPathPrecompileCall( int cost = params.prc.cost(callDataSize); switch (params.gas) { case ZERO -> program.push(0); - case EXACT_MO -> program.push(cost - 1); - case EXACT -> program.push(cost); - case EXACT_PO -> program.push(cost + 1); + case COST_MO -> program.push(cost - 1); + case COST -> program.push(cost); case FULL -> program.op(GAS); + case MAX -> program.push("ff".repeat(32)); } program.op(params.call); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 1fee02d383..d6b1d8f792 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -15,6 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ByteSizeParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -22,6 +23,7 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.module.constants.GlobalConstants; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; import org.junit.jupiter.api.Tag; @@ -38,8 +40,8 @@ public class HappyPathTests { /** * MESSAGE_CALL_TRANSACTION case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * * @param params */ @@ -52,8 +54,8 @@ public void messageCallTransactionTest(ModexpCallParameters params) { /** * CONTRACT_DEPLOYMENT_TRANSACTION case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * * @param params */ @@ -69,8 +71,8 @@ public void deploymentTransactionTest(ModexpCallParameters params) { /** * MESSAGE_CALL_FROM_ROOT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * * @param params */ @@ -83,8 +85,8 @@ public void messageCallFromRootTest(ModexpCallParameters params) { /** * DURING_DEPLOYMENT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. * *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the @@ -96,37 +98,59 @@ public void messageCallFromRootTest(ModexpCallParameters params) { @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void happyPathDuringCreate(ModexpCallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); } /** * AFTER_DEPLOYMENT case. - *

See {@link CodeExecutionMethods} for - * documentation and context. + * + *

See {@link CodeExecutionMethods} for documentation and context. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void happyPathAfterCreate(ModexpCallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); } /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest() { + CallDataParametersForModexp callDataParameters = + new CallDataParametersForModexp( + MODERATE, // bbs + MODERATE, // ebs + MAX, // mbs + ModexpCallDataSizeParameter.MODULUS_FULL // cds + ); + ModexpCallParameters params = + new ModexpCallParameters( + CALL, + GasParameter.COST_MO, + callDataParameters, + ReturnAtParameter.FULL, + RelativeRangePosition.OVERLAP, + true); + setCodeOfHolderAccounts(params); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest2() { CallDataParametersForModexp callDataParameters = new CallDataParametersForModexp( - ByteSizeParameter.MODERATE, // bbs - ByteSizeParameter.MODERATE, // ebs - ByteSizeParameter.MAX, // mbs + MAX, // bbs + SHORT, // ebs + MODERATE, // mbs ModexpCallDataSizeParameter.MODULUS_FULL // cds ); ModexpCallParameters params = new ModexpCallParameters( STATICCALL, - GasParameter.FULL, + GasParameter.COST, callDataParameters, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, @@ -137,14 +161,19 @@ public void singleMessageCallTransactionTest() { } /** - * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy path - * testing of MODEXP. This code does the following: + * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy + * path testing of MODEXP. This code does the following: * *

- populate memory with the data for first MODEXP call + * *

- perform first MODEXP call and play around with its return data + * *

- wipe return data + * *

- populate memory with the data for second MODEXP call + * *

- perform second MODEXP call and play around with its return data + * * @param params * @return */ @@ -201,12 +230,13 @@ public static Stream happyPathParameterGeneration() { /** * Constructs a CALL to the MODEXP precompile in terms of {@link ModexpCallParameters}. + * * @param program * @param params * @param variant */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, ModexpCallParameters params, boolean variant) { + BytecodeCompiler program, ModexpCallParameters params, boolean variant) { int cds = params.callData.memorySize(variant); @@ -236,22 +266,26 @@ public void appendHappyPathPrecompileCall( // pushing zero value onto the stack if (params.call.callHasValueArgument()) { - program.push(0); + program.push(1); } // pushing MODEXP address onto the stack program.push(Address.MODEXP); - // TODO: replace with actual gas price - int cost = 10_000; + int modexpGasCost = params.callData.gasCost(variant); + int gasParam = + (params.call.callHasValueArgument() + && modexpGasCost >= GlobalConstants.GAS_CONST_G_CALL_STIPEND) + ? modexpGasCost - GlobalConstants.GAS_CONST_G_CALL_STIPEND + : modexpGasCost; // pushing gas onto the stack switch (params.gas) { case ZERO -> program.push(0); - case EXACT_MO -> program.push(cost - 1); - case EXACT -> program.push(cost); - case EXACT_PO -> program.push(cost + 1); + case COST_MO -> program.push(gasParam - 1); + case COST -> program.push(gasParam); case FULL -> program.op(GAS); + case MAX -> program.push("ff".repeat(32)); } program.op(params.call); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index b0bbe320a9..874cba3d2b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -57,32 +57,33 @@ public static Stream happyPathParameterGeneration() { List argumentsList = new ArrayList<>(); for (OpCode opCode : CallOpCodes) { // 4 - // for (GasParameter gas : GasParameter.values()) { // 5 - for (ByteSizeParameter bbs : ByteSizeParameter.values()) { // 4 - for (ByteSizeParameter ebs : ByteSizeParameter.values()) { // 4 - for (ByteSizeParameter mbs : ByteSizeParameter.values()) { // 4 - for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { // 9 - for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { // 4 - for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - GasParameter.FULL, - new CallDataParametersForModexp(bbs, ebs, mbs, cds), - returnAt, - relPos, - false))); + for (GasParameter gas : GasParameter.values()) { // 5 + for (ByteSizeParameter bbs : ByteSizeParameter.values()) { // 5 + for (ByteSizeParameter ebs : ByteSizeParameter.values()) { // 5 + for (ByteSizeParameter mbs : ByteSizeParameter.values()) { // 5 + for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { // 9 + for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { // 4 + for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new CallDataParametersForModexp(bbs, ebs, mbs, cds), + returnAt, + relPos, + false))); - argumentsList.add( - Arguments.of( - new ModexpCallParameters( - opCode, - GasParameter.FULL, - new CallDataParametersForModexp(bbs, ebs, mbs, cds), - returnAt, - relPos, - false))); + argumentsList.add( + Arguments.of( + new ModexpCallParameters( + opCode, + gas, + new CallDataParametersForModexp(bbs, ebs, mbs, cds), + returnAt, + relPos, + true))); + } } } } @@ -90,7 +91,6 @@ public static Stream happyPathParameterGeneration() { } } } - // } return argumentsList.stream(); } } From ad253f4f9fcf24ea533967f32b7aa4e3e28e5ce9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 13 Feb 2025 16:45:22 +0100 Subject: [PATCH 32/57] ras: refactoring --- .../prc/{ => hash}/HashPrecompile.java | 2 +- .../HashPrecompileCallParameters.java | 3 +- .../prc/{ => modexp}/ByteSizeParameter.java | 2 +- .../CallDataParameter.java} | 10 ++--- .../CallDataSizeParameter.java} | 6 +-- .../CallParameter.java} | 13 +++--- .../callTests/prc/modexp/HappyPathTests.java | 44 +++++++++---------- .../prc/modexp/ParameterGeneration.java | 12 ++--- 8 files changed, 48 insertions(+), 44 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ => hash}/HashPrecompile.java (99%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ => hash}/HashPrecompileCallParameters.java (95%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ => modexp}/ByteSizeParameter.java (98%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{CallDataParametersForModexp.java => modexp/CallDataParameter.java} (98%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ModexpCallDataSizeParameter.java => modexp/CallDataSizeParameter.java} (92%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{ModexpCallParameters.java => modexp/CallParameter.java} (74%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompile.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompile.java index 7400cdcde6..592d36833a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompile.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompile.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; import static com.google.common.base.Preconditions.checkArgument; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java similarity index 95% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java index 6c96066803..91db98766e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/HashPrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java @@ -12,8 +12,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import net.consensys.linea.zktracer.opcode.OpCode; public class HashPrecompileCallParameters { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java similarity index 98% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java index 7274a73944..2f8f1b788d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ByteSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; public enum ByteSizeParameter { ZERO, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java similarity index 98% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java index a4d91e8544..faddafee7c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CallDataParametersForModexp.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; import static com.google.common.base.Preconditions.checkState; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; @@ -22,7 +22,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -public class CallDataParametersForModexp { +public class CallDataParameter { /** base byte size. */ public final ByteSizeParameter bbs; @@ -33,13 +33,13 @@ public class CallDataParametersForModexp { public final ByteSizeParameter mbs; /** call data size. */ - public final ModexpCallDataSizeParameter cds; + public final CallDataSizeParameter cds; - public CallDataParametersForModexp( + public CallDataParameter( ByteSizeParameter bbs, ByteSizeParameter ebs, ByteSizeParameter mbs, - ModexpCallDataSizeParameter cds) { + CallDataSizeParameter cds) { this.bbs = bbs; this.ebs = ebs; this.mbs = mbs; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataSizeParameter.java similarity index 92% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataSizeParameter.java index 47e1d3819f..3a464c0f1c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataSizeParameter.java @@ -12,10 +12,10 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; /** - * {@link ModexpCallDataSizeParameter} represents different call data sizes for CALL's to the + * {@link CallDataSizeParameter} represents different call data sizes for CALL's to the * MODEXP precompile. The interpretation goes as follows: * *

- {@link #EMPTY} for empty call data (cds ≡ 0) @@ -38,7 +38,7 @@ * *

- {@link #LARGE} for call data larger than required (cds > 96 + bbs + bbs + mbs) */ -public enum ModexpCallDataSizeParameter { +public enum CallDataSizeParameter { EMPTY, BBS, EBS, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java similarity index 74% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java index 533264caa0..5b0ec5996b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ModexpCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java @@ -12,23 +12,26 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; import net.consensys.linea.zktracer.opcode.OpCode; -public class ModexpCallParameters { +public class CallParameter { public final OpCode call; public final GasParameter gas; - public final CallDataParametersForModexp callData; + public final CallDataParameter callData; public final ReturnAtParameter returnAt; public final RelativeRangePosition relPos; public final boolean willRevert; - public ModexpCallParameters( + public CallParameter( OpCode call, GasParameter gas, - CallDataParametersForModexp callData, + CallDataParameter callData, ReturnAtParameter returnAt, RelativeRangePosition relPos, boolean willRevert) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index d6b1d8f792..0132209c87 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -15,7 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ByteSizeParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -47,7 +47,7 @@ public class HappyPathTests { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(ModexpCallParameters params) { + public void messageCallTransactionTest(CallParameter params) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } @@ -61,7 +61,7 @@ public void messageCallTransactionTest(ModexpCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(ModexpCallParameters params) { + public void deploymentTransactionTest(CallParameter params) { BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); if (params.willRevert) revertWith(txInitCode, 0, 0); @@ -78,7 +78,7 @@ public void deploymentTransactionTest(ModexpCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(ModexpCallParameters params) { + public void messageCallFromRootTest(CallParameter params) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); } @@ -97,7 +97,7 @@ public void messageCallFromRootTest(ModexpCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(ModexpCallParameters params) { + public void happyPathDuringCreate(CallParameter params) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); runForeignByteCodeAsInitCode(foreignCode, params.willRevert); } @@ -109,7 +109,7 @@ public void happyPathDuringCreate(ModexpCallParameters params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(ModexpCallParameters params) { + public void happyPathAfterCreate(CallParameter params) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); } @@ -117,18 +117,18 @@ public void happyPathAfterCreate(ModexpCallParameters params) { /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest() { - CallDataParametersForModexp callDataParameters = - new CallDataParametersForModexp( + CallDataParameter callDataParameter = + new CallDataParameter( MODERATE, // bbs MODERATE, // ebs MAX, // mbs - ModexpCallDataSizeParameter.MODULUS_FULL // cds + CallDataSizeParameter.MODULUS_FULL // cds ); - ModexpCallParameters params = - new ModexpCallParameters( + CallParameter params = + new CallParameter( CALL, GasParameter.COST_MO, - callDataParameters, + callDataParameter, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, true); @@ -140,18 +140,18 @@ public void singleMessageCallTransactionTest() { /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest2() { - CallDataParametersForModexp callDataParameters = - new CallDataParametersForModexp( + CallDataParameter callDataParameter = + new CallDataParameter( MAX, // bbs SHORT, // ebs MODERATE, // mbs - ModexpCallDataSizeParameter.MODULUS_FULL // cds + CallDataSizeParameter.MODULUS_FULL // cds ); - ModexpCallParameters params = - new ModexpCallParameters( + CallParameter params = + new CallParameter( STATICCALL, GasParameter.COST, - callDataParameters, + callDataParameter, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, true); @@ -177,7 +177,7 @@ public void singleMessageCallTransactionTest2() { * @param params * @return */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParameters params) { + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameter params) { setCodeOfHolderAccounts(params); @@ -215,7 +215,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(ModexpCallParam * * @param params */ - private void setCodeOfHolderAccounts(ModexpCallParameters params) { + private void setCodeOfHolderAccounts(CallParameter params) { String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); @@ -229,14 +229,14 @@ public static Stream happyPathParameterGeneration() { } /** - * Constructs a CALL to the MODEXP precompile in terms of {@link ModexpCallParameters}. + * Constructs a CALL to the MODEXP precompile in terms of {@link CallParameter}. * * @param program * @param params * @param variant */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, ModexpCallParameters params, boolean variant) { + BytecodeCompiler program, CallParameter params, boolean variant) { int cds = params.callData.memorySize(variant); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 874cba3d2b..efb56496ec 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -38,7 +38,7 @@ public class ParameterGeneration { *

- {@code bbs}, {@code ebs}, {@code mbs} are {@link ByteSizeParameter} values for * MODEXP, either 0, 1, something small, or the maximum (512) * - *

- {@code cds} is one of the {@link ModexpCallDataSizeParameter} values, which dictates how + *

- {@code cds} is one of the {@link CallDataSizeParameter} values, which dictates how * much of the parameters in RAM (bbs, ebs, mbs, BASE, EXPONENT * and MODULUS) actually get passed down to MODEXP * @@ -61,25 +61,25 @@ public static Stream happyPathParameterGeneration() { for (ByteSizeParameter bbs : ByteSizeParameter.values()) { // 5 for (ByteSizeParameter ebs : ByteSizeParameter.values()) { // 5 for (ByteSizeParameter mbs : ByteSizeParameter.values()) { // 5 - for (ModexpCallDataSizeParameter cds : ModexpCallDataSizeParameter.values()) { // 9 + for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 9 for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { // 4 for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 argumentsList.add( Arguments.of( - new ModexpCallParameters( + new CallParameter( opCode, gas, - new CallDataParametersForModexp(bbs, ebs, mbs, cds), + new CallDataParameter(bbs, ebs, mbs, cds), returnAt, relPos, false))); argumentsList.add( Arguments.of( - new ModexpCallParameters( + new CallParameter( opCode, gas, - new CallDataParametersForModexp(bbs, ebs, mbs, cds), + new CallDataParameter(bbs, ebs, mbs, cds), returnAt, relPos, true))); From e458e868006ca748cfafee71d8abb5aaaec943e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 13 Feb 2025 23:17:05 +0100 Subject: [PATCH 33/57] ras --- .../prc/modexp/CallDataParameter.java | 28 ++++++++------- ...CallParameter.java => CallParameters.java} | 4 +-- .../callTests/prc/modexp/HappyPathTests.java | 34 ++++++++----------- .../prc/modexp/ParameterGeneration.java | 9 ++--- 4 files changed, 37 insertions(+), 38 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/{CallParameter.java => CallParameters.java} (96%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java index faddafee7c..0e5e418a3c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java @@ -23,6 +23,21 @@ import org.apache.tuweni.bytes.Bytes32; public class CallDataParameter { + + private static final String BASE_512_a = + "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; + private static final String EXPN_512_a = + "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; + private static final String MDLS_512_a = + "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; + + private static final String BASE_512_b = + "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; + private static final String EXPN_512_b = + "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + private static final String MDLS_512_b = + "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; + /** base byte size. */ public final ByteSizeParameter bbs; @@ -163,17 +178,4 @@ private String mbs(boolean variant) { return Bytes32.leftPad(Bytes.ofUnsignedShort(mbsShort(variant))).toString(); } - static String BASE_512_a = - "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; - static String EXPN_512_a = - "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; - static String MDLS_512_a = - "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; - - static String BASE_512_b = - "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; - static String EXPN_512_b = - "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; - static String MDLS_512_b = - "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java similarity index 96% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java index 5b0ec5996b..06b1d312e9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java @@ -19,7 +19,7 @@ import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; import net.consensys.linea.zktracer.opcode.OpCode; -public class CallParameter { +public class CallParameters { public final OpCode call; public final GasParameter gas; @@ -28,7 +28,7 @@ public class CallParameter { public final RelativeRangePosition relPos; public final boolean willRevert; - public CallParameter( + public CallParameters( OpCode call, GasParameter gas, CallDataParameter callData, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 0132209c87..8a2aadfaba 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -39,15 +39,11 @@ public class HappyPathTests { private final boolean variant2 = false; /** - * MESSAGE_CALL_TRANSACTION case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - * @param params + * MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParameter params) { + public void messageCallTransactionTest(CallParameters params) { BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } @@ -61,7 +57,7 @@ public void messageCallTransactionTest(CallParameter params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParameter params) { + public void deploymentTransactionTest(CallParameters params) { BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); if (params.willRevert) revertWith(txInitCode, 0, 0); @@ -78,7 +74,7 @@ public void deploymentTransactionTest(CallParameter params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParameter params) { + public void messageCallFromRootTest(CallParameters params) { BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); } @@ -97,7 +93,7 @@ public void messageCallFromRootTest(CallParameter params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(CallParameter params) { + public void happyPathDuringCreate(CallParameters params) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); runForeignByteCodeAsInitCode(foreignCode, params.willRevert); } @@ -109,7 +105,7 @@ public void happyPathDuringCreate(CallParameter params) { */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(CallParameter params) { + public void happyPathAfterCreate(CallParameters params) { BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); } @@ -124,8 +120,8 @@ public void singleMessageCallTransactionTest() { MAX, // mbs CallDataSizeParameter.MODULUS_FULL // cds ); - CallParameter params = - new CallParameter( + CallParameters params = + new CallParameters( CALL, GasParameter.COST_MO, callDataParameter, @@ -147,8 +143,8 @@ public void singleMessageCallTransactionTest2() { MODERATE, // mbs CallDataSizeParameter.MODULUS_FULL // cds ); - CallParameter params = - new CallParameter( + CallParameters params = + new CallParameters( STATICCALL, GasParameter.COST, callDataParameter, @@ -177,7 +173,7 @@ public void singleMessageCallTransactionTest2() { * @param params * @return */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameter params) { + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { setCodeOfHolderAccounts(params); @@ -215,7 +211,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameter p * * @param params */ - private void setCodeOfHolderAccounts(CallParameter params) { + private void setCodeOfHolderAccounts(CallParameters params) { String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); @@ -229,14 +225,14 @@ public static Stream happyPathParameterGeneration() { } /** - * Constructs a CALL to the MODEXP precompile in terms of {@link CallParameter}. + * Constructs a CALL to the MODEXP precompile in terms of {@link CallParameters}. * * @param program * @param params * @param variant */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, CallParameter params, boolean variant) { + BytecodeCompiler program, CallParameters params, boolean variant) { int cds = params.callData.memorySize(variant); @@ -264,7 +260,7 @@ public void appendHappyPathPrecompileCall( // pushing cdo onto the stack program.push(0); - // pushing zero value onto the stack + // pushing value onto the stack if (params.call.callHasValueArgument()) { program.push(1); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index efb56496ec..d17141af78 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -64,25 +64,26 @@ public static Stream happyPathParameterGeneration() { for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 9 for (ReturnAtParameter returnAt : ReturnAtParameter.values()) { // 4 for (RelativeRangePosition relPos : RelativeRangePosition.values()) { // 2 + argumentsList.add( Arguments.of( - new CallParameter( + new CallParameters( opCode, gas, new CallDataParameter(bbs, ebs, mbs, cds), returnAt, relPos, - false))); + true))); argumentsList.add( Arguments.of( - new CallParameter( + new CallParameters( opCode, gas, new CallDataParameter(bbs, ebs, mbs, cds), returnAt, relPos, - true))); + false))); } } } From 707e4cc48a1212c2f1f5f6f49278dbab99ff1e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Thu, 13 Feb 2025 23:17:13 +0100 Subject: [PATCH 34/57] feat: ECADD tests --- .../prc/ecadd/CallDataSizeParameter.java | 29 +++ .../callTests/prc/ecadd/CallParameters.java | 48 +++++ .../callTests/prc/ecadd/HappyPathTests.java | 186 ++++++++++++++++++ .../prc/ecadd/MemoryContentParameter.java | 104 ++++++++++ .../prc/ecadd/ParameterGeneration.java | 60 ++++++ 5 files changed, 427 insertions(+) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java new file mode 100644 index 0000000000..b67ffa8508 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java @@ -0,0 +1,29 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +public enum CallDataSizeParameter { + ZERO, + NONEMPTY_1f, + NONEMPTY_20, + NONEMPTY_3f, + NONEMPTY_40, + NONEMPTY_5f, + NONEMPTY_60, + NONEMPTY_7f, + NONEMPTY_80, + FULL, + LARGE +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java new file mode 100644 index 0000000000..63dfbee0c8 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java @@ -0,0 +1,48 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; + +public class CallParameters { + + public final OpCode call; + public final GasParameter gas; + public final MemoryContentParameter memoryContent; + public final CallDataSizeParameter cds; + public final ReturnAtParameter returnAt; + public final boolean willRevert; + + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContentParameter memoryContent, + CallDataSizeParameter cds, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContent = memoryContent; + this.cds = cds; + this.returnAt = returnAt; + this.willRevert = willRevert; + } + + public void switchVariants() { + memoryContent.switchVariants(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java new file mode 100644 index 0000000000..8921a5c5ab --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -0,0 +1,186 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.CallDataParameter; +import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.modexpMemoryHolderAddress2; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.MAX; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.MODERATE; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + + +public class HappyPathTests { + + /** + * MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallTransactionTest(CallParameters params) { + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + GasParameter.COST_MO, + MemoryContentParameter.WELLFORMED_POINTS, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); + + setCodeOfHolderAccounts(params); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + + /** + * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy + * path testing of MODEXP. This code does the following: + * + *

- populate memory with the data for first MODEXP call + * + *

- perform first MODEXP call and play around with its return data + * + *

- wipe return data + * + *

- populate memory with the data for second MODEXP call + * + *

- perform second MODEXP call and play around with its return data + * + * @param params + * @return + */ +private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { + + setCodeOfHolderAccounts(params); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first MODEXP call + copyForeignCodeToRam(program, modexpMemoryHolderAddress1); + + // happy path: first MODEXP call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("c0ffeebabe"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second MODEXP call + copyForeignCodeToRam(program, modexpMemoryHolderAddress2); + + // happy path: second MODEXP call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + return program; +} + + private void setCodeOfHolderAccounts(CallParameters params) { + + BytecodeCompiler code1 = params.memoryContent.memoryContents(); + params.switchVariants(); + + BytecodeCompiler code2 = params.memoryContent.memoryContents(); + + modexpMemoryHolder1.code(code1.compile()); + modexpMemoryHolder2.code(code1.compile()); + } + + public static Stream happyPathParameterGeneration() { + return ParameterGeneration.happyPathParameterGeneration(); + } + + /** + * Constructs a call to the ECADD precompile in terms of {@link CallParameters}. + */ + public void appendHappyPathPrecompileCall( + BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case ZERO -> program.push(0); + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_3f -> program.push(0x3f); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_5f -> program.push(0x5f); + case NONEMPTY_60 -> program.push(0x60); + case NONEMPTY_7f -> program.push(0x7f); + case NONEMPTY_80 -> program.push(0x80); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(params.willRevert ? 0x0200 : 0); + } + + program.push(Address.ALTBN128_ADD); + + // push gas onto the stack + switch (params.gas) { + case ZERO -> program.push(0); // remains interesting in the nonzero value case + case COST_MO -> program.push(149); + case COST -> program.push(150); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(params.call); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java new file mode 100644 index 0000000000..507bf75eb7 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java @@ -0,0 +1,104 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE_MO; + +import net.consensys.linea.testing.BytecodeCompiler; + +public enum MemoryContentParameter { + ZEROS, + WELLFORMED_POINTS, + MIXED, + MALFORMED_AT_1f, + MALFORMED_AT_3f, + MALFORMED_AT_5f, + MALFORMED_AT_7f, + RANDOM, + MAX; + + boolean variant = false; + + public void switchVariants() { + variant = !variant; + } + + // coordinates for 5 curve points + private static final String A_X = + "08d555288636cfb5abeac1d38a828fc4d975fb8def9f63a34f8c91701b5478d1"; + private static final String A_Y = + "2fe58eb05ff7bed143c398b0b62e18e8b0327a3be8250b2923ea29e6773a65f5"; + private static final String B_X = + "0d89e2e42be7fbda9358a2689c73af3ecd519728359f175ee7919d31c8f61d5d"; + private static final String B_Y = + "0eb7c8cfbbe0a89bf12697e97b482c3a91ff985ba456f1684a0b68efa2933019"; + private static final String C_X = + "070375d4eec4f22aa3ad39cb40ccd73d2dbab6de316e75f81dc2948a996795d5"; + private static final String C_Y = + "041b98f07f44aa55ce8bd97e32cacf55f1e42229d540d5e7a767d1138a5da656"; + private static final String D_X = + "185f6f5cf93c8afa0461a948c2da7c403b6f8477c488155dfa8d2da1c62517b8"; + private static final String D_Y = + "13d83d7a51eb18fdb51225873c87d44f883e770ce2ca56c305d02d6cb99ca5b8"; + private static final String RND = + "e2db57e640f49001c04ca5cb36e72f97af535c4d7620a48b96f8d0475afcaee569dcf211255b9ce6c05178cdf45152650496523591db85dadc328f6cb57e94ad83a66cca880b9fc02154c6941457158585230a843f38778f1d4cd6cbb42c778bcc5f05ab1c8306b59db726b705e3f782017a4dcaa04694b5c62e645445ede56b"; + + /** + * Constructs "byte code" of the following form + * + *

[ W_1 | W_2 | W_3 | W_4 | ff .. ff ] + * + *

for various EVM words W_k. These may or may not contain x/y coordinates of curve points. + * The final 32 bytes are all set to ff and may get overwritten with return + * data after the precompile call. + * + *

Note. The purpose of the resulting 'byte code' is to be EXTCODECOPY'ed to + * memory and used as input to a call to ECADD. + */ + public BytecodeCompiler memoryContents() { + + final String ZERO = "00".repeat(WORD_SIZE); + final String MAX_BYTE = "00".repeat(WORD_SIZE_MO) + "ff"; + final String MAX_WORD = "ff".repeat(WORD_SIZE); + + // Note that 4 = 2 * 2. We need 4 * 32 hex characters for the data representing a point. + String pointData = + switch (this) { + case ZEROS -> "00".repeat(4 * WORD_SIZE); + case WELLFORMED_POINTS -> variant ? A_X + A_Y + B_X + B_Y : C_X + C_Y + D_X + D_Y; + case MIXED -> variant + ? A_X + A_Y + RND.substring(13, 13 + 4 * WORD_SIZE) + : C_X + C_Y + RND.substring(99, 99 + 4 * WORD_SIZE); + case MALFORMED_AT_1f -> MAX_BYTE + (variant ? A_Y + B_X + B_Y : C_Y + D_X + D_Y); + case MALFORMED_AT_3f -> ZERO + MAX_BYTE + (variant ? B_X + B_Y : D_X + D_Y); + case MALFORMED_AT_5f -> ZERO.repeat(2) + MAX_BYTE + (variant ? B_Y : D_Y); + case MALFORMED_AT_7f -> ZERO.repeat(3) + MAX_BYTE; + case RANDOM -> RND; + case MAX -> MAX_WORD.repeat(4); + }; + + final boolean correctLength = pointData.length() == 2 * 4 * WORD_SIZE; + checkState(correctLength); + + String memoryContentsString = pointData + MAX_WORD; + + BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); + memoryContents.immediate(memoryContentsString.getBytes()); + + return memoryContents; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java new file mode 100644 index 0000000000..5dcf4ce51e --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -0,0 +1,60 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + +public class ParameterGeneration { + + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + List GasParameters = + List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); + List ReturnAtParameters = + List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { // 4 + for (GasParameter gas : GasParameters) { // 4 + for (MemoryContentParameter memoryContent : MemoryContentParameter.values()) { // 9 + for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, true))); + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, false))); + } + } + } + } + } + return argumentsList.stream(); + } +} From e021a44a2a7077336e1b5ae3ba78c96821cb2b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 14 Feb 2025 01:15:07 +0100 Subject: [PATCH 35/57] feat: fixed typo in sstore method --- .../instructionprocessing/callTests/Utilities.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index cee6aa1c36..e19f42c29c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -288,25 +288,17 @@ public static void copyForeignCodeToRam(BytecodeCompiler program, Address foreig } public static void sstoreTopOfStackTo(BytecodeCompiler program, int storageKey) { - program.push(storageKey).op(MSTORE); + program.push(storageKey).op(SSTORE); } public static void sloadFrom(BytecodeCompiler program, int storageKey) { program.push(storageKey).op(SLOAD); } - public static void rightShiftTopOfStackToProduceAddress(BytecodeCompiler program) { - program.push(8 * 12).op(SHR); - } - public static void revertWith(BytecodeCompiler program, int offset, int size) { program.push(size).push(offset).op(REVERT); } - public static void callDataLoadFrom(BytecodeCompiler program, int offset) { - program.push(offset).op(CALLDATALOAD); - } - public static void pushSeveral(BytecodeCompiler program, int... values) { for (int value : values) { program.push(value); From f8d673026304d4696331bb99ffbb2c76f4b73875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 14 Feb 2025 01:15:27 +0100 Subject: [PATCH 36/57] feat: the remaining ECADD tests --- .../callTests/prc/CodeExecutionMethods.java | 16 ++-- .../callTests/prc/ecadd/HappyPathTests.java | 73 ++++++++++++++++--- .../prc/ecadd/MemoryContentParameter.java | 20 +++-- .../prc/ecadd/ParameterGeneration.java | 3 + .../callTests/prc/modexp/HappyPathTests.java | 36 ++++----- 5 files changed, 101 insertions(+), 47 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index 8770b5a215..f21cd22364 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -61,17 +61,17 @@ public class CodeExecutionMethods { public static final ToyAccount.ToyAccountBuilder foreignCodeOwner = ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); - public static final Address modexpMemoryHolderAddress1 = Address.fromHexString("d00d"); - public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder1 = + public static final Address codeHolderAddress1 = Address.fromHexString("d00d"); + public static final ToyAccount.ToyAccountBuilder codeHolder1 = ToyAccount.builder() - .address(modexpMemoryHolderAddress1) + .address(codeHolderAddress1) .balance(Wei.of(0x2025)) .nonce(0x11aaff); - public static final Address modexpMemoryHolderAddress2 = Address.fromHexString("dada"); - public static final ToyAccount.ToyAccountBuilder modexpMemoryHolder2 = + public static final Address codeHolderAddress2 = Address.fromHexString("dada"); + public static final ToyAccount.ToyAccountBuilder codeHolder2 = ToyAccount.builder() - .address(modexpMemoryHolderAddress2) + .address(codeHolderAddress2) .balance(Wei.of(0x2025)) .nonce(0x11aaff); @@ -232,7 +232,7 @@ private static List listOfAccounts() { initCodeOwner.build(), foreignCodeOwner.build(), chadPrcEnjoyer.build(), - modexpMemoryHolder1.build(), - modexpMemoryHolder2.build()); + codeHolder1.build(), + codeHolder2.build()); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java index 8921a5c5ab..83b159905d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -17,10 +17,9 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.CallDataParameter; import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -30,13 +29,11 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.modexpMemoryHolderAddress2; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.MAX; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.MODERATE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolderAddress2; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; - +@Tag("weekly") public class HappyPathTests { /** @@ -45,10 +42,66 @@ public class HappyPathTests { @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void messageCallTransactionTest(CallParameters params) { + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 0, 5 * WORD_SIZE); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } + /** + * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void deploymentTransactionTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 5 * WORD_SIZE); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallFromRootTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 0); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathDuringCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + } + + /** + * AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathAfterCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); + } + /** Non-parametric test to make sure things are working as expected. */ @Test public void singleMessageCallTransactionTest() { @@ -91,7 +144,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters BytecodeCompiler program = BytecodeCompiler.newProgram(); // populate memory with the data for first MODEXP call - copyForeignCodeToRam(program, modexpMemoryHolderAddress1); + copyForeignCodeToRam(program, codeHolderAddress1); // happy path: first MODEXP call appendHappyPathPrecompileCall(program, params); @@ -105,7 +158,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters loadFirstReturnDataWordOntoStack(program, 48); // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, modexpMemoryHolderAddress2); + copyForeignCodeToRam(program, codeHolderAddress2); // happy path: second MODEXP call appendHappyPathPrecompileCall(program, params); @@ -122,8 +175,8 @@ private void setCodeOfHolderAccounts(CallParameters params) { BytecodeCompiler code2 = params.memoryContent.memoryContents(); - modexpMemoryHolder1.code(code1.compile()); - modexpMemoryHolder2.code(code1.compile()); + codeHolder1.code(code1.compile()); + codeHolder2.code(code2.compile()); } public static Stream happyPathParameterGeneration() { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java index 507bf75eb7..83e26dcdbd 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java @@ -19,6 +19,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE_MO; import net.consensys.linea.testing.BytecodeCompiler; +import org.apache.tuweni.bytes.Bytes; public enum MemoryContentParameter { ZEROS, @@ -58,16 +59,21 @@ public void switchVariants() { "e2db57e640f49001c04ca5cb36e72f97af535c4d7620a48b96f8d0475afcaee569dcf211255b9ce6c05178cdf45152650496523591db85dadc328f6cb57e94ad83a66cca880b9fc02154c6941457158585230a843f38778f1d4cd6cbb42c778bcc5f05ab1c8306b59db726b705e3f782017a4dcaa04694b5c62e645445ede56b"; /** - * Constructs "byte code" of the following form + * Constructs a slice of bytes of the following form * *

[ W_1 | W_2 | W_3 | W_4 | ff .. ff ] * - *

for various EVM words W_k. These may or may not contain x/y coordinates of curve points. - * The final 32 bytes are all set to ff and may get overwritten with return - * data after the precompile call. + *

for various EVM words W_k. These may or may not contain x/y coordinates of curve + * points. The final 32 bytes are all set to ff and may get overwritten with + * return data after the precompile call. * - *

Note. The purpose of the resulting 'byte code' is to be EXTCODECOPY'ed to - * memory and used as input to a call to ECADD. + *

Wrt the EVM words W_k, there are several cases: coordinates of actual curve points, + * coordinates of the form 00 .. 00 ff that don't match the other coordinate, 00 .. 00 + * 00, just random bytes ... + * + *

Note. The purpose of the resulting slice of bytes is to become the 'byte code' of + * some account whose 'byte code' is to be EXTCODECOPY'ed to memory and used as input to a + * call to ECADD. */ public BytecodeCompiler memoryContents() { @@ -97,7 +103,7 @@ public BytecodeCompiler memoryContents() { String memoryContentsString = pointData + MAX_WORD; BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); - memoryContents.immediate(memoryContentsString.getBytes()); + memoryContents.immediate(Bytes.fromHexString(memoryContentsString)); return memoryContents; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index 5dcf4ce51e..145a3f059f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -28,6 +28,9 @@ public class ParameterGeneration { + /** + * Parameter generation for ECADD testing. + */ public static Stream happyPathParameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 8a2aadfaba..c0c1096e31 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -17,6 +17,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; import java.util.stream.Stream; @@ -44,16 +45,15 @@ public class HappyPathTests { @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void messageCallTransactionTest(CallParameters params) { + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 0, 0); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } /** - * CONTRACT_DEPLOYMENT_TRANSACTION case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - * @param params + * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -66,11 +66,7 @@ public void deploymentTransactionTest(CallParameters params) { } /** - * MESSAGE_CALL_FROM_ROOT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - * @param params + * MESSAGE_CALL_FROM_ROOT case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -80,9 +76,7 @@ public void messageCallFromRootTest(CallParameters params) { } /** - * DURING_DEPLOYMENT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. + * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. * *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the @@ -99,9 +93,7 @@ public void happyPathDuringCreate(CallParameters params) { } /** - * AFTER_DEPLOYMENT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. + * AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") @@ -180,7 +172,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters BytecodeCompiler program = BytecodeCompiler.newProgram(); // populate memory with the data for first MODEXP call - copyForeignCodeToRam(program, modexpMemoryHolderAddress1); + copyForeignCodeToRam(program, codeHolderAddress1); // happy path: first MODEXP call appendHappyPathPrecompileCall(program, params, variant1); @@ -194,7 +186,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters loadFirstReturnDataWordOntoStack(program, 48); // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, modexpMemoryHolderAddress2); + copyForeignCodeToRam(program, codeHolderAddress2); // happy path: second MODEXP call appendHappyPathPrecompileCall(program, params, variant2); @@ -205,8 +197,8 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters } /** - * Populate the byte code of {@link CodeExecutionMethods#modexpMemoryHolder1} and {@link - * CodeExecutionMethods#modexpMemoryHolder2} with "byte code" that is well-formed data for a + * Populate the byte code of {@link CodeExecutionMethods#codeHolder1} and {@link + * CodeExecutionMethods#codeHolder2} with "byte code" that is well-formed data for a * MODEXP call. * * @param params @@ -216,8 +208,8 @@ private void setCodeOfHolderAccounts(CallParameters params) { String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); - modexpMemoryHolder1.code(Bytes.fromHexString(code1)); - modexpMemoryHolder2.code(Bytes.fromHexString(code2)); + codeHolder1.code(Bytes.fromHexString(code1)); + codeHolder2.code(Bytes.fromHexString(code2)); } public static Stream happyPathParameterGeneration() { From b3a72be392955e2cf9d556484eee9de4189135bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 14 Feb 2025 01:45:16 +0100 Subject: [PATCH 37/57] spotless --- .../callTests/prc/CodeExecutionMethods.java | 10 +- .../prc/ecadd/CallDataSizeParameter.java | 22 +- .../callTests/prc/ecadd/CallParameters.java | 46 +-- .../callTests/prc/ecadd/HappyPathTests.java | 330 +++++++++--------- .../prc/ecadd/ParameterGeneration.java | 4 +- .../prc/modexp/CallDataParameter.java | 13 +- .../callTests/prc/modexp/HappyPathTests.java | 28 +- .../prc/modexp/ParameterGeneration.java | 6 +- 8 files changed, 214 insertions(+), 245 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index f21cd22364..733dbab7de 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -63,17 +63,11 @@ public class CodeExecutionMethods { public static final Address codeHolderAddress1 = Address.fromHexString("d00d"); public static final ToyAccount.ToyAccountBuilder codeHolder1 = - ToyAccount.builder() - .address(codeHolderAddress1) - .balance(Wei.of(0x2025)) - .nonce(0x11aaff); + ToyAccount.builder().address(codeHolderAddress1).balance(Wei.of(0x2025)).nonce(0x11aaff); public static final Address codeHolderAddress2 = Address.fromHexString("dada"); public static final ToyAccount.ToyAccountBuilder codeHolder2 = - ToyAccount.builder() - .address(codeHolderAddress2) - .balance(Wei.of(0x2025)) - .nonce(0x11aaff); + ToyAccount.builder().address(codeHolderAddress2).balance(Wei.of(0x2025)).nonce(0x11aaff); public static final ToyTransaction.ToyTransactionBuilder transaction = ToyTransaction.builder() diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java index b67ffa8508..28d7190fea 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java @@ -15,15 +15,15 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; public enum CallDataSizeParameter { - ZERO, - NONEMPTY_1f, - NONEMPTY_20, - NONEMPTY_3f, - NONEMPTY_40, - NONEMPTY_5f, - NONEMPTY_60, - NONEMPTY_7f, - NONEMPTY_80, - FULL, - LARGE + ZERO, + NONEMPTY_1f, + NONEMPTY_20, + NONEMPTY_3f, + NONEMPTY_40, + NONEMPTY_5f, + NONEMPTY_60, + NONEMPTY_7f, + NONEMPTY_80, + FULL, + LARGE } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java index 63dfbee0c8..7ba224b9ba 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java @@ -20,29 +20,29 @@ public class CallParameters { - public final OpCode call; - public final GasParameter gas; - public final MemoryContentParameter memoryContent; - public final CallDataSizeParameter cds; - public final ReturnAtParameter returnAt; - public final boolean willRevert; + public final OpCode call; + public final GasParameter gas; + public final MemoryContentParameter memoryContent; + public final CallDataSizeParameter cds; + public final ReturnAtParameter returnAt; + public final boolean willRevert; - public CallParameters( - OpCode call, - GasParameter gas, - MemoryContentParameter memoryContent, - CallDataSizeParameter cds, - ReturnAtParameter returnAt, - boolean willRevert) { - this.call = call; - this.gas = gas; - this.memoryContent = memoryContent; - this.cds = cds; - this.returnAt = returnAt; - this.willRevert = willRevert; - } + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContentParameter memoryContent, + CallDataSizeParameter cds, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContent = memoryContent; + this.cds = cds; + this.returnAt = returnAt; + this.willRevert = willRevert; + } - public void switchVariants() { - memoryContent.switchVariants(); - } + public void switchVariants() { + memoryContent.switchVariants(); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java index 83b159905d..0833a0db68 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -14,6 +14,14 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolderAddress2; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.stream.Stream; + import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; @@ -25,119 +33,102 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import java.util.stream.Stream; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolderAddress2; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - @Tag("weekly") public class HappyPathTests { - /** - * MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParameters params) { - - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 0, 5 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** - * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParameters params) { + /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallTransactionTest(CallParameters params) { + + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 0, 5 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void deploymentTransactionTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 5 * WORD_SIZE); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallFromRootTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 0); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathDuringCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + } + + /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathAfterCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); + } + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + GasParameter.COST_MO, + MemoryContentParameter.WELLFORMED_POINTS, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 5 * WORD_SIZE); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** - * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 0); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** - * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. - * - *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose - * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the - * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code - * of a CREATE. The whole operation optionally REVERT's. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); - } - - /** - * AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); - } - - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest() { - CallParameters params = - new CallParameters( - CALL, - GasParameter.COST_MO, - MemoryContentParameter.WELLFORMED_POINTS, - CallDataSizeParameter.FULL, - ReturnAtParameter.FULL, - true); - - setCodeOfHolderAccounts(params); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - - /** - * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy - * path testing of MODEXP. This code does the following: - * - *

- populate memory with the data for first MODEXP call - * - *

- perform first MODEXP call and play around with its return data - * - *

- wipe return data - * - *

- populate memory with the data for second MODEXP call - * - *

- perform second MODEXP call and play around with its return data - * - * @param params - * @return - */ -private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { + setCodeOfHolderAccounts(params); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** + * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy + * path testing of MODEXP. This code does the following: + * + *

- populate memory with the data for first MODEXP call + * + *

- perform first MODEXP call and play around with its return data + * + *

- wipe return data + * + *

- populate memory with the data for second MODEXP call + * + *

- perform second MODEXP call and play around with its return data + * + * @param params + * @return + */ + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { setCodeOfHolderAccounts(params); @@ -153,7 +144,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters // return data wiping appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("c0ffeebabe"), 13, 15, 17, 19); + program, CALL, 34_000, Address.fromHexString("c0ffeebabe"), 13, 15, 17, 19); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); loadFirstReturnDataWordOntoStack(program, 48); @@ -166,74 +157,71 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters loadFirstReturnDataWordOntoStack(program, 0x02ff); return program; -} + } + + private void setCodeOfHolderAccounts(CallParameters params) { + + BytecodeCompiler code1 = params.memoryContent.memoryContents(); + params.switchVariants(); - private void setCodeOfHolderAccounts(CallParameters params) { + BytecodeCompiler code2 = params.memoryContent.memoryContents(); - BytecodeCompiler code1 = params.memoryContent.memoryContents(); - params.switchVariants(); + codeHolder1.code(code1.compile()); + codeHolder2.code(code2.compile()); + } - BytecodeCompiler code2 = params.memoryContent.memoryContents(); + public static Stream happyPathParameterGeneration() { + return ParameterGeneration.happyPathParameterGeneration(); + } - codeHolder1.code(code1.compile()); - codeHolder2.code(code2.compile()); + /** Constructs a call to the ECADD precompile in terms of {@link CallParameters}. */ + public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case ZERO -> program.push(0); + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_3f -> program.push(0x3f); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_5f -> program.push(0x5f); + case NONEMPTY_60 -> program.push(0x60); + case NONEMPTY_7f -> program.push(0x7f); + case NONEMPTY_80 -> program.push(0x80); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); } - public static Stream happyPathParameterGeneration() { - return ParameterGeneration.happyPathParameterGeneration(); + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(params.willRevert ? 0x0200 : 0); } - /** - * Constructs a call to the ECADD precompile in terms of {@link CallParameters}. - */ - public void appendHappyPathPrecompileCall( - BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push(23); - case FULL -> program.push(2 * WORD_SIZE); - default -> throw new RuntimeException("Unsupported returnAt parameter"); - } - - // push the r@o onto the stack - program.push(4 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case ZERO -> program.push(0); - case NONEMPTY_1f -> program.push(0x1f); - case NONEMPTY_20 -> program.push(0x20); - case NONEMPTY_3f -> program.push(0x3f); - case NONEMPTY_40 -> program.push(0x40); - case NONEMPTY_5f -> program.push(0x5f); - case NONEMPTY_60 -> program.push(0x60); - case NONEMPTY_7f -> program.push(0x7f); - case NONEMPTY_80 -> program.push(0x80); - case FULL -> program.op(MSIZE); - case LARGE -> program.push("ff".repeat(WORD_SIZE)); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(params.willRevert ? 0x0200 : 0); - } - - program.push(Address.ALTBN128_ADD); - - // push gas onto the stack - switch (params.gas) { - case ZERO -> program.push(0); // remains interesting in the nonzero value case - case COST_MO -> program.push(149); - case COST -> program.push(150); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - - program.op(params.call); + program.push(Address.ALTBN128_ADD); + + // push gas onto the stack + switch (params.gas) { + case ZERO -> program.push(0); // remains interesting in the nonzero value case + case COST_MO -> program.push(149); + case COST -> program.push(150); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); } + + program.op(params.call); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index 145a3f059f..427256250d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -28,9 +28,7 @@ public class ParameterGeneration { - /** - * Parameter generation for ECADD testing. - */ + /** Parameter generation for ECADD testing. */ public static Stream happyPathParameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java index 0e5e418a3c..2692458b6c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java @@ -25,18 +25,18 @@ public class CallDataParameter { private static final String BASE_512_a = - "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; + "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; private static final String EXPN_512_a = - "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; + "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; private static final String MDLS_512_a = - "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; + "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; private static final String BASE_512_b = - "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; + "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; private static final String EXPN_512_b = - "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; private static final String MDLS_512_b = - "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; + "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; /** base byte size. */ public final ByteSizeParameter bbs; @@ -177,5 +177,4 @@ private String ebs(boolean variant) { private String mbs(boolean variant) { return Bytes32.leftPad(Bytes.ofUnsignedShort(mbsShort(variant))).toString(); } - } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index c0c1096e31..37c9c4f4f9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -15,9 +15,8 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; import static net.consensys.linea.zktracer.opcode.OpCode.*; import java.util.stream.Stream; @@ -39,9 +38,7 @@ public class HappyPathTests { private final boolean variant1 = true; private final boolean variant2 = false; - /** - * MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. - */ + /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void messageCallTransactionTest(CallParameters params) { @@ -52,9 +49,7 @@ public void messageCallTransactionTest(CallParameters params) { runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); } - /** - * CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. - */ + /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void deploymentTransactionTest(CallParameters params) { @@ -65,9 +60,7 @@ public void deploymentTransactionTest(CallParameters params) { runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); } - /** - * MESSAGE_CALL_FROM_ROOT case, see {@link CodeExecutionMethods}. - */ + /** MESSAGE_CALL_FROM_ROOT case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void messageCallFromRootTest(CallParameters params) { @@ -92,9 +85,7 @@ public void happyPathDuringCreate(CallParameters params) { runForeignByteCodeAsInitCode(foreignCode, params.willRevert); } - /** - * AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. - */ + /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ @ParameterizedTest @MethodSource("happyPathParameterGeneration") public void happyPathAfterCreate(CallParameters params) { @@ -116,7 +107,7 @@ public void singleMessageCallTransactionTest() { new CallParameters( CALL, GasParameter.COST_MO, - callDataParameter, + callDataParameter, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, true); @@ -139,7 +130,7 @@ public void singleMessageCallTransactionTest2() { new CallParameters( STATICCALL, GasParameter.COST, - callDataParameter, + callDataParameter, ReturnAtParameter.FULL, RelativeRangePosition.OVERLAP, true); @@ -198,8 +189,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters /** * Populate the byte code of {@link CodeExecutionMethods#codeHolder1} and {@link - * CodeExecutionMethods#codeHolder2} with "byte code" that is well-formed data for a - * MODEXP call. + * CodeExecutionMethods#codeHolder2} with "byte code" that is well-formed data for a MODEXP call. * * @param params */ @@ -224,7 +214,7 @@ public static Stream happyPathParameterGeneration() { * @param variant */ public void appendHappyPathPrecompileCall( - BytecodeCompiler program, CallParameters params, boolean variant) { + BytecodeCompiler program, CallParameters params, boolean variant) { int cds = params.callData.memorySize(variant); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index d17141af78..25eed4d314 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -38,9 +38,9 @@ public class ParameterGeneration { *

- {@code bbs}, {@code ebs}, {@code mbs} are {@link ByteSizeParameter} values for * MODEXP, either 0, 1, something small, or the maximum (512) * - *

- {@code cds} is one of the {@link CallDataSizeParameter} values, which dictates how - * much of the parameters in RAM (bbs, ebs, mbs, BASE, EXPONENT - * and MODULUS) actually get passed down to MODEXP + *

- {@code cds} is one of the {@link CallDataSizeParameter} values, which dictates how much of + * the parameters in RAM (bbs, ebs, mbs, BASE, EXPONENT and + * MODULUS) actually get passed down to MODEXP * *

- {@code returnAt} is one of the {@link ReturnAtParameter} values, which dictates how much * of the return data will be written to RAM, it can be EMPTY, PARTIAL or From 291dcd3e3c429dd432718bd54e4b2320dc5df6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Fri, 14 Feb 2025 20:26:15 +0100 Subject: [PATCH 38/57] wip: ECMUL tests --- .../prc/ecadd/CallDataSizeParameter.java | 10 +- .../callTests/prc/ecadd/HappyPathTests.java | 20 +-- .../prc/ecadd/MemoryContentParameter.java | 45 +++--- .../prc/ecadd/ParameterGeneration.java | 25 +++- .../prc/ecmul/CallDataSizeParameter.java | 34 +++++ .../callTests/prc/ecmul/CallParameters.java | 62 ++++++++ .../callTests/prc/ecmul/HappyPathTests.java | 133 ++++++++++++++++++ .../prc/ecmul/MemoryContentsParameter.java | 92 ++++++++++++ .../prc/ecmul/ParameterGeneration.java | 60 ++++++++ 9 files changed, 445 insertions(+), 36 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java index 28d7190fea..85166fcfa5 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallDataSizeParameter.java @@ -15,14 +15,16 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; public enum CallDataSizeParameter { - ZERO, + EMPTY, + // partial words NONEMPTY_1f, - NONEMPTY_20, NONEMPTY_3f, - NONEMPTY_40, NONEMPTY_5f, - NONEMPTY_60, NONEMPTY_7f, + // full words + NONEMPTY_20, + NONEMPTY_40, + NONEMPTY_60, NONEMPTY_80, FULL, LARGE diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java index 0833a0db68..647a2ea99c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -101,7 +101,7 @@ public void singleMessageCallTransactionTest() { new CallParameters( CALL, GasParameter.COST_MO, - MemoryContentParameter.WELLFORMED_POINTS, + MemoryContentParameter.WELL_FORMED_POINTS, CallDataSizeParameter.FULL, ReturnAtParameter.FULL, true); @@ -134,10 +134,10 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters BytecodeCompiler program = BytecodeCompiler.newProgram(); - // populate memory with the data for first MODEXP call + // populate memory with the data for first ECADD call copyForeignCodeToRam(program, codeHolderAddress1); - // happy path: first MODEXP call + // happy path: first ECADD call appendHappyPathPrecompileCall(program, params); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); loadFirstReturnDataWordOntoStack(program, 0x02ff); @@ -151,7 +151,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters // populate memory with the data for second MODEXP call copyForeignCodeToRam(program, codeHolderAddress2); - // happy path: second MODEXP call + // happy path: second ECADD call appendHappyPathPrecompileCall(program, params); copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); loadFirstReturnDataWordOntoStack(program, 0x02ff); @@ -190,14 +190,16 @@ public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParamete // push the cds onto the stack switch (params.cds) { - case ZERO -> program.push(0); + case EMPTY -> program.push(0); + // partial words case NONEMPTY_1f -> program.push(0x1f); - case NONEMPTY_20 -> program.push(0x20); case NONEMPTY_3f -> program.push(0x3f); - case NONEMPTY_40 -> program.push(0x40); case NONEMPTY_5f -> program.push(0x5f); - case NONEMPTY_60 -> program.push(0x60); case NONEMPTY_7f -> program.push(0x7f); + // full words + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_60 -> program.push(0x60); case NONEMPTY_80 -> program.push(0x80); case FULL -> program.op(MSIZE); case LARGE -> program.push("ff".repeat(WORD_SIZE)); @@ -215,7 +217,7 @@ public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParamete // push gas onto the stack switch (params.gas) { - case ZERO -> program.push(0); // remains interesting in the nonzero value case + case ZERO -> program.push(0); // interesting in the nonzero value case case COST_MO -> program.push(149); case COST -> program.push(150); case FULL -> program.op(GAS); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java index 83e26dcdbd..cc96b1a8c6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java @@ -23,7 +23,7 @@ public enum MemoryContentParameter { ZEROS, - WELLFORMED_POINTS, + WELL_FORMED_POINTS, MIXED, MALFORMED_AT_1f, MALFORMED_AT_3f, @@ -39,25 +39,30 @@ public void switchVariants() { } // coordinates for 5 curve points - private static final String A_X = + public static final String A_X = "08d555288636cfb5abeac1d38a828fc4d975fb8def9f63a34f8c91701b5478d1"; - private static final String A_Y = + public static final String A_Y = "2fe58eb05ff7bed143c398b0b62e18e8b0327a3be8250b2923ea29e6773a65f5"; - private static final String B_X = + public static final String B_X = "0d89e2e42be7fbda9358a2689c73af3ecd519728359f175ee7919d31c8f61d5d"; - private static final String B_Y = + public static final String B_Y = "0eb7c8cfbbe0a89bf12697e97b482c3a91ff985ba456f1684a0b68efa2933019"; - private static final String C_X = + public static final String C_X = "070375d4eec4f22aa3ad39cb40ccd73d2dbab6de316e75f81dc2948a996795d5"; - private static final String C_Y = + public static final String C_Y = "041b98f07f44aa55ce8bd97e32cacf55f1e42229d540d5e7a767d1138a5da656"; - private static final String D_X = + public static final String D_X = "185f6f5cf93c8afa0461a948c2da7c403b6f8477c488155dfa8d2da1c62517b8"; - private static final String D_Y = + public static final String D_Y = "13d83d7a51eb18fdb51225873c87d44f883e770ce2ca56c305d02d6cb99ca5b8"; - private static final String RND = + public static final String RND = "e2db57e640f49001c04ca5cb36e72f97af535c4d7620a48b96f8d0475afcaee569dcf211255b9ce6c05178cdf45152650496523591db85dadc328f6cb57e94ad83a66cca880b9fc02154c6941457158585230a843f38778f1d4cd6cbb42c778bcc5f05ab1c8306b59db726b705e3f782017a4dcaa04694b5c62e645445ede56b"; + public static final String ZERO_WORD = "00".repeat(WORD_SIZE); + public static final String MAX_BYTE = "00".repeat(WORD_SIZE_MO) + "ff"; + public static final String MAX_WORD = "ff".repeat(WORD_SIZE); + public static final int WORD_HEX_SIZE = 2 * WORD_SIZE; + /** * Constructs a slice of bytes of the following form * @@ -77,27 +82,23 @@ public void switchVariants() { */ public BytecodeCompiler memoryContents() { - final String ZERO = "00".repeat(WORD_SIZE); - final String MAX_BYTE = "00".repeat(WORD_SIZE_MO) + "ff"; - final String MAX_WORD = "ff".repeat(WORD_SIZE); - // Note that 4 = 2 * 2. We need 4 * 32 hex characters for the data representing a point. String pointData = switch (this) { - case ZEROS -> "00".repeat(4 * WORD_SIZE); - case WELLFORMED_POINTS -> variant ? A_X + A_Y + B_X + B_Y : C_X + C_Y + D_X + D_Y; + case ZEROS -> ZERO_WORD.repeat(4); + case WELL_FORMED_POINTS -> variant ? A_X + A_Y + B_X + B_Y : C_X + C_Y + D_X + D_Y; case MIXED -> variant - ? A_X + A_Y + RND.substring(13, 13 + 4 * WORD_SIZE) - : C_X + C_Y + RND.substring(99, 99 + 4 * WORD_SIZE); + ? A_X + A_Y + RND.substring(13, 13 + 2 * WORD_HEX_SIZE) + : C_X + C_Y + RND.substring(99, 99 + 2 * WORD_HEX_SIZE); case MALFORMED_AT_1f -> MAX_BYTE + (variant ? A_Y + B_X + B_Y : C_Y + D_X + D_Y); - case MALFORMED_AT_3f -> ZERO + MAX_BYTE + (variant ? B_X + B_Y : D_X + D_Y); - case MALFORMED_AT_5f -> ZERO.repeat(2) + MAX_BYTE + (variant ? B_Y : D_Y); - case MALFORMED_AT_7f -> ZERO.repeat(3) + MAX_BYTE; + case MALFORMED_AT_3f -> ZERO_WORD + MAX_BYTE + (variant ? B_X + B_Y : D_X + D_Y); + case MALFORMED_AT_5f -> ZERO_WORD.repeat(2) + MAX_BYTE + (variant ? B_Y : D_Y); + case MALFORMED_AT_7f -> ZERO_WORD.repeat(3) + MAX_BYTE; case RANDOM -> RND; case MAX -> MAX_WORD.repeat(4); }; - final boolean correctLength = pointData.length() == 2 * 4 * WORD_SIZE; + final boolean correctLength = pointData.length() == 4 * WORD_HEX_SIZE; checkState(correctLength); String memoryContentsString = pointData + MAX_WORD; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index 427256250d..dfb5920b25 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -28,7 +28,30 @@ public class ParameterGeneration { - /** Parameter generation for ECADD testing. */ + /** + * Parameter generation for ECADD testing. The paramters encompass the following: + * + *

- OpCode the call opcode to be tested; the only distinction we draw here is between + * value-bearing CALL-type opcodes and non-value-bearing ones; the value bearing ones are + * interesting in conjunction with ZERO_WORD gas calls to ECADD; + * + *

- GasParameter the gas parameter to be tested: the relevant options are + * ZERO_WORD, COST_MO, COST, and FULL; recall that the gas cost of + * ECADD is constant equal to 150; testing with ZERO_WORD gas makes sense for value + * bearing CALL-type opcodes given the call stipend of 2_300; + * + *

- MemoryContentParameter the memory content parameter to be tested; the way we + * produce this memory content is by providing 5 EVM words, the last one of which is blackened out + * (i.e. set to 0x ff .. ff ff), the others being either coordinates of curve points, + * invalid coordinates of the form 0x 00 .. 00 ff, random junk; + * + *

- CallDataSizeParameter the call data size parameter to be tested; options are + * EMPTY, some number of full EVM words with the final one either full (e.g. + * NONEMPTY_20) or missing the final byte (e.g. NONEMPTY_5f), and FULL; + * + *

- ReturnAtParameter the return at parameter to be tested; return data will be written + * on the aforementioned blackened word in RAM; + */ public static Stream happyPathParameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java new file mode 100644 index 0000000000..467c835499 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java @@ -0,0 +1,34 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +/** + * Call data size parameters for the ECMUL precompile. We provision for either a collection of + * complete EVM words or a collection of EVM words with the final one either missing one byte or + * being just 11 bytes. + */ +public enum CallDataSizeParameter { + EMPTY, + // partial words + NONEMPTY_1f, // 32 - 1 bytes + NONEMPTY_3f, // 64 - 1 bytes + NONEMPTY_4d, // 64 + 11 bytes + // full words + NONEMPTY_20, + NONEMPTY_40, + NONEMPTY_60, + FULL, + LARGE +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java new file mode 100644 index 0000000000..7d88491d33 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java @@ -0,0 +1,62 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolder1; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolder2; + +public class CallParameters { + public final OpCode call; + public final GasParameter gas; + public final MemoryContentsParameter memoryContent; + public final CallDataSizeParameter cds; + public final ReturnAtParameter returnAt; + public final boolean willRevert; + + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContentsParameter memoryContent, + CallDataSizeParameter cds, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContent = memoryContent; + this.cds = cds; + this.returnAt = returnAt; + this.willRevert = willRevert; + } + + public void switchVariants() { + memoryContent.switchVariants(); + } + + public void setCodeOfHolderAccounts() { + + BytecodeCompiler code1 = this.memoryContent.memoryContents(); + this.switchVariants(); + + BytecodeCompiler code2 = this.memoryContent.memoryContents(); + + codeHolder1.code(code1.compile()); + codeHolder2.code(code2.compile()); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java new file mode 100644 index 0000000000..b7bfa8520a --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java @@ -0,0 +1,133 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul.CallDataSizeParameter; +import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +@Tag("weekly") +public class HappyPathTests { + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + GasParameter.COST, + MemoryContentsParameter.WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); + + params.setCodeOfHolderAccounts(); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { + + params.setCodeOfHolderAccounts(); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first ECMUL call + copyForeignCodeToRam(program, codeHolderAddress1); + + // happy path: first ECMUL call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("deadc0ffee"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second MODEXP call + copyForeignCodeToRam(program, codeHolderAddress2); + + // happy path: second ECMUL call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x11); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + return program; + } + + /** Constructs a call to the ECADD precompile in terms of {@link net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.CallParameters}. */ + public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(3 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case EMPTY -> program.push(0); + // partial words + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_3f -> program.push(0x3f); + // full words + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_60 -> program.push(0x60); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(0x0400); + } + + program.push(Address.ALTBN128_MUL); + + // push gas onto the stack + int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; + switch (params.gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(5_999 - callStipend); + case COST -> program.push(6_000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(params.call); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java new file mode 100644 index 0000000000..564ec479c8 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java @@ -0,0 +1,92 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentParameter.*; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.apache.tuweni.bytes.Bytes; + +/** + * Enumerates the different memory contents parameters for a precompile call. Similarly to {@link + * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentParameter}, + * memory content comprises a certain number of data words and one final EVM word where the + * CALL instruction will be required to write its return data: + * + *

[ COORD_X | COORD_Y || MULITIPLIER || ff .. ff ] + */ +public enum MemoryContentsParameter { + /** [ ZEROS | ZEROS || ZEROS || ff .. ff ] */ + ZEROS, + + /** [ ZEROS | ZEROS || RAND || ff .. ff ] */ + POINT_AT_INFINITY_RANDOM_MULTIPLIER, + + /** [ A_x | A_y || ZEROS || ff .. ff ] */ + CURVE_POINT_ZERO_MULTIPLIER, + + /** [ 00 .. 00 ff | RAND || RAND || ff .. ff ] */ + MALFORMED_AT_1f, + + /** [ ZEROS | 00 .. 00 ff || RAND || ff .. ff ] */ + MALFORMED_AT_3f, + + /** [ B_x | B_y || 00 .. 00 xx .. xx || ff .. ff ] with {@code nByte} many xx's */ + FIRST_FEW_BYTES_OF_MULTIPLIER_ARE_ZERO, + + /** [ C_x | C_y || RAND || ff .. ff ] */ + WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, + + /** [ RAND | RAND || RAND || ff .. ff ] */ + RANDOM; + + public boolean variant = false; + + public void switchVariants() { + variant = !variant; + } + + public BytecodeCompiler memoryContents() { + + int nBytes = 11; + + String pointData = + switch (this) { + case ZEROS -> ZERO_WORD.repeat(3); + case POINT_AT_INFINITY_RANDOM_MULTIPLIER -> ZERO_WORD.repeat(2) + + RND.substring(17, 17 + WORD_HEX_SIZE); + case CURVE_POINT_ZERO_MULTIPLIER -> (variant ? A_X + A_Y : B_X + B_Y) + ZERO_WORD; + case MALFORMED_AT_1f -> MAX_BYTE + RND.substring(61, 61 + 2 * WORD_HEX_SIZE); + case MALFORMED_AT_3f -> ZERO_WORD + MAX_BYTE + RND.substring(129, 129 + WORD_HEX_SIZE); + case FIRST_FEW_BYTES_OF_MULTIPLIER_ARE_ZERO -> (variant ? B_X + B_Y : C_X + C_Y) + + "00".repeat(nBytes) + + RND.substring(99, 99 + 2 * (WORD_SIZE - nBytes)); + case WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER -> (variant ? C_X + C_Y : D_X + D_Y) + + RND.substring(71, 71 + WORD_HEX_SIZE); + case RANDOM -> RND.substring(36, 36 + 3 * WORD_HEX_SIZE); + }; + + checkState(pointData.length() == 3 * WORD_HEX_SIZE); + + String memoryContentsString = pointData + MAX_WORD; + + BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); + memoryContents.immediate(Bytes.fromHexString(memoryContentsString)); + + return memoryContents; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java new file mode 100644 index 0000000000..5f6b3529a4 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java @@ -0,0 +1,60 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; + +public class ParameterGeneration { + + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + List GasParameters = + List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); + List ReturnAtParameters = + List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { // 4 + for (GasParameter gas : GasParameters) { // 4 + for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, true))); + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, false))); + } + } + } + } + } + return argumentsList.stream(); + } +} From 7c877ad8645a394bb994000eab3bdd9bb3818956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Mon, 17 Feb 2025 19:31:10 +0100 Subject: [PATCH 39/57] wip: ECRECOVER --- .../callTests/prc/ecadd/CallParameters.java | 4 +- .../callTests/prc/ecadd/HappyPathTests.java | 2 +- ...eter.java => MemoryContentsParameter.java} | 2 +- .../prc/ecadd/ParameterGeneration.java | 2 +- .../prc/ecmul/MemoryContentsParameter.java | 4 +- .../ecrecover/MemoryContentsParameter.java | 40 +++++++++++++++++++ 6 files changed, 47 insertions(+), 7 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/{MemoryContentParameter.java => MemoryContentsParameter.java} (99%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java index 7ba224b9ba..afaf79a438 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java @@ -22,7 +22,7 @@ public class CallParameters { public final OpCode call; public final GasParameter gas; - public final MemoryContentParameter memoryContent; + public final MemoryContentsParameter memoryContent; public final CallDataSizeParameter cds; public final ReturnAtParameter returnAt; public final boolean willRevert; @@ -30,7 +30,7 @@ public class CallParameters { public CallParameters( OpCode call, GasParameter gas, - MemoryContentParameter memoryContent, + MemoryContentsParameter memoryContent, CallDataSizeParameter cds, ReturnAtParameter returnAt, boolean willRevert) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java index 647a2ea99c..b7e9c79ecb 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -101,7 +101,7 @@ public void singleMessageCallTransactionTest() { new CallParameters( CALL, GasParameter.COST_MO, - MemoryContentParameter.WELL_FORMED_POINTS, + MemoryContentsParameter.WELL_FORMED_POINTS, CallDataSizeParameter.FULL, ReturnAtParameter.FULL, true); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java index cc96b1a8c6..89b54842db 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java @@ -21,7 +21,7 @@ import net.consensys.linea.testing.BytecodeCompiler; import org.apache.tuweni.bytes.Bytes; -public enum MemoryContentParameter { +public enum MemoryContentsParameter { ZEROS, WELL_FORMED_POINTS, MIXED, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index dfb5920b25..0f1d27a625 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -63,7 +63,7 @@ public static Stream happyPathParameterGeneration() { for (OpCode opCode : CallOpCodes) { // 4 for (GasParameter gas : GasParameters) { // 4 - for (MemoryContentParameter memoryContent : MemoryContentParameter.values()) { // 9 + for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java index 564ec479c8..5299d92729 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java @@ -15,7 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.*; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; @@ -23,7 +23,7 @@ /** * Enumerates the different memory contents parameters for a precompile call. Similarly to {@link - * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentParameter}, + * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter}, * memory content comprises a certain number of data words and one final EVM word where the * CALL instruction will be required to write its return data: * diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java new file mode 100644 index 0000000000..2e108cae89 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java @@ -0,0 +1,40 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +/** + * Most values of {@link MemoryContentsParameter} values are self-explanatory. Memory will be + * made to contain inputs of the form + * + *

[ h | v | r | s ]

+ * + *

where h, v, r and s are 32-byte integers. With the enum + * we will test in particular: + * + *

- {@link #MALFORMED_AT_7f_BUT_RECOVERABLE} + *

- {@link #INVALID_V} + *

- {@link #BOUNDARY_R} and {@link #BOUNDARY_S}: cases where r or s are + * equal to 0 or the secp256k1n prime + */ +public enum MemoryContentsParameter { + ZEROS, + WELL_FORMED, + MALFORMED_AT_7f_BUT_RECOVERABLE, + INVALID_V, + BOUNDARY_R, + BOUNDARY_S, + RANDOM, + MAX; +} From 0fcc291e620ec44c36b9d4148bd07cf6ce3c8b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Tue, 18 Feb 2025 19:45:08 +0100 Subject: [PATCH 40/57] feat: progress on ECRECOVER --- .../prc/ecrecover/CallDataSizeParameter.java | 24 +++ .../prc/ecrecover/CallParameters.java | 44 +++++ .../prc/ecrecover/EcRecoverTuple.java | 94 ++++++++++ .../prc/ecrecover/HappyPathTests.java | 67 +++++++ .../ecrecover/MemoryContentsParameter.java | 163 ++++++++++++++++-- .../prc/ecrecover/ParameterGeneration.java | 59 +++++++ 6 files changed, 434 insertions(+), 17 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java new file mode 100644 index 0000000000..97e5f074f8 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java @@ -0,0 +1,24 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +public enum CallDataSizeParameter { + EMPTY, + // partial data + MISSING_FINAL_BYTE_OF_R, + MISSING_FINAL_BYTE_OF_S, + // full data + FULL; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java new file mode 100644 index 0000000000..dcec39a765 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java @@ -0,0 +1,44 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; + +public class CallParameters { + + public final OpCode call; + public final GasParameter gas; + public final MemoryContentsParameter memoryContent; + public final CallDataSizeParameter cds; + public final ReturnAtParameter returnAt; + public final boolean willRevert; + + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContentsParameter memoryContent, + CallDataSizeParameter cds, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContent = memoryContent; + this.cds = cds; + this.returnAt = returnAt; + this.willRevert = willRevert; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java new file mode 100644 index 0000000000..99307f4b8f --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java @@ -0,0 +1,94 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; + +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.MAX_WORD; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +public record EcRecoverTuple( + String h, + String v, + String r, + String s +) { + + public static String SECP_256_K1N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; + public static String ZERO = "00".repeat(WORD_SIZE); + + /** + * {@link #memoryContents} converts the {@link EcRecoverTuple} into the byte slice + * + *

[ h | v | r | s | ff .. ff ] + * + *

and optionally on {@code changeFinalByteOfS} modifies the final byte of s. + * As per usual, the purpose of the last EVM word is to be overwritten by return data. + * @param changeFinalByteOfS + * @return + */ + public BytecodeCompiler memoryContents(boolean changeFinalByteOfS) { + Bytes hBytes = Bytes32.leftPad(Bytes.fromHexString(h)); + Bytes vBytes = Bytes32.leftPad(Bytes.fromHexString(v)); + Bytes rBytes = Bytes32.leftPad(Bytes.fromHexString(r)); + Bytes sBytes = Bytes32.leftPad(Bytes.fromHexString(s)); + + if (changeFinalByteOfS) { + sBytes = sBytes.xor(Bytes32.leftPad(Bytes.ofUnsignedLong(0xff))); + } + + Bytes pointData = Bytes.concatenate(hBytes, vBytes, rBytes, sBytes, Bytes.fromHexString(MAX_WORD)); + + checkState(pointData.size() == 5 * WORD_SIZE); + + BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); + memoryContents.immediate(pointData); + + return memoryContents; + } + + /** + * {@link #replaceR} produces a copy of {@code this} with {@link #r} replaced by either + * + *

- {@link #ZERO} + *

- {@link #SECP_256_K1N} + * + * @param useZero + * @return + */ + public EcRecoverTuple replaceR(boolean useZero) { + return new EcRecoverTuple(h, v, zeroOrPrime(useZero), s); + } + + /** + * {@link #replaceS} produces a copy of {@code this} with {@link #s} replaced by either + * + *

- {@link #ZERO} + *

- {@link #SECP_256_K1N} + * + * @param useZero + * @return + */ + public EcRecoverTuple replaceS(boolean useZero) { + return new EcRecoverTuple(h, v, r, zeroOrPrime(useZero)); + } + + private String zeroOrPrime(boolean returnZero) { + return returnZero ? ZERO : SECP_256_K1N; + } +} \ No newline at end of file diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java new file mode 100644 index 0000000000..1972ce6f12 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java @@ -0,0 +1,67 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.hyperledger.besu.datatypes.Address; + +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +public class HappyPathTests { + + /** Constructs a call to the ECADD precompile in terms of {@link CallParameters}. */ + public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(12 + 6); // the first 12 bytes are zeros for successful ECRECOVER calls + case FULL -> program.push(WORD_SIZE); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case EMPTY -> program.push(0); + case MISSING_FINAL_BYTE_OF_R -> program.push(3 * WORD_SIZE - 1); + case MISSING_FINAL_BYTE_OF_S -> program.push(4 * WORD_SIZE - 1); + case FULL -> program.op(MSIZE); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(0x0600); + } + + program.push(Address.ECREC); + + // push gas onto the stack + int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; + switch (params.gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(3000 - callStipend - 1); + case COST -> program.push(3000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + program.op(params.call); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java index 2e108cae89..8de203321f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java @@ -14,27 +14,156 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.RND; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.WORD_HEX_SIZE; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +import net.consensys.linea.testing.BytecodeCompiler; + /** - * Most values of {@link MemoryContentsParameter} values are self-explanatory. Memory will be - * made to contain inputs of the form + * Memory for ECRECOVER testing will be made to contain inputs of the form + * + *

[ h | v | r | s ] + * + *

where h, v, r and s are 32-byte integers and with the + * precise contents being dictated by the enum. Most values of {@link MemoryContentsParameter} + * values are self-explanatory. We will test in particular: * - *

[ h | v | r | s ]

+ *

- {@link #MALFORMED_AT_7f_BUT_SALVAGEABLE} for cases where s is correct save for its final + * byte which would have to be 0x00 to be valid but instead is 0xff; the point + * being that if we provide a call data size of 127 then the signature becomes valid; * - *

where h, v, r and s are 32-byte integers. With the enum - * we will test in particular: + *

- {@link #INVALID_V} where v is neither 27 nor 28; * - *

- {@link #MALFORMED_AT_7f_BUT_RECOVERABLE} - *

- {@link #INVALID_V} - *

- {@link #BOUNDARY_R} and {@link #BOUNDARY_S}: cases where r or s are - * equal to 0 or the secp256k1n prime + *

- {@link #BOUNDARY_R} and {@link #BOUNDARY_S}: cases where r or s are equal to + * 0 or the secp256k1n prime */ public enum MemoryContentsParameter { - ZEROS, - WELL_FORMED, - MALFORMED_AT_7f_BUT_RECOVERABLE, - INVALID_V, - BOUNDARY_R, - BOUNDARY_S, - RANDOM, - MAX; + ZEROS, + WELL_FORMED, + MALFORMED_AT_7f_BUT_SALVAGEABLE, + INVALID_V, + BOUNDARY_R, + BOUNDARY_S, + RANDOM, + MALLEABLE; + + boolean variant = false; + + public void switchVariants() { + variant = !variant; + } + + public static final EcRecoverTuple VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_1 = + new EcRecoverTuple( + "74657374", + "27", + "29DFBC75A9092AC090852F1385EDF63FB0424F0E76FE6235AA92DDC6125931F5", + "37A787EEC7E3F12C0DF48461BEBDAD9880D6C4CF298F1D6F6CAC201F65C82B00"); + + public static final EcRecoverTuple VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_2 = + new EcRecoverTuple( + "74657374", + "28", + "242043660FDE1E9ED3B653C9DBD4EE7AD931FDCC2969DFC750F92A2E14FF5B4A", + "9E61F78441A49A3746E17E59FC626FC279FD1CCEA3448AAF984E7F4C9C873400"); + + public static final EcRecoverTuple INVALID_V_TUPLE_1 = + new EcRecoverTuple( + "74657374", + "29", + "CE146C6A682C1A7A5E1B56548D985764F8FD1547734B889AC7D9D0208CE375AA", + "E3A544E21BE92DD9A9AFE15015F2DF94E17E7090D7D164013E3806983A4D4E00"); + + public static final EcRecoverTuple INVALID_V_TUPLE_2 = + new EcRecoverTuple( + "74657374", + "30", + "C2728E508D0EC7F821E12D9401D2D0C66C5D2CAB2C17094D77462E1A72D7A9A4", + "CE521971A70CF4DEBD00DECDE04D523068142E73D52CA7E81BFEF76B0F79A100"); + + public static final EcRecoverTuple EVM_CODES_EXAMPLE = + new EcRecoverTuple( + "456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3", + "28", + "9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac8038825608", + "4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada"); + + /** + * {@link #EVM_CODES_EXAMPLE_MANIPULATED} is derived rom that of {@link #EVM_CODES_EXAMPLE} via + * + *

switch v to other value (27 ↔ 28) + * + *

{@link EcRecoverTuple#SECP_256_K1N} - s + */ + public static final EcRecoverTuple EVM_CODES_EXAMPLE_MANIPULATED = + new EcRecoverTuple( + "456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3", + "27", + "9242685bf161793cc25603c231bc2f568eb630ea16aa137d2664ac8038825608", + "b0751c428acadb72f42bb7d6733d1df79c5843b9a7d3c407b39bd3a37fb11667"); + + public static final EcRecoverTuple RANDOM_TUPLE = + new EcRecoverTuple( + RND.substring(0, WORD_HEX_SIZE), + RND.substring(64, 64 + WORD_HEX_SIZE), + RND.substring(128, 128 + WORD_HEX_SIZE), + RND.substring(192, 192 + WORD_HEX_SIZE)); + + /** + * {@link #memoryContents} converts the {@link MemoryContentsParameter} into a byte slice + * containing "interesting" memory contents for a ECRECOVER call. + * + *

Note. Calling this method twice in a row on the same {@link + * MemoryContentsParameter}'s generally results in two different outputs. Indeed, this method + * starts by switching the {@link #variant}. + * + * @return + */ + public BytecodeCompiler memoryContents() { + + // we switch with every call + switchVariants(); + + switch (this) { + case ZEROS -> { + final String ZERO_WORD = "00".repeat(WORD_SIZE); + return new EcRecoverTuple(ZERO_WORD, ZERO_WORD, ZERO_WORD, ZERO_WORD).memoryContents(false); + } + case WELL_FORMED -> { + return variant + ? VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_1.memoryContents(false) + : VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_2.memoryContents(false); + } + case MALFORMED_AT_7f_BUT_SALVAGEABLE -> { + return variant + ? VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_1.memoryContents(true) + : VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_2.memoryContents(true); + } + case INVALID_V -> { + return variant + ? INVALID_V_TUPLE_1.memoryContents(false) + : INVALID_V_TUPLE_2.memoryContents(false); + } + case BOUNDARY_R -> { + return variant + ? VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_1.replaceR(true).memoryContents(false) + : VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_2.replaceR(false).memoryContents(false); + } + case BOUNDARY_S -> { + return variant + ? VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_1.replaceS(true).memoryContents(false) + : VALID_TUPLE_WHERE_THE_FINAL_BYTE_OF_S_IS_ZERO_2.replaceS(false).memoryContents(false); + } + case RANDOM -> { + return RANDOM_TUPLE.memoryContents(false); + } + case MALLEABLE -> { + return variant + ? EVM_CODES_EXAMPLE.memoryContents(false) + : EVM_CODES_EXAMPLE_MANIPULATED.memoryContents(false); + } + default -> throw new RuntimeException("Unknown MemoryContentsParameter"); + } + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java new file mode 100644 index 0000000000..18f688395d --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java @@ -0,0 +1,59 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + +public class ParameterGeneration { + + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + List GasParameters = List.of(ZERO, COST_MO, COST, FULL); + List ReturnAtParameters = + List.of(ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { // 4 + for (GasParameter gas : GasParameters) { // 4 + for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, true))); + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, false))); + } + } + } + } + } + return argumentsList.stream(); + } +} From 8fc22c113a0eb3702db5bbff6dde699f73a7263e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Wed, 19 Feb 2025 16:23:15 +0100 Subject: [PATCH 41/57] feat: ECRECOVER tests --- .../callTests/Utilities.java | 12 +- .../callTests/prc/CodeExecutionMethods.java | 34 +-- .../callTests/prc/ecadd/HappyPathTests.java | 24 +- .../prc/ecadd/MemoryContentsParameter.java | 3 + .../callTests/prc/ecmul/CallParameters.java | 16 +- .../callTests/prc/ecmul/HappyPathTests.java | 198 +++++++++-------- .../prc/ecmul/MemoryContentsParameter.java | 9 + .../prc/ecmul/ParameterGeneration.java | 64 +++--- .../prc/ecrecover/CallDataSizeParameter.java | 12 +- .../prc/ecrecover/CallParameters.java | 40 ++-- .../prc/ecrecover/EcRecoverTuple.java | 128 +++++------ .../prc/ecrecover/HappyPathTests.java | 210 ++++++++++++++---- .../ecrecover/MemoryContentsParameter.java | 15 +- .../callTests/prc/modexp/HappyPathTests.java | 13 +- 14 files changed, 452 insertions(+), 326 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java index e19f42c29c..f749799906 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/Utilities.java @@ -169,16 +169,16 @@ public static void pushMinOfRdsAnd32OntoStack(BytecodeCompiler program) { program .push(WORD_SIZE) .op(RETURNDATASIZE) - .op(LT) // stack: [ c | ... [, where c ≡ [RDS < 32] + .op(LT) // stack: | ... | c ], where c ≡ [RDS < 32] .op(DUP1) .push(1) - .op(SUB) // stack: [ d | c | ... [, where d ≡ ¬c ≡ [RDS ≥ 32] + .op(SUB) // stack: | ... | c | d ], where d ≡ ¬c ≡ [RDS ≥ 32] .push(WORD_SIZE) - .op(MUL) // stack: [ (d ? 32 : 0) | c | ... [ - .op(SWAP1) // stack: [ c | (d ? 32 : 0) | ... [ + .op(MUL) // stack: | ... | c | (d ? 32 : 0) ] + .op(SWAP1) // stack: | ... | (d ? 32 : 0) | c ] .op(RETURNDATASIZE) - .op(MUL) // stack: [ (c ? RDS : 0) | (d ? 32 : 0) | ... [ - .op(ADD) // stack: [ min(RDS, 32) | ... [ + .op(MUL) // stack: | ... | (d ? 32 : 0) | (c ? RDS : 0) ] + .op(ADD) // stack: | ... | min(RDS, 32) ] ; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index 733dbab7de..6f6220ebc7 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -47,27 +47,33 @@ public class CodeExecutionMethods { public static final Address rootAddress = Address.fromHexString("7007"); public static final ToyAccount.ToyAccountBuilder root = - ToyAccount.builder().address(rootAddress).balance(Wei.of(65536L)).nonce(1865); + ToyAccount.builder().address(rootAddress).balance(Wei.of(0xff1122ccL)).nonce(1865); public static final Address chadPrcEnjoyerAddress = Address.fromHexString("cbad"); public static final ToyAccount.ToyAccountBuilder chadPrcEnjoyer = - ToyAccount.builder().address(chadPrcEnjoyerAddress).balance(Wei.of(1024L)).nonce(64); + ToyAccount.builder().address(chadPrcEnjoyerAddress).balance(Wei.of(0xff003300L)).nonce(64); public static final Address initCodeOwnerAddress = Address.fromHexString("1717"); public static final ToyAccount.ToyAccountBuilder initCodeOwner = - ToyAccount.builder().address(initCodeOwnerAddress).balance(Wei.of(0x1337L)).nonce(127); + ToyAccount.builder().address(initCodeOwnerAddress).balance(Wei.of(0xff1337L)).nonce(127); public static final Address foreignCodeOwnerAddress = Address.fromHexString("f00d"); public static final ToyAccount.ToyAccountBuilder foreignCodeOwner = - ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0x1789L)).nonce(255); - - public static final Address codeHolderAddress1 = Address.fromHexString("d00d"); - public static final ToyAccount.ToyAccountBuilder codeHolder1 = - ToyAccount.builder().address(codeHolderAddress1).balance(Wei.of(0x2025)).nonce(0x11aaff); - - public static final Address codeHolderAddress2 = Address.fromHexString("dada"); - public static final ToyAccount.ToyAccountBuilder codeHolder2 = - ToyAccount.builder().address(codeHolderAddress2).balance(Wei.of(0x2025)).nonce(0x11aaff); + ToyAccount.builder().address(foreignCodeOwnerAddress).balance(Wei.of(0xff1789L)).nonce(255); + + public static final Address memoryContentsHolderAddress1 = Address.fromHexString("d00d"); + public static final ToyAccount.ToyAccountBuilder memoryContentsHolder1 = + ToyAccount.builder() + .address(memoryContentsHolderAddress1) + .balance(Wei.of(0xff2025L)) + .nonce(0x11aaff); + + public static final Address memoryContentsHolderAddress2 = Address.fromHexString("dada"); + public static final ToyAccount.ToyAccountBuilder memoryContentsHolder2 = + ToyAccount.builder() + .address(memoryContentsHolderAddress2) + .balance(Wei.of(0xff1776L)) + .nonce(0x11aabb); public static final ToyTransaction.ToyTransactionBuilder transaction = ToyTransaction.builder() @@ -226,7 +232,7 @@ private static List listOfAccounts() { initCodeOwner.build(), foreignCodeOwner.build(), chadPrcEnjoyer.build(), - codeHolder1.build(), - codeHolder2.build()); + memoryContentsHolder1.build(), + memoryContentsHolder2.build()); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java index b7e9c79ecb..19aea3ab4a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java @@ -16,7 +16,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolderAddress2; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolderAddress2; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; @@ -113,17 +113,7 @@ public void singleMessageCallTransactionTest() { /** * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy - * path testing of MODEXP. This code does the following: - * - *

- populate memory with the data for first MODEXP call - * - *

- perform first MODEXP call and play around with its return data - * - *

- wipe return data - * - *

- populate memory with the data for second MODEXP call - * - *

- perform second MODEXP call and play around with its return data + * path testing of ECADD. This code does the following: * * @param params * @return @@ -135,7 +125,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters BytecodeCompiler program = BytecodeCompiler.newProgram(); // populate memory with the data for first ECADD call - copyForeignCodeToRam(program, codeHolderAddress1); + copyForeignCodeToRam(program, memoryContentsHolderAddress1); // happy path: first ECADD call appendHappyPathPrecompileCall(program, params); @@ -149,7 +139,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters loadFirstReturnDataWordOntoStack(program, 48); // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, codeHolderAddress2); + copyForeignCodeToRam(program, memoryContentsHolderAddress2); // happy path: second ECADD call appendHappyPathPrecompileCall(program, params); @@ -162,12 +152,10 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters private void setCodeOfHolderAccounts(CallParameters params) { BytecodeCompiler code1 = params.memoryContent.memoryContents(); - params.switchVariants(); - BytecodeCompiler code2 = params.memoryContent.memoryContents(); - codeHolder1.code(code1.compile()); - codeHolder2.code(code2.compile()); + memoryContentsHolder1.code(code1.compile()); + memoryContentsHolder2.code(code2.compile()); } public static Stream happyPathParameterGeneration() { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java index 89b54842db..8d704ea658 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java @@ -82,6 +82,9 @@ public void switchVariants() { */ public BytecodeCompiler memoryContents() { + // we switch with every call + this.switchVariants(); + // Note that 4 = 2 * 2. We need 4 * 32 hex characters for the data representing a point. String pointData = switch (this) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java index 7d88491d33..8ea9770f20 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java @@ -14,14 +14,14 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder1; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; + import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; import net.consensys.linea.zktracer.opcode.OpCode; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolder1; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.codeHolder2; - public class CallParameters { public final OpCode call; public final GasParameter gas; @@ -45,18 +45,12 @@ public CallParameters( this.willRevert = willRevert; } - public void switchVariants() { - memoryContent.switchVariants(); - } - public void setCodeOfHolderAccounts() { BytecodeCompiler code1 = this.memoryContent.memoryContents(); - this.switchVariants(); - BytecodeCompiler code2 = this.memoryContent.memoryContents(); - codeHolder1.code(code1.compile()); - codeHolder2.code(code2.compile()); + memoryContentsHolder1.code(code1.compile()); + memoryContentsHolder2.code(code2.compile()); } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java index b7bfa8520a..e77fcc61f6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java @@ -14,120 +14,122 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul.CallDataSizeParameter; import org.hyperledger.besu.datatypes.Address; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - @Tag("weekly") public class HappyPathTests { - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest() { - CallParameters params = - new CallParameters( - CALL, - GasParameter.COST, - MemoryContentsParameter.WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, - CallDataSizeParameter.FULL, - ReturnAtParameter.FULL, - true); - - params.setCodeOfHolderAccounts(); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + GasParameter.COST, + MemoryContentsParameter.WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); + + params.setCodeOfHolderAccounts(); + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { + + params.setCodeOfHolderAccounts(); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first ECMUL call + copyForeignCodeToRam(program, memoryContentsHolderAddress1); + + // happy path: first ECMUL call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("deadc0ffee"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second MODEXP call + copyForeignCodeToRam(program, memoryContentsHolderAddress2); + + // happy path: second ECMUL call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x11); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + return program; + } + + /** + * Constructs a call to the ECADD precompile in terms of {@link + * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.CallParameters}. + */ + public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); } - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { - - params.setCodeOfHolderAccounts(); - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - // populate memory with the data for first ECMUL call - copyForeignCodeToRam(program, codeHolderAddress1); - - // happy path: first ECMUL call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); - loadFirstReturnDataWordOntoStack(program, 0x02ff); + // push the r@o onto the stack + program.push(3 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case EMPTY -> program.push(0); + // partial words + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_3f -> program.push(0x3f); + // full words + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_60 -> program.push(0x60); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); + } - // return data wiping - appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("deadc0ffee"), 13, 15, 17, 19); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); - loadFirstReturnDataWordOntoStack(program, 48); + // push the cdo onto the stack; + program.push(0); - // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, codeHolderAddress2); + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(0x0400); + } - // happy path: second ECMUL call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x11); - loadFirstReturnDataWordOntoStack(program, 0x02ff); + program.push(Address.ALTBN128_MUL); - return program; + // push gas onto the stack + int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; + switch (params.gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(5_999 - callStipend); + case COST -> program.push(6_000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); } - /** Constructs a call to the ECADD precompile in terms of {@link net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.CallParameters}. */ - public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push(23); - case FULL -> program.push(2 * WORD_SIZE); - default -> throw new RuntimeException("Unsupported returnAt parameter"); - } - - // push the r@o onto the stack - program.push(3 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case EMPTY -> program.push(0); - // partial words - case NONEMPTY_1f -> program.push(0x1f); - case NONEMPTY_3f -> program.push(0x3f); - // full words - case NONEMPTY_20 -> program.push(0x20); - case NONEMPTY_40 -> program.push(0x40); - case NONEMPTY_60 -> program.push(0x60); - case FULL -> program.op(MSIZE); - case LARGE -> program.push("ff".repeat(WORD_SIZE)); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(0x0400); - } - - program.push(Address.ALTBN128_MUL); - - // push gas onto the stack - int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; - switch (params.gas) { - case ZERO -> program.push(0); // interesting in the nonzero value case - case COST_MO -> program.push(5_999 - callStipend); - case COST -> program.push(6_000 - callStipend); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - - program.op(params.call); - } + program.op(params.call); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java index 5299d92729..1a853b231d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java @@ -60,8 +60,17 @@ public void switchVariants() { variant = !variant; } + /** + * Note. Calling this method twice in a row on the same {@link MemoryContentsParameter}'s + * generally results in two different outputs. Indeed, this method starts by switching the {@link + * #variant}. + * + * @return + */ public BytecodeCompiler memoryContents() { + this.switchVariants(); + int nBytes = 11; String pointData = diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java index 5f6b3529a4..53c2baa023 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java @@ -14,47 +14,47 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.opcode.OpCode; -import org.junit.jupiter.params.provider.Arguments; +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; -import static net.consensys.linea.zktracer.opcode.OpCode.*; -import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; public class ParameterGeneration { - public static Stream happyPathParameterGeneration() { - List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - List GasParameters = - List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); - List ReturnAtParameters = - List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); - - List argumentsList = new ArrayList<>(); - - for (OpCode opCode : CallOpCodes) { // 4 - for (GasParameter gas : GasParameters) { // 4 - for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 - for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 - for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 - - argumentsList.add( - Arguments.of( - new CallParameters(opCode, gas, memoryContent, cds, returnAt, true))); - - argumentsList.add( - Arguments.of( - new CallParameters(opCode, gas, memoryContent, cds, returnAt, false))); - } - } - } + public static Stream happyPathParameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + List GasParameters = + List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); + List ReturnAtParameters = + List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { // 4 + for (GasParameter gas : GasParameters) { // 4 + for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, true))); + + argumentsList.add( + Arguments.of( + new CallParameters(opCode, gas, memoryContent, cds, returnAt, false))); } + } } - return argumentsList.stream(); + } } + return argumentsList.stream(); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java index 97e5f074f8..d423601a5d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java @@ -15,10 +15,10 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; public enum CallDataSizeParameter { - EMPTY, - // partial data - MISSING_FINAL_BYTE_OF_R, - MISSING_FINAL_BYTE_OF_S, - // full data - FULL; + EMPTY, + // partial data + MISSING_FINAL_BYTE_OF_R, + MISSING_FINAL_BYTE_OF_S, + // full data + FULL; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java index dcec39a765..b673c25f47 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java @@ -20,25 +20,25 @@ public class CallParameters { - public final OpCode call; - public final GasParameter gas; - public final MemoryContentsParameter memoryContent; - public final CallDataSizeParameter cds; - public final ReturnAtParameter returnAt; - public final boolean willRevert; + public final OpCode call; + public final GasParameter gas; + public final MemoryContentsParameter memoryContent; + public final CallDataSizeParameter cds; + public final ReturnAtParameter returnAt; + public final boolean willRevert; - public CallParameters( - OpCode call, - GasParameter gas, - MemoryContentsParameter memoryContent, - CallDataSizeParameter cds, - ReturnAtParameter returnAt, - boolean willRevert) { - this.call = call; - this.gas = gas; - this.memoryContent = memoryContent; - this.cds = cds; - this.returnAt = returnAt; - this.willRevert = willRevert; - } + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContentsParameter memoryContent, + CallDataSizeParameter cds, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContent = memoryContent; + this.cds = cds; + this.returnAt = returnAt; + this.willRevert = willRevert; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java index 99307f4b8f..4e5c69036e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java @@ -14,81 +14,81 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; -import net.consensys.linea.testing.BytecodeCompiler; -import org.apache.tuweni.bytes.Bytes; -import org.apache.tuweni.bytes.Bytes32; - import static com.google.common.base.Preconditions.checkState; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.MAX_WORD; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -public record EcRecoverTuple( - String h, - String v, - String r, - String s -) { +import net.consensys.linea.testing.BytecodeCompiler; +import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; - public static String SECP_256_K1N = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; - public static String ZERO = "00".repeat(WORD_SIZE); +public record EcRecoverTuple(String h, String v, String r, String s) { - /** - * {@link #memoryContents} converts the {@link EcRecoverTuple} into the byte slice - * - *

[ h | v | r | s | ff .. ff ] - * - *

and optionally on {@code changeFinalByteOfS} modifies the final byte of s. - * As per usual, the purpose of the last EVM word is to be overwritten by return data. - * @param changeFinalByteOfS - * @return - */ - public BytecodeCompiler memoryContents(boolean changeFinalByteOfS) { - Bytes hBytes = Bytes32.leftPad(Bytes.fromHexString(h)); - Bytes vBytes = Bytes32.leftPad(Bytes.fromHexString(v)); - Bytes rBytes = Bytes32.leftPad(Bytes.fromHexString(r)); - Bytes sBytes = Bytes32.leftPad(Bytes.fromHexString(s)); + public static String SECP_256_K1N = + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; + public static String ZERO = "00".repeat(WORD_SIZE); - if (changeFinalByteOfS) { - sBytes = sBytes.xor(Bytes32.leftPad(Bytes.ofUnsignedLong(0xff))); - } + /** + * {@link #memoryContents} converts the {@link EcRecoverTuple} into the byte slice + * + *

[ h | v | r | s | ff .. ff ] + * + *

and optionally on {@code changeFinalByteOfS} modifies the final byte of s. As per + * usual, the purpose of the last EVM word is to be overwritten by return data. + * + * @param changeFinalByteOfS + * @return + */ + public BytecodeCompiler memoryContents(boolean changeFinalByteOfS) { + Bytes hBytes = Bytes32.leftPad(Bytes.fromHexString(h)); + Bytes vBytes = Bytes32.leftPad(Bytes.fromHexString(v)); + Bytes rBytes = Bytes32.leftPad(Bytes.fromHexString(r)); + Bytes sBytes = Bytes32.leftPad(Bytes.fromHexString(s)); - Bytes pointData = Bytes.concatenate(hBytes, vBytes, rBytes, sBytes, Bytes.fromHexString(MAX_WORD)); + if (changeFinalByteOfS) { + sBytes = sBytes.xor(Bytes32.leftPad(Bytes.ofUnsignedLong(0xff))); + } - checkState(pointData.size() == 5 * WORD_SIZE); + Bytes pointData = + Bytes.concatenate(hBytes, vBytes, rBytes, sBytes, Bytes.fromHexString(MAX_WORD)); - BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); - memoryContents.immediate(pointData); + checkState(pointData.size() == 5 * WORD_SIZE); - return memoryContents; - } + BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); + memoryContents.immediate(pointData); - /** - * {@link #replaceR} produces a copy of {@code this} with {@link #r} replaced by either - * - *

- {@link #ZERO} - *

- {@link #SECP_256_K1N} - * - * @param useZero - * @return - */ - public EcRecoverTuple replaceR(boolean useZero) { - return new EcRecoverTuple(h, v, zeroOrPrime(useZero), s); - } + return memoryContents; + } - /** - * {@link #replaceS} produces a copy of {@code this} with {@link #s} replaced by either - * - *

- {@link #ZERO} - *

- {@link #SECP_256_K1N} - * - * @param useZero - * @return - */ - public EcRecoverTuple replaceS(boolean useZero) { - return new EcRecoverTuple(h, v, r, zeroOrPrime(useZero)); - } + /** + * {@link #replaceR} produces a copy of {@code this} with {@link #r} replaced by either + * + *

- {@link #ZERO} + * + *

- {@link #SECP_256_K1N} + * + * @param useZero + * @return + */ + public EcRecoverTuple replaceR(boolean useZero) { + return new EcRecoverTuple(h, v, zeroOrPrime(useZero), s); + } - private String zeroOrPrime(boolean returnZero) { - return returnZero ? ZERO : SECP_256_K1N; - } -} \ No newline at end of file + /** + * {@link #replaceS} produces a copy of {@code this} with {@link #s} replaced by either + * + *

- {@link #ZERO} + * + *

- {@link #SECP_256_K1N} + * + * @param useZero + * @return + */ + public EcRecoverTuple replaceS(boolean useZero) { + return new EcRecoverTuple(h, v, r, zeroOrPrime(useZero)); + } + + private String zeroOrPrime(boolean returnZero) { + return returnZero ? ZERO : SECP_256_K1N; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java index 1972ce6f12..42ee45923a 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java @@ -14,54 +14,176 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; -import net.consensys.linea.testing.BytecodeCompiler; -import org.hyperledger.besu.datatypes.Address; - +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import static net.consensys.linea.zktracer.opcode.OpCode.*; +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; +import org.hyperledger.besu.datatypes.Address; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@Tag("weekly") public class HappyPathTests { - /** Constructs a call to the ECADD precompile in terms of {@link CallParameters}. */ - public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push(12 + 6); // the first 12 bytes are zeros for successful ECRECOVER calls - case FULL -> program.push(WORD_SIZE); - } - - // push the r@o onto the stack - program.push(4 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case EMPTY -> program.push(0); - case MISSING_FINAL_BYTE_OF_R -> program.push(3 * WORD_SIZE - 1); - case MISSING_FINAL_BYTE_OF_S -> program.push(4 * WORD_SIZE - 1); - case FULL -> program.op(MSIZE); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(0x0600); - } - - program.push(Address.ECREC); - - // push gas onto the stack - int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; - switch (params.gas) { - case ZERO -> program.push(0); // interesting in the nonzero value case - case COST_MO -> program.push(3000 - callStipend - 1); - case COST -> program.push(3000 - callStipend); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - program.op(params.call); + /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallTransactionTest(CallParameters params) { + + BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(rootCode, 0, 4 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void deploymentTransactionTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 4 * WORD_SIZE); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void messageCallFromRootTest(CallParameters params) { + + BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); + if (params.willRevert) revertWith(txInitCode, 0, 0); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. + * + * @param params + */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathDuringCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runForeignByteCodeAsInitCode(foreignCode, params.willRevert); + } + + /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ + @ParameterizedTest + @MethodSource("happyPathParameterGeneration") + public void happyPathAfterCreate(CallParameters params) { + BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); + runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); + } + + /** + * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy + * path testing of ECRECOVER. This code does the following: + * + * @param params + * @return + */ + private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { + + setCodeOfHolderAccounts(params); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first ECRECOVER call + copyForeignCodeToRam(program, memoryContentsHolderAddress1); + + // happy path: first ECRECOVER call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x2a); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("b077c0ffee1337"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second ECRECOVER call + copyForeignCodeToRam(program, memoryContentsHolderAddress2); + + // happy path: second ECRECOVER call + appendHappyPathPrecompileCall(program, params); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); + loadFirstReturnDataWordOntoStack(program, 0x00); + + return program; + } + + private void setCodeOfHolderAccounts(CallParameters params) { + + // implicitly switches variants thus producing different contents + BytecodeCompiler contents1 = params.memoryContent.memoryContents(); + BytecodeCompiler contents2 = params.memoryContent.memoryContents(); + + memoryContentsHolder1.code(contents1.compile()); + memoryContentsHolder2.code(contents2.compile()); + } + + public static Stream happyPathParameterGeneration() { + return ParameterGeneration.happyPathParameterGeneration(); + } + + /** Constructs a call to the ECRECOVER precompile in terms of {@link CallParameters}. */ + public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { + + // push r@c onto the stack + switch (params.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push( + 12 + 6); // the first 12 bytes are zeros for successful ECRECOVER calls + case FULL -> program.push(WORD_SIZE); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (params.cds) { + case EMPTY -> program.push(0); + case MISSING_FINAL_BYTE_OF_R -> program.push(3 * WORD_SIZE - 1); + case MISSING_FINAL_BYTE_OF_S -> program.push(4 * WORD_SIZE - 1); + case FULL -> program.op(MSIZE); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (params.call.callHasValueArgument()) { + program.push(0x0600); + } + + program.push(Address.ECREC); + + // push gas onto the stack + int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; + switch (params.gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(3000 - callStipend - 1); + case COST -> program.push(3000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); } + program.op(params.call); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java index 8de203321f..743d1e7984 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java @@ -90,13 +90,13 @@ public void switchVariants() { "4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852ada"); /** - * {@link #EVM_CODES_EXAMPLE_MANIPULATED} is derived rom that of {@link #EVM_CODES_EXAMPLE} via + * {@link #EVM_CODES_EXAMPLE_MALLEABLE} is derived from {@link #EVM_CODES_EXAMPLE} via * - *

switch v to other value (27 ↔ 28) + *

- switching v to other value (27 ↔ 28) * - *

{@link EcRecoverTuple#SECP_256_K1N} - s + *

- switching s to its opposite (s' ← {@link EcRecoverTuple#SECP_256_K1N} - s) */ - public static final EcRecoverTuple EVM_CODES_EXAMPLE_MANIPULATED = + public static final EcRecoverTuple EVM_CODES_EXAMPLE_MALLEABLE = new EcRecoverTuple( "456e9aea5e197a1f1af7a3e85a3212fa4049a3ba34c2289b4c860fc0b0c64ef3", "27", @@ -111,8 +111,9 @@ public void switchVariants() { RND.substring(192, 192 + WORD_HEX_SIZE)); /** - * {@link #memoryContents} converts the {@link MemoryContentsParameter} into a byte slice - * containing "interesting" memory contents for a ECRECOVER call. + * {@link #memoryContents} converts the {@link MemoryContentsParameter} into a {@link + * BytecodeCompiler} (from which we will later extract a byte slice) containing "interesting" + * memory contents for a ECRECOVER call. * *

Note. Calling this method twice in a row on the same {@link * MemoryContentsParameter}'s generally results in two different outputs. Indeed, this method @@ -161,7 +162,7 @@ public BytecodeCompiler memoryContents() { case MALLEABLE -> { return variant ? EVM_CODES_EXAMPLE.memoryContents(false) - : EVM_CODES_EXAMPLE_MANIPULATED.memoryContents(false); + : EVM_CODES_EXAMPLE_MALLEABLE.memoryContents(false); } default -> throw new RuntimeException("Unknown MemoryContentsParameter"); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java index 37c9c4f4f9..a46a963aa9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java @@ -163,7 +163,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters BytecodeCompiler program = BytecodeCompiler.newProgram(); // populate memory with the data for first MODEXP call - copyForeignCodeToRam(program, codeHolderAddress1); + copyForeignCodeToRam(program, memoryContentsHolderAddress1); // happy path: first MODEXP call appendHappyPathPrecompileCall(program, params, variant1); @@ -177,7 +177,7 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters loadFirstReturnDataWordOntoStack(program, 48); // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, codeHolderAddress2); + copyForeignCodeToRam(program, memoryContentsHolderAddress2); // happy path: second MODEXP call appendHappyPathPrecompileCall(program, params, variant2); @@ -188,8 +188,9 @@ private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters } /** - * Populate the byte code of {@link CodeExecutionMethods#codeHolder1} and {@link - * CodeExecutionMethods#codeHolder2} with "byte code" that is well-formed data for a MODEXP call. + * Populate the byte code of {@link CodeExecutionMethods#memoryContentsHolder1} and {@link + * CodeExecutionMethods#memoryContentsHolder2} with "byte code" that is well-formed data for a + * MODEXP call. * * @param params */ @@ -198,8 +199,8 @@ private void setCodeOfHolderAccounts(CallParameters params) { String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); - codeHolder1.code(Bytes.fromHexString(code1)); - codeHolder2.code(Bytes.fromHexString(code2)); + memoryContentsHolder1.code(Bytes.fromHexString(code1)); + memoryContentsHolder2.code(Bytes.fromHexString(code2)); } public static Stream happyPathParameterGeneration() { From 672d7ab003a626a09b164dc8f818df2d4337f4d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= <38285177+OlivierBBB@users.noreply.github.com> Date: Thu, 20 Feb 2025 20:55:18 +0100 Subject: [PATCH 42/57] Generic precompile testing methods (#1837) --- .../callTests/prc/CodeExecutionMethods.java | 9 +- .../callTests/prc/ecadd/CallParameters.java | 96 ++++++- .../callTests/prc/ecadd/HappyPathTests.java | 217 -------------- ...entsParameter.java => MemoryContents.java} | 15 +- .../prc/ecadd/ParameterGeneration.java | 4 +- .../callTests/prc/ecadd/Tests.java | 53 ++++ .../prc/ecmul/CallDataSizeParameter.java | 2 +- .../callTests/prc/ecmul/CallParameters.java | 95 +++++- .../callTests/prc/ecmul/HappyPathTests.java | 135 --------- ...entsParameter.java => MemoryContents.java} | 24 +- .../prc/ecmul/ParameterGeneration.java | 4 +- .../callTests/prc/ecmul/Tests.java | 57 ++++ .../prc/ecrecover/CallDataSizeParameter.java | 3 +- .../prc/ecrecover/CallParameters.java | 85 +++++- .../prc/ecrecover/EcRecoverTuple.java | 2 +- .../prc/ecrecover/HappyPathTests.java | 189 ------------ ...entsParameter.java => MemoryContents.java} | 27 +- .../prc/ecrecover/ParameterGeneration.java | 4 +- .../callTests/prc/ecrecover/Tests.java | 28 ++ .../PrecompileCallMemoryContents.java | 33 +++ .../frameWork/PrecompileCallParameters.java | 68 +++++ .../prc/frameWork/PrecompileCallTests.java | 104 +++++++ .../callTests/prc/hash/CallParameters.java | 169 +++++++++++ .../callTests/prc/hash/HappyPathTests.java | 235 --------------- .../hash/HashPrecompileCallParameters.java | 65 ----- .../callTests/prc/hash/MemoryContents.java | 37 +++ .../prc/hash/ParameterGeneration.java | 9 +- .../callTests/prc/hash/Tests.java | 92 ++++++ .../prc/modexp/ByteSizeParameter.java | 9 + .../callTests/prc/modexp/CallParameters.java | 24 +- .../callTests/prc/modexp/HappyPathTests.java | 272 ------------------ ...DataParameter.java => MemoryContents.java} | 110 ++++--- .../prc/modexp/ParameterGeneration.java | 6 +- .../callTests/prc/modexp/Tests.java | 83 ++++++ 34 files changed, 1112 insertions(+), 1253 deletions(-) delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/{MemoryContentsParameter.java => MemoryContents.java} (95%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/{MemoryContentsParameter.java => MemoryContents.java} (84%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/{MemoryContentsParameter.java => MemoryContents.java} (88%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/{CallDataParameter.java => MemoryContents.java} (85%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java index 6f6220ebc7..be83aeadb9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/CodeExecutionMethods.java @@ -32,11 +32,14 @@ /** * The following class provides methods to run code in the following contexts: * - *

- MESSAGE_CALL_TRANSACTION: at depth 0 in the root context of a + *

- MESSAGE_CALL_TRANSACTION: at depth 0 in the root context of a message call + * transaction * - *

- CONTRACT_DEPLOYMENT_TRANSACTION: at depth 0 in the root context of a + *

- CONTRACT_DEPLOYMENT_TRANSACTION: at depth 0 in the root context of a contract + * deployment transaction * - *

- MESSAGE_CALL_FROM_ROOT: at depth 1 as the byte code executed in a CALL + *

- MESSAGE_CALL_FROM_ROOT: at depth 1 as the byte code executed in a CALL to a + * SMC * *

- DURING_DEPLOYMENT: at depth 1 as the init code of a CREATE * diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java index afaf79a438..241892f29f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java @@ -14,15 +14,23 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; +import static net.consensys.linea.zktracer.opcode.OpCode.MSIZE; + +import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; -public class CallParameters { +public class CallParameters implements PrecompileCallParameters { public final OpCode call; public final GasParameter gas; - public final MemoryContentsParameter memoryContent; + public final MemoryContents memoryContents; public final CallDataSizeParameter cds; public final ReturnAtParameter returnAt; public final boolean willRevert; @@ -30,19 +38,95 @@ public class CallParameters { public CallParameters( OpCode call, GasParameter gas, - MemoryContentsParameter memoryContent, + MemoryContents memoryContents, CallDataSizeParameter cds, ReturnAtParameter returnAt, boolean willRevert) { this.call = call; this.gas = gas; - this.memoryContent = memoryContent; + this.memoryContents = memoryContents; this.cds = cds; this.returnAt = returnAt; this.willRevert = willRevert; } - public void switchVariants() { - memoryContent.switchVariants(); + @Override + public boolean willRevert() { + return willRevert; + } + + @Override + public PrecompileCallMemoryContents memoryContents() { + return memoryContents; + } + + @Override + public void appendCustomPrecompileCall(BytecodeCompiler program) { + // push r@c onto the stack + switch (returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (cds) { + case EMPTY -> program.push(0); + // partial words + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_3f -> program.push(0x3f); + case NONEMPTY_5f -> program.push(0x5f); + case NONEMPTY_7f -> program.push(0x7f); + // full words + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_60 -> program.push(0x60); + case NONEMPTY_80 -> program.push(0x80); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (call.callHasValueArgument()) { + program.push(willRevert ? 0x0200 : 0); + } + + program.push(Address.ALTBN128_ADD); + + // push gas onto the stack + switch (gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(149); + case COST -> program.push(150); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(call); + } + + @Override + public String toString() { + return "CallParameters{" + + "call=" + + call + + ", gas=" + + gas + + ", memoryContents=" + + memoryContents + + ", cds=" + + cds + + ", returnAt=" + + returnAt + + ", willRevert=" + + willRevert + + '}'; } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java deleted file mode 100644 index 19aea3ab4a..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/HappyPathTests.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolderAddress2; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - -import java.util.stream.Stream; - -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import org.hyperledger.besu.datatypes.Address; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -@Tag("weekly") -public class HappyPathTests { - - /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParameters params) { - - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 0, 5 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 5 * WORD_SIZE); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 0); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** - * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. - * - *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose - * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the - * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code - * of a CREATE. The whole operation optionally REVERT's. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); - } - - /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); - } - - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest() { - CallParameters params = - new CallParameters( - CALL, - GasParameter.COST_MO, - MemoryContentsParameter.WELL_FORMED_POINTS, - CallDataSizeParameter.FULL, - ReturnAtParameter.FULL, - true); - - setCodeOfHolderAccounts(params); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** - * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy - * path testing of ECADD. This code does the following: - * - * @param params - * @return - */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { - - setCodeOfHolderAccounts(params); - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - // populate memory with the data for first ECADD call - copyForeignCodeToRam(program, memoryContentsHolderAddress1); - - // happy path: first ECADD call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - // return data wiping - appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("c0ffeebabe"), 13, 15, 17, 19); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); - loadFirstReturnDataWordOntoStack(program, 48); - - // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, memoryContentsHolderAddress2); - - // happy path: second ECADD call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - return program; - } - - private void setCodeOfHolderAccounts(CallParameters params) { - - BytecodeCompiler code1 = params.memoryContent.memoryContents(); - BytecodeCompiler code2 = params.memoryContent.memoryContents(); - - memoryContentsHolder1.code(code1.compile()); - memoryContentsHolder2.code(code2.compile()); - } - - public static Stream happyPathParameterGeneration() { - return ParameterGeneration.happyPathParameterGeneration(); - } - - /** Constructs a call to the ECADD precompile in terms of {@link CallParameters}. */ - public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push(23); - case FULL -> program.push(2 * WORD_SIZE); - default -> throw new RuntimeException("Unsupported returnAt parameter"); - } - - // push the r@o onto the stack - program.push(4 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case EMPTY -> program.push(0); - // partial words - case NONEMPTY_1f -> program.push(0x1f); - case NONEMPTY_3f -> program.push(0x3f); - case NONEMPTY_5f -> program.push(0x5f); - case NONEMPTY_7f -> program.push(0x7f); - // full words - case NONEMPTY_20 -> program.push(0x20); - case NONEMPTY_40 -> program.push(0x40); - case NONEMPTY_60 -> program.push(0x60); - case NONEMPTY_80 -> program.push(0x80); - case FULL -> program.op(MSIZE); - case LARGE -> program.push("ff".repeat(WORD_SIZE)); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(params.willRevert ? 0x0200 : 0); - } - - program.push(Address.ALTBN128_ADD); - - // push gas onto the stack - switch (params.gas) { - case ZERO -> program.push(0); // interesting in the nonzero value case - case COST_MO -> program.push(149); - case COST -> program.push(150); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - - program.op(params.call); - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java similarity index 95% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java index 8d704ea658..785cf98ba5 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java @@ -19,9 +19,10 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE_MO; import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; -public enum MemoryContentsParameter { +public enum MemoryContents implements PrecompileCallMemoryContents { ZEROS, WELL_FORMED_POINTS, MIXED, @@ -34,10 +35,6 @@ public enum MemoryContentsParameter { boolean variant = false; - public void switchVariants() { - variant = !variant; - } - // coordinates for 5 curve points public static final String A_X = "08d555288636cfb5abeac1d38a828fc4d975fb8def9f63a34f8c91701b5478d1"; @@ -63,6 +60,11 @@ public void switchVariants() { public static final String MAX_WORD = "ff".repeat(WORD_SIZE); public static final int WORD_HEX_SIZE = 2 * WORD_SIZE; + @Override + public void switchVariant() { + variant = !variant; + } + /** * Constructs a slice of bytes of the following form * @@ -82,9 +84,6 @@ public void switchVariants() { */ public BytecodeCompiler memoryContents() { - // we switch with every call - this.switchVariants(); - // Note that 4 = 2 * 2. We need 4 * 32 hex characters for the data representing a point. String pointData = switch (this) { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index 0f1d27a625..37da6fc41d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -52,7 +52,7 @@ public class ParameterGeneration { *

- ReturnAtParameter the return at parameter to be tested; return data will be written * on the aforementioned blackened word in RAM; */ - public static Stream happyPathParameterGeneration() { + public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); @@ -63,7 +63,7 @@ public static Stream happyPathParameterGeneration() { for (OpCode opCode : CallOpCodes) { // 4 for (GasParameter gas : GasParameters) { // 4 - for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (MemoryContents memoryContent : MemoryContents.values()) { // 9 for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java new file mode 100644 index 0000000000..d5362a6759 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java @@ -0,0 +1,53 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST_MO; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WELL_FORMED_POINTS; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; + +@Tag("weekly") +public class Tests extends PrecompileCallTests { + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + COST_MO, + WELL_FORMED_POINTS, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java index 467c835499..545659be46 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallDataSizeParameter.java @@ -24,7 +24,7 @@ public enum CallDataSizeParameter { // partial words NONEMPTY_1f, // 32 - 1 bytes NONEMPTY_3f, // 64 - 1 bytes - NONEMPTY_4d, // 64 + 11 bytes + NONEMPTY_4d, // 64 + 13 bytes // full words NONEMPTY_20, NONEMPTY_40, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java index 8ea9770f20..81f106daec 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java @@ -14,18 +14,22 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder1; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; +import static net.consensys.linea.zktracer.opcode.OpCode.MSIZE; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; -public class CallParameters { +public class CallParameters implements PrecompileCallParameters { public final OpCode call; public final GasParameter gas; - public final MemoryContentsParameter memoryContent; + public final MemoryContents memoryContents; public final CallDataSizeParameter cds; public final ReturnAtParameter returnAt; public final boolean willRevert; @@ -33,24 +37,93 @@ public class CallParameters { public CallParameters( OpCode call, GasParameter gas, - MemoryContentsParameter memoryContent, + MemoryContents memoryContents, CallDataSizeParameter cds, ReturnAtParameter returnAt, boolean willRevert) { this.call = call; this.gas = gas; - this.memoryContent = memoryContent; + this.memoryContents = memoryContents; this.cds = cds; this.returnAt = returnAt; this.willRevert = willRevert; } - public void setCodeOfHolderAccounts() { + @Override + public boolean willRevert() { + return willRevert; + } + + @Override + public PrecompileCallMemoryContents memoryContents() { + return memoryContents; + } + + @Override + public void appendCustomPrecompileCall(BytecodeCompiler program) { + // push r@c onto the stack + switch (this.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(23); + case FULL -> program.push(2 * WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(3 * WORD_SIZE); + + // push the cds onto the stack + switch (cds) { + case EMPTY -> program.push(0); + // partial words + case NONEMPTY_1f -> program.push(0x1f); + case NONEMPTY_3f -> program.push(0x3f); + // full words + case NONEMPTY_20 -> program.push(0x20); + case NONEMPTY_40 -> program.push(0x40); + case NONEMPTY_60 -> program.push(0x60); + case FULL -> program.op(MSIZE); + case LARGE -> program.push("ff".repeat(WORD_SIZE)); + } - BytecodeCompiler code1 = this.memoryContent.memoryContents(); - BytecodeCompiler code2 = this.memoryContent.memoryContents(); + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (call.callHasValueArgument()) { + program.push(0x0400); + } + + program.push(Address.ALTBN128_MUL); + + // push gas onto the stack + int callStipend = call.callHasValueArgument() ? 2_300 : 0; + switch (gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(6_000 - callStipend - 1); + case COST -> program.push(6_000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(call); + } - memoryContentsHolder1.code(code1.compile()); - memoryContentsHolder2.code(code2.compile()); + @Override + public String toString() { + return "EcmulCallParameters{" + + "call=" + + call + + ", gas=" + + gas + + ", memoryContents=" + + memoryContents + + ", cds=" + + cds + + ", returnAt=" + + returnAt + + ", willRevert=" + + willRevert + + '}'; } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java deleted file mode 100644 index e77fcc61f6..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/HappyPathTests.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import org.hyperledger.besu.datatypes.Address; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; - -@Tag("weekly") -public class HappyPathTests { - - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest() { - CallParameters params = - new CallParameters( - CALL, - GasParameter.COST, - MemoryContentsParameter.WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, - CallDataSizeParameter.FULL, - ReturnAtParameter.FULL, - true); - - params.setCodeOfHolderAccounts(); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { - - params.setCodeOfHolderAccounts(); - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - // populate memory with the data for first ECMUL call - copyForeignCodeToRam(program, memoryContentsHolderAddress1); - - // happy path: first ECMUL call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - // return data wiping - appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("deadc0ffee"), 13, 15, 17, 19); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); - loadFirstReturnDataWordOntoStack(program, 48); - - // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, memoryContentsHolderAddress2); - - // happy path: second ECMUL call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x11); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - return program; - } - - /** - * Constructs a call to the ECADD precompile in terms of {@link - * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.CallParameters}. - */ - public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push(23); - case FULL -> program.push(2 * WORD_SIZE); - default -> throw new RuntimeException("Unsupported returnAt parameter"); - } - - // push the r@o onto the stack - program.push(3 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case EMPTY -> program.push(0); - // partial words - case NONEMPTY_1f -> program.push(0x1f); - case NONEMPTY_3f -> program.push(0x3f); - // full words - case NONEMPTY_20 -> program.push(0x20); - case NONEMPTY_40 -> program.push(0x40); - case NONEMPTY_60 -> program.push(0x60); - case FULL -> program.op(MSIZE); - case LARGE -> program.push("ff".repeat(WORD_SIZE)); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(0x0400); - } - - program.push(Address.ALTBN128_MUL); - - // push gas onto the stack - int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; - switch (params.gas) { - case ZERO -> program.push(0); // interesting in the nonzero value case - case COST_MO -> program.push(5_999 - callStipend); - case COST -> program.push(6_000 - callStipend); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - - program.op(params.call); - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java similarity index 84% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java index 1a853b231d..c4a57af6a9 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java @@ -15,21 +15,22 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.*; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; /** * Enumerates the different memory contents parameters for a precompile call. Similarly to {@link - * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter}, - * memory content comprises a certain number of data words and one final EVM word where the - * CALL instruction will be required to write its return data: + * net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents}, memory + * content comprises a certain number of data words and one final EVM word where the CALL + * instruction will be required to write its return data: * *

[ COORD_X | COORD_Y || MULITIPLIER || ff .. ff ] */ -public enum MemoryContentsParameter { +public enum MemoryContents implements PrecompileCallMemoryContents { /** [ ZEROS | ZEROS || ZEROS || ff .. ff ] */ ZEROS, @@ -56,23 +57,12 @@ public enum MemoryContentsParameter { public boolean variant = false; - public void switchVariants() { + public void switchVariant() { variant = !variant; } - /** - * Note. Calling this method twice in a row on the same {@link MemoryContentsParameter}'s - * generally results in two different outputs. Indeed, this method starts by switching the {@link - * #variant}. - * - * @return - */ public BytecodeCompiler memoryContents() { - - this.switchVariants(); - int nBytes = 11; - String pointData = switch (this) { case ZEROS -> ZERO_WORD.repeat(3); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java index 53c2baa023..d9dd613a13 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java @@ -28,7 +28,7 @@ public class ParameterGeneration { - public static Stream happyPathParameterGeneration() { + public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); @@ -39,7 +39,7 @@ public static Stream happyPathParameterGeneration() { for (OpCode opCode : CallOpCodes) { // 4 for (GasParameter gas : GasParameters) { // 4 - for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (MemoryContents memoryContent : MemoryContents.values()) { // 9 for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java new file mode 100644 index 0000000000..cdc007ffaa --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java @@ -0,0 +1,57 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul.MemoryContents.WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; + +@Tag("weekly") +public class Tests extends PrecompileCallTests { + + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + COST, + WELL_FORMED_POINT_AND_NONTRIVIAL_MULTIPLIER, + CallDataSizeParameter.FULL, + ReturnAtParameter.FULL, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java index d423601a5d..014af1ab28 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallDataSizeParameter.java @@ -14,11 +14,10 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; +/** */ public enum CallDataSizeParameter { EMPTY, - // partial data MISSING_FINAL_BYTE_OF_R, MISSING_FINAL_BYTE_OF_S, - // full data FULL; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java index b673c25f47..3d6566fe1d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java @@ -14,15 +14,22 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; -public class CallParameters { +public class CallParameters implements PrecompileCallParameters { public final OpCode call; public final GasParameter gas; - public final MemoryContentsParameter memoryContent; + public final MemoryContents memoryContents; public final CallDataSizeParameter cds; public final ReturnAtParameter returnAt; public final boolean willRevert; @@ -30,15 +37,85 @@ public class CallParameters { public CallParameters( OpCode call, GasParameter gas, - MemoryContentsParameter memoryContent, + MemoryContents memoryContent, CallDataSizeParameter cds, ReturnAtParameter returnAt, boolean willRevert) { this.call = call; this.gas = gas; - this.memoryContent = memoryContent; + this.memoryContents = memoryContent; this.cds = cds; this.returnAt = returnAt; this.willRevert = willRevert; } + + public boolean willRevert() { + return willRevert; + } + + public PrecompileCallMemoryContents memoryContents() { + return memoryContents; + } + + public void appendCustomPrecompileCall(BytecodeCompiler program) { + + // push r@c onto the stack + switch (returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push( + 12 + 6); // the first 12 bytes are zeros for successful ECRECOVER calls + case FULL -> program.push(WORD_SIZE); + } + + // push the r@o onto the stack + program.push(4 * WORD_SIZE); + + // push the cds onto the stack + switch (cds) { + case EMPTY -> program.push(0); + case MISSING_FINAL_BYTE_OF_R -> program.push(3 * WORD_SIZE - 1); + case MISSING_FINAL_BYTE_OF_S -> program.push(4 * WORD_SIZE - 1); + case FULL -> program.op(MSIZE); + } + + // push the cdo onto the stack; + program.push(0); + + // if appropriate, push the value onto the stack + if (call.callHasValueArgument()) { + program.push(0x0600); + } + + program.push(Address.ECREC); + + // push gas onto the stack + int callStipend = call.callHasValueArgument() ? 2_300 : 0; + switch (gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(3000 - callStipend - 1); + case COST -> program.push(3000 - callStipend); + case FULL -> program.op(GAS); + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(call); + } + + @Override + public String toString() { + return "EcrecoverCallParameters{" + + "call=" + + call + + ", gas=" + + gas + + ", memoryContents=" + + memoryContents + + ", cds=" + + cds + + ", returnAt=" + + returnAt + + ", willRevert=" + + willRevert + + '}'; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java index 4e5c69036e..368e8ab588 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/EcRecoverTuple.java @@ -15,7 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.MAX_WORD; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.MAX_WORD; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java deleted file mode 100644 index 42ee45923a..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/HappyPathTests.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - -import java.util.stream.Stream; - -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; -import org.hyperledger.besu.datatypes.Address; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -@Tag("weekly") -public class HappyPathTests { - - /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParameters params) { - - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 0, 4 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 4 * WORD_SIZE); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 0); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** - * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. - * - *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose - * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the - * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code - * of a CREATE. The whole operation optionally REVERT's. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); - } - - /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); - } - - /** - * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy - * path testing of ECRECOVER. This code does the following: - * - * @param params - * @return - */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { - - setCodeOfHolderAccounts(params); - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - // populate memory with the data for first ECRECOVER call - copyForeignCodeToRam(program, memoryContentsHolderAddress1); - - // happy path: first ECRECOVER call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x2a); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - // return data wiping - appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("b077c0ffee1337"), 13, 15, 17, 19); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); - loadFirstReturnDataWordOntoStack(program, 48); - - // populate memory with the data for second ECRECOVER call - copyForeignCodeToRam(program, memoryContentsHolderAddress2); - - // happy path: second ECRECOVER call - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); - loadFirstReturnDataWordOntoStack(program, 0x00); - - return program; - } - - private void setCodeOfHolderAccounts(CallParameters params) { - - // implicitly switches variants thus producing different contents - BytecodeCompiler contents1 = params.memoryContent.memoryContents(); - BytecodeCompiler contents2 = params.memoryContent.memoryContents(); - - memoryContentsHolder1.code(contents1.compile()); - memoryContentsHolder2.code(contents2.compile()); - } - - public static Stream happyPathParameterGeneration() { - return ParameterGeneration.happyPathParameterGeneration(); - } - - /** Constructs a call to the ECRECOVER precompile in terms of {@link CallParameters}. */ - public void appendHappyPathPrecompileCall(BytecodeCompiler program, CallParameters params) { - - // push r@c onto the stack - switch (params.returnAt) { - case EMPTY -> program.push(0); - case PARTIAL -> program.push( - 12 + 6); // the first 12 bytes are zeros for successful ECRECOVER calls - case FULL -> program.push(WORD_SIZE); - } - - // push the r@o onto the stack - program.push(4 * WORD_SIZE); - - // push the cds onto the stack - switch (params.cds) { - case EMPTY -> program.push(0); - case MISSING_FINAL_BYTE_OF_R -> program.push(3 * WORD_SIZE - 1); - case MISSING_FINAL_BYTE_OF_S -> program.push(4 * WORD_SIZE - 1); - case FULL -> program.op(MSIZE); - } - - // push the cdo onto the stack; - program.push(0); - - // if appropriate, push the value onto the stack - if (params.call.callHasValueArgument()) { - program.push(0x0600); - } - - program.push(Address.ECREC); - - // push gas onto the stack - int callStipend = params.call.callHasValueArgument() ? 2_300 : 0; - switch (params.gas) { - case ZERO -> program.push(0); // interesting in the nonzero value case - case COST_MO -> program.push(3000 - callStipend - 1); - case COST -> program.push(3000 - callStipend); - case FULL -> program.op(GAS); - default -> throw new RuntimeException("Unsupported gas parameter"); - } - program.op(params.call); - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java similarity index 88% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java index 743d1e7984..e2ae118039 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContentsParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java @@ -14,11 +14,12 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.RND; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContentsParameter.WORD_HEX_SIZE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; /** * Memory for ECRECOVER testing will be made to contain inputs of the form @@ -26,8 +27,8 @@ *

[ h | v | r | s ] * *

where h, v, r and s are 32-byte integers and with the - * precise contents being dictated by the enum. Most values of {@link MemoryContentsParameter} - * values are self-explanatory. We will test in particular: + * precise contents being dictated by the enum. Most values of {@link MemoryContents} values are + * self-explanatory. We will test in particular: * *

- {@link #MALFORMED_AT_7f_BUT_SALVAGEABLE} for cases where s is correct save for its final * byte which would have to be 0x00 to be valid but instead is 0xff; the point @@ -38,7 +39,7 @@ *

- {@link #BOUNDARY_R} and {@link #BOUNDARY_S}: cases where r or s are equal to * 0 or the secp256k1n prime */ -public enum MemoryContentsParameter { +public enum MemoryContents implements PrecompileCallMemoryContents { ZEROS, WELL_FORMED, MALFORMED_AT_7f_BUT_SALVAGEABLE, @@ -50,7 +51,7 @@ public enum MemoryContentsParameter { boolean variant = false; - public void switchVariants() { + public void switchVariant() { variant = !variant; } @@ -111,20 +112,20 @@ public void switchVariants() { RND.substring(192, 192 + WORD_HEX_SIZE)); /** - * {@link #memoryContents} converts the {@link MemoryContentsParameter} into a {@link - * BytecodeCompiler} (from which we will later extract a byte slice) containing "interesting" - * memory contents for a ECRECOVER call. + * {@link #memoryContents} converts the {@link MemoryContents} into a {@link BytecodeCompiler} + * (from which we will later extract a byte slice) containing "interesting" memory contents for a + * ECRECOVER call. * - *

Note. Calling this method twice in a row on the same {@link - * MemoryContentsParameter}'s generally results in two different outputs. Indeed, this method - * starts by switching the {@link #variant}. + *

Note. Calling this method twice in a row on the same {@link MemoryContents}'s + * generally results in two different outputs. Indeed, this method starts by switching the {@link + * #variant}. * * @return */ public BytecodeCompiler memoryContents() { // we switch with every call - switchVariants(); + switchVariant(); switch (this) { case ZEROS -> { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java index 18f688395d..ba2d8f6ad0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java @@ -28,7 +28,7 @@ public class ParameterGeneration { - public static Stream happyPathParameterGeneration() { + public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = List.of(ZERO, COST_MO, COST, FULL); List ReturnAtParameters = @@ -38,7 +38,7 @@ public static Stream happyPathParameterGeneration() { for (OpCode opCode : CallOpCodes) { // 4 for (GasParameter gas : GasParameters) { // 4 - for (MemoryContentsParameter memoryContent : MemoryContentsParameter.values()) { // 9 + for (MemoryContents memoryContent : MemoryContents.values()) { // 9 for (CallDataSizeParameter cds : CallDataSizeParameter.values()) { // 10 for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java new file mode 100644 index 0000000000..ed4fd87292 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java @@ -0,0 +1,28 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecrecover; + +import java.util.stream.Stream; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.params.provider.Arguments; + +@Tag("weekly") +public class Tests extends PrecompileCallTests { + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java new file mode 100644 index 0000000000..b70af243b0 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java @@ -0,0 +1,33 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder1; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; + +import net.consensys.linea.testing.BytecodeCompiler; + +public interface PrecompileCallMemoryContents { + + void switchVariant(); + + BytecodeCompiler memoryContents(); + + default void setCodeOfHolderAccounts() { + memoryContentsHolder1.code(this.memoryContents().compile()); + this.switchVariant(); + memoryContentsHolder2.code(this.memoryContents().compile()); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java new file mode 100644 index 0000000000..2d659d4739 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java @@ -0,0 +1,68 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolderAddress1; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolderAddress2; +import static net.consensys.linea.zktracer.opcode.OpCode.CALL; + +import net.consensys.linea.testing.BytecodeCompiler; +import org.hyperledger.besu.datatypes.Address; + +public interface PrecompileCallParameters { + + boolean willRevert(); + + PrecompileCallMemoryContents memoryContents(); + + void appendCustomPrecompileCall(BytecodeCompiler program); + + /** + * {@link #customPrecompileCallsSeparatedByReturnDataWipingOperation} constructs the byte code for + * the happy path testing of the relevant PRECOMPILE. + */ + default BytecodeCompiler customPrecompileCallsSeparatedByReturnDataWipingOperation() { + + // populate foreign accounts' byte code with call data + this.memoryContents().setCodeOfHolderAccounts(); + + BytecodeCompiler program = BytecodeCompiler.newProgram(); + + // populate memory with the data for first PRECOMPILE call + copyForeignCodeToRam(program, memoryContentsHolderAddress1); + + // first PRECOMPILE call + this.appendCustomPrecompileCall(program); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x2a); + loadFirstReturnDataWordOntoStack(program, 0x02ff); + + // return data wiping + appendInsufficientBalanceCall( + program, CALL, 34_000, Address.fromHexString("b077c0ffee1337"), 13, 15, 17, 19); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); + loadFirstReturnDataWordOntoStack(program, 48); + + // populate memory with the data for second PRECOMPILE call + copyForeignCodeToRam(program, memoryContentsHolderAddress2); + + // second PRECOMPILE call + this.appendCustomPrecompileCall(program); + copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); + loadFirstReturnDataWordOntoStack(program, 0x00); + + return program; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java new file mode 100644 index 0000000000..a096a61fe2 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java @@ -0,0 +1,104 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.revertWith; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.runCreateDeployingForeignCodeAndCallIntoIt; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public abstract class PrecompileCallTests { + + /** + * MESSAGE_CALL_TRANSACTION case. + * + *

See {@link CodeExecutionMethods} for documentation and context. + */ + @ParameterizedTest + @MethodSource("parameterGeneration") + public void messageCallTransactionTest(T callParameter) { + + BytecodeCompiler rootCode = + callParameter.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + if (callParameter.willRevert()) revertWith(rootCode, 0, 5 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** + * CONTRACT_DEPLOYMENT_TRANSACTION case. + * + *

See {@link CodeExecutionMethods} for documentation and context. + */ + @ParameterizedTest + @MethodSource("parameterGeneration") + public void deploymentTransactionTest(T callParameter) { + + BytecodeCompiler txInitCode = + callParameter.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + if (callParameter.willRevert()) revertWith(txInitCode, 0, 0); + + runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); + } + + /** + * MESSAGE_CALL_FROM_ROOT case. + * + *

See {@link CodeExecutionMethods} for documentation and context. + */ + @ParameterizedTest + @MethodSource("parameterGeneration") + public void messageCallFromRootTest(T callParameter) { + BytecodeCompiler chadPrcEnjoyerCode = + callParameter.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, callParameter.willRevert()); + } + + /** + * DURING_DEPLOYMENT case. + * + *

See {@link CodeExecutionMethods} for documentation and context. + * + *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose + * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the + * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code + * of a CREATE. The whole operation optionally REVERT's. + */ + @ParameterizedTest + @MethodSource("parameterGeneration") + public void happyPathDuringCreate(T callParameter) { + BytecodeCompiler foreignCode = + callParameter.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runForeignByteCodeAsInitCode(foreignCode, callParameter.willRevert()); + } + + /** + * AFTER_DEPLOYMENT case. + * + *

See {@link CodeExecutionMethods} for documentation and context. + */ + @ParameterizedTest + @MethodSource("parameterGeneration") + public void happyPathAfterCreate(T callParameter) { + BytecodeCompiler chadPrcEnjoyerCode = + callParameter.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runCreateDeployingForeignCodeAndCallIntoIt(chadPrcEnjoyerCode, callParameter.willRevert()); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java new file mode 100644 index 0000000000..8435ace06c --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java @@ -0,0 +1,169 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.OVERLAP; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.opcode.OpCode; + +public class CallParameters implements PrecompileCallParameters { + public final OpCode call; + public GasParameter gas; + public final HashPrecompile prc; + public ValueParameter value; + public final CallOffset cdo; + public final CallSize cds; + public final CallOffset rao; + public final CallSize rac; + public final MemoryContents memoryContents; + public final RelativeRangePosition relPos; + public final boolean willRevert; + + public CallParameters( + OpCode call, + GasParameter gas, + HashPrecompile prc, + ValueParameter value, + CallOffset cdo, + CallSize cds, + CallOffset rao, + CallSize rac, + MemoryContents memoryContents, + RelativeRangePosition relPos, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.prc = prc; + this.value = value; + this.cdo = cdo; + this.cds = cds; + this.rao = rao; + this.rac = rac; + this.memoryContents = memoryContents; + this.relPos = relPos; + this.willRevert = willRevert; + } + + public CallParameters next() { + return new CallParameters( + call, gas, prc.next(), value, cdo, cds, rao, rac, memoryContents, relPos, willRevert); + } + + @Override + public boolean willRevert() { + return willRevert; + } + + @Override + public PrecompileCallMemoryContents memoryContents() { + return memoryContents; + } + + @Override + public void appendCustomPrecompileCall(BytecodeCompiler program) { + + // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM + switch (rac) { + case ZERO -> program.push(0); + case WORD -> program.push(WORD_SIZE); + case OTHER -> program.push(58); + } + + switch (rao) { + case ALIGNED -> program.push((relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + prc.smallOffset1()); + case MISALIGNED -> program.push( + (relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + prc.smallOffset1()); + case INFINITY -> program.push("ff".repeat(32)); + } + + // call data can occupy up to 52 bytes; it lives among words 0 and 1 of RAM + int callDataSize = + switch (cds) { + case ZERO -> 0; + case WORD -> WORD_SIZE; + case OTHER -> 43; + }; + program.push(callDataSize); + + switch (cdo) { + case ALIGNED -> program.push(prc.smallOffset2()); + case MISALIGNED -> program.push(13 + prc.smallOffset2()); + case INFINITY -> program.push("ff".repeat(32)); + } + + if (call.callHasValueArgument()) { + switch (value) { + case ZERO -> program.push(0); + case ONE -> program.push(1); + case VALUE -> program.push("69"); + } + } + + // push address + program.push(prc.getAddress()); + + // push gas parameter + int cost = prc.cost(callDataSize); + switch (gas) { + case ZERO -> program.push(0); + case COST_MO -> program.push(cost - 1); + case COST -> program.push(cost); + case FULL -> program.op(GAS); + case MAX -> program.push("ff".repeat(32)); + } + + program.op(call); + } + + public final boolean willMxpx() { + final boolean callDataMxpx = (cds != CallSize.ZERO) && (cdo == CallOffset.INFINITY); + final boolean returnAtMxpx = (rac != CallSize.ZERO) && (rao == CallOffset.INFINITY); + return callDataMxpx || returnAtMxpx; + } + + @Override + public String toString() { + return "CallParameters{" + + "call=" + + call + + ", gas=" + + gas + + ", prc=" + + prc + + ", value=" + + value + + ", cdo=" + + cdo + + ", cds=" + + cds + + ", rao=" + + rao + + ", rac=" + + rac + + ", memoryContents=" + + memoryContents + + ", relPos=" + + relPos + + ", willRevert=" + + willRevert + + '}'; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java deleted file mode 100644 index bb31cb6818..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HappyPathTests.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - -import java.util.stream.Stream; - -import net.consensys.linea.testing.*; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -/** - * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY. The present - * tests pertain to precompile calls where - * - *

- the precompile is provided with sufficient gas (ensuring scenario/PRC_SUCCESS) - * - *

- nothing REVERTs (thus value only matters in terms of pricing) - * - *

To avoid trivialities we pre-populate memory with nonzero values. We force interactions - * between the call data range, the return at range and return data ranges in - * the OVERLAP case. - * - *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and MLOAD. - * - *

The tests do more: we then wipe the return data and start all over again with the next - * precompile. - * - *

To give full details, we will test the following scenario which we call happy path - * precompile: - * - *

- happy path precompile CALL - * - *

- play with (precompile) return data - * - *

- wipe return data - * - *

- (different) happy path precompile CALL - * - *

- play with (precompile) return data - */ -@Tag("weekly") -public class HappyPathTests { - - public static Stream happyPathParameterGeneration() { - return ParameterGeneration.happyPathParameterGeneration(); - } - - /** - * MESSAGE_CALL_TRANSACTION case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(HashPrecompileCallParameters params) { - if (!params.willRevert) { - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - } - - /** - * CONTRACT_DEPLOYMENT_TRANSACTION case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(HashPrecompileCallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 0); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** - * MESSAGE_CALL_FROM_ROOT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(HashPrecompileCallParameters params) { - BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); - } - - /** - * DURING_DEPLOYMENT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - * - *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose - * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the - * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code - * of a CREATE. The whole operation optionally REVERT's. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(HashPrecompileCallParameters params) { - if (!params.willMxpx()) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); - } - } - - /** - * AFTER_DEPLOYMENT case. - * - *

See {@link CodeExecutionMethods} for documentation and context. - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(HashPrecompileCallParameters params) { - if (!params.willMxpx()) { - BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(chadPrcEnjoyerCode, params.willRevert); - } - } - - public void appendHappyPathPrecompileCall( - BytecodeCompiler program, HashPrecompileCallParameters params) { - - // if DISJOINT the "return at range"; it lives among words 2 and 3 of RAM - switch (params.rac) { - case ZERO -> program.push(0); - case WORD -> program.push(WORD_SIZE); - case OTHER -> program.push(58); - } - - switch (params.rao) { - case ALIGNED -> program.push( - (params.relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + params.prc.smallOffset1()); - case MISALIGNED -> program.push( - (params.relPos == OVERLAP ? 0 : 2 * WORD_SIZE) + 4 + params.prc.smallOffset1()); - case INFINITY -> program.push("ff".repeat(32)); - } - - // call data can occupy up to 52 bytes; it lives among words 0 and 1 of RAM - int callDataSize = - switch (params.cds) { - case ZERO -> 0; - case WORD -> WORD_SIZE; - case OTHER -> 43; - }; - program.push(callDataSize); - - switch (params.cdo) { - case ALIGNED -> program.push(params.prc.smallOffset2()); - case MISALIGNED -> program.push(13 + params.prc.smallOffset2()); - case INFINITY -> program.push("ff".repeat(32)); - } - - if (params.call.callHasValueArgument()) { - switch (params.value) { - case ZERO -> program.push(0); - case ONE -> program.push(1); - case VALUE -> program.push("69"); - } - } - - // push address - program.push(params.prc.getAddress()); - - // push gas parameter - int cost = params.prc.cost(callDataSize); - switch (params.gas) { - case ZERO -> program.push(0); - case COST_MO -> program.push(cost - 1); - case COST -> program.push(cost); - case FULL -> program.op(GAS); - case MAX -> program.push("ff".repeat(32)); - } - - program.op(params.call); - } - - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram( - HashPrecompileCallParameters params) { - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - populateMemory(program); - - // Note: we provide zero value, otherwise the precompile would receive a G_stipend = 2300 gas - // bonus, offsetting our gas cost computation - // happy path 1 - appendHappyPathPrecompileCall(program, params); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt( - program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - - // return data wiping - appendInsufficientBalanceCall(program, CALL, 20_000, params.prc.getAddress(), 1, 2, 3, 4); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt( - program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - - // happy path 2 - appendHappyPathPrecompileCall(program, params.next()); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt( - program, params.relPos == OVERLAP ? 4 : 4 * WORD_SIZE); - loadFirstReturnDataWordOntoStack(program, params.relPos == OVERLAP ? 15 : 5 * WORD_SIZE); - - return program; - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java deleted file mode 100644 index 91db98766e..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/HashPrecompileCallParameters.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; - -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.opcode.OpCode; - -public class HashPrecompileCallParameters { - public final OpCode call; - public GasParameter gas; - public final HashPrecompile prc; - public ValueParameter value; - public final CallOffset cdo; - public final CallSize cds; - public final CallOffset rao; - public final CallSize rac; - public final RelativeRangePosition relPos; - public final boolean willRevert; - - public HashPrecompileCallParameters( - OpCode call, - GasParameter gas, - HashPrecompile prc, - ValueParameter value, - CallOffset cdo, - CallSize cds, - CallOffset rao, - CallSize rac, - RelativeRangePosition relPos, - boolean willRevert) { - this.call = call; - this.gas = gas; - this.prc = prc; - this.value = value; - this.cdo = cdo; - this.cds = cds; - this.rao = rao; - this.rac = rac; - this.relPos = relPos; - this.willRevert = willRevert; - } - - public HashPrecompileCallParameters next() { - return new HashPrecompileCallParameters( - call, gas, prc.next(), value, cdo, cds, rao, rac, relPos, willRevert); - } - - public final boolean willMxpx() { - final boolean callDataMxpx = (cds != CallSize.ZERO) && (cdo == CallOffset.INFINITY); - final boolean returnAtMxpx = (rac != CallSize.ZERO) && (rao == CallOffset.INFINITY); - return callDataMxpx || returnAtMxpx; - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java new file mode 100644 index 0000000000..c0b85800fe --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java @@ -0,0 +1,37 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.populateMemory; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; + +public class MemoryContents implements PrecompileCallMemoryContents { + + boolean variant = false; + + @Override + public void switchVariant() { + variant = !variant; + } + + @Override + public BytecodeCompiler memoryContents() { + BytecodeCompiler program = BytecodeCompiler.newProgram(); + populateMemory(program, variant ? 6 : 12, variant ? 0x11 : 0x0a); + return program; + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java index 645a1d2c4a..e36e00ed1e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/ParameterGeneration.java @@ -35,7 +35,7 @@ public class ParameterGeneration { * * @return Stream of test parameters */ - public static Stream happyPathParameterGeneration() { + public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); @@ -51,7 +51,7 @@ public static Stream happyPathParameterGeneration() { // adding PrecompileCallParameters argumentsList.add( Arguments.of( - new HashPrecompileCallParameters( + new CallParameters( callOpcode, gas, precompile, @@ -60,11 +60,13 @@ public static Stream happyPathParameterGeneration() { cds, rao, rac, + new MemoryContents(), relPos, true))); + argumentsList.add( Arguments.of( - new HashPrecompileCallParameters( + new CallParameters( callOpcode, gas, precompile, @@ -73,6 +75,7 @@ public static Stream happyPathParameterGeneration() { cds, rao, rac, + new MemoryContents(), relPos, false))); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java new file mode 100644 index 0000000000..4b66572c4d --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java @@ -0,0 +1,92 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.hash; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.*; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.*; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; + +/** + * Happy path tests for SHA2-256, RIPEMD-160 and IDENTITY. The present + * tests pertain to precompile calls where + * + *

- the precompile is provided with sufficient gas (ensuring scenario/PRC_SUCCESS) + * + *

- nothing REVERTs (thus value only matters in terms of pricing) + * + *

To avoid trivialities we pre-populate memory with nonzero values. We force interactions + * between the call data range, the return at range and return data ranges in + * the OVERLAP case. + * + *

After the call we interact with return data via RETURNDATA[SIZE/COPY] and MLOAD. + * + *

The tests do more: we then wipe the return data and start all over again with the next + * precompile. + * + *

To give full details, we will test the following scenario which we call happy path + * precompile: + * + *

- happy path precompile CALL + * + *

- play with (precompile) return data + * + *

- wipe return data + * + *

- (different) happy path precompile CALL + * + *

- play with (precompile) return data + */ +@Tag("weekly") +public class Tests extends PrecompileCallTests { + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = + new CallParameters( + CALL, + COST, + HashPrecompile.IDENTITY, + ValueParameter.ZERO, + CallOffset.ALIGNED, + CallSize.WORD, + CallOffset.MISALIGNED, + CallSize.WORD, + new MemoryContents(), + OVERLAP, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); + + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java index 2f8f1b788d..a2bc39706c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ByteSizeParameter.java @@ -14,6 +14,15 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; +/** + * Used to describe one of the three byte size parameters of a MODEXP call: + * + *

- bbs: base byte size + * + *

- ebs: exponent byte size + * + *

- mbs: modulus byte size + */ public enum ByteSizeParameter { ZERO, ONE, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java index 06b1d312e9..3629fa3261 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java @@ -14,16 +14,19 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; +import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; -public class CallParameters { +public class CallParameters implements PrecompileCallParameters { public final OpCode call; public final GasParameter gas; - public final CallDataParameter callData; + public final MemoryContents callData; public final ReturnAtParameter returnAt; public final RelativeRangePosition relPos; public final boolean willRevert; @@ -31,15 +34,28 @@ public class CallParameters { public CallParameters( OpCode call, GasParameter gas, - CallDataParameter callData, + MemoryContents memoryContents, ReturnAtParameter returnAt, RelativeRangePosition relPos, boolean willRevert) { this.call = call; this.gas = gas; - this.callData = callData; + this.callData = memoryContents; this.returnAt = returnAt; this.relPos = relPos; this.willRevert = willRevert; } + + @Override + public boolean willRevert() { + return willRevert; + } + + @Override + public PrecompileCallMemoryContents memoryContents() { + return callData; + } + + @Override + public void appendCustomPrecompileCall(BytecodeCompiler program) {} } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java deleted file mode 100644 index a46a963aa9..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/HappyPathTests.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; - -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; -import static net.consensys.linea.zktracer.opcode.OpCode.*; - -import java.util.stream.Stream; - -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.module.constants.GlobalConstants; -import org.apache.tuweni.bytes.Bytes; -import org.hyperledger.besu.datatypes.Address; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -@Tag("weekly") -public class HappyPathTests { - - private final boolean variant1 = true; - private final boolean variant2 = false; - - /** MESSAGE_CALL_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallTransactionTest(CallParameters params) { - - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(rootCode, 0, 0); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** CONTRACT_DEPLOYMENT_TRANSACTION case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void deploymentTransactionTest(CallParameters params) { - - BytecodeCompiler txInitCode = happyPathWipeReturnDataHappyPathProgram(params); - if (params.willRevert) revertWith(txInitCode, 0, 0); - - runDeploymentTransactionWithProvidedCodeAsInitCode(txInitCode); - } - - /** MESSAGE_CALL_FROM_ROOT case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void messageCallFromRootTest(CallParameters params) { - BytecodeCompiler chadPrcEnjoyerCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallToAccountEndowedWithProvidedCode(chadPrcEnjoyerCode, params.willRevert); - } - - /** - * DURING_DEPLOYMENT case, see {@link CodeExecutionMethods}. - * - *

The {@link CodeExecutionMethods#root} contract fully copies the code of the account whose - * address is in the {@link CodeExecutionMethods#transaction} call data. This account is the - * {@link CodeExecutionMethods#chadPrcEnjoyer}. That code is then used as the initialization code - * of a CREATE. The whole operation optionally REVERT's. - * - * @param params - */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathDuringCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runForeignByteCodeAsInitCode(foreignCode, params.willRevert); - } - - /** AFTER_DEPLOYMENT case, see {@link CodeExecutionMethods}. */ - @ParameterizedTest - @MethodSource("happyPathParameterGeneration") - public void happyPathAfterCreate(CallParameters params) { - BytecodeCompiler foreignCode = happyPathWipeReturnDataHappyPathProgram(params); - runCreateDeployingForeignCodeAndCallIntoIt(foreignCode, params.willRevert); - } - - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest() { - CallDataParameter callDataParameter = - new CallDataParameter( - MODERATE, // bbs - MODERATE, // ebs - MAX, // mbs - CallDataSizeParameter.MODULUS_FULL // cds - ); - CallParameters params = - new CallParameters( - CALL, - GasParameter.COST_MO, - callDataParameter, - ReturnAtParameter.FULL, - RelativeRangePosition.OVERLAP, - true); - setCodeOfHolderAccounts(params); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** Non-parametric test to make sure things are working as expected. */ - @Test - public void singleMessageCallTransactionTest2() { - CallDataParameter callDataParameter = - new CallDataParameter( - MAX, // bbs - SHORT, // ebs - MODERATE, // mbs - CallDataSizeParameter.MODULUS_FULL // cds - ); - CallParameters params = - new CallParameters( - STATICCALL, - GasParameter.COST, - callDataParameter, - ReturnAtParameter.FULL, - RelativeRangePosition.OVERLAP, - true); - setCodeOfHolderAccounts(params); - BytecodeCompiler rootCode = happyPathWipeReturnDataHappyPathProgram(params); - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } - - /** - * {@link #happyPathWipeReturnDataHappyPathProgram} constructs the byte code for the happy - * path testing of MODEXP. This code does the following: - * - *

- populate memory with the data for first MODEXP call - * - *

- perform first MODEXP call and play around with its return data - * - *

- wipe return data - * - *

- populate memory with the data for second MODEXP call - * - *

- perform second MODEXP call and play around with its return data - * - * @param params - * @return - */ - private BytecodeCompiler happyPathWipeReturnDataHappyPathProgram(CallParameters params) { - - setCodeOfHolderAccounts(params); - - BytecodeCompiler program = BytecodeCompiler.newProgram(); - - // populate memory with the data for first MODEXP call - copyForeignCodeToRam(program, memoryContentsHolderAddress1); - - // happy path: first MODEXP call - appendHappyPathPrecompileCall(program, params, variant1); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x0140); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - // return data wiping - appendInsufficientBalanceCall( - program, CALL, 34_000, Address.fromHexString("c0ffee69"), 13, 15, 17, 19); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 21); - loadFirstReturnDataWordOntoStack(program, 48); - - // populate memory with the data for second MODEXP call - copyForeignCodeToRam(program, memoryContentsHolderAddress2); - - // happy path: second MODEXP call - appendHappyPathPrecompileCall(program, params, variant2); - copyHalfOfReturnDataOmittingTheFirstThirdOfIt(program, 0x026c); - loadFirstReturnDataWordOntoStack(program, 0x02ff); - - return program; - } - - /** - * Populate the byte code of {@link CodeExecutionMethods#memoryContentsHolder1} and {@link - * CodeExecutionMethods#memoryContentsHolder2} with "byte code" that is well-formed data for a - * MODEXP call. - * - * @param params - */ - private void setCodeOfHolderAccounts(CallParameters params) { - - String code1 = params.callData.wellFormedCallDataForModexpCall(variant1); - String code2 = params.callData.wellFormedCallDataForModexpCall(variant2); - - memoryContentsHolder1.code(Bytes.fromHexString(code1)); - memoryContentsHolder2.code(Bytes.fromHexString(code2)); - } - - public static Stream happyPathParameterGeneration() { - return ParameterGeneration.happyPathParameterGeneration(); - } - - /** - * Constructs a CALL to the MODEXP precompile in terms of {@link CallParameters}. - * - * @param program - * @param params - * @param variant - */ - public void appendHappyPathPrecompileCall( - BytecodeCompiler program, CallParameters params, boolean variant) { - - int cds = params.callData.memorySize(variant); - - // pushing r@c onto the stack - int rac = - switch (params.returnAt) { - case EMPTY -> 0; - case PARTIAL -> cds / 2; - case FULL -> cds; - case LARGE -> cds + 256; - }; - program.push(rac); - - // pushing r@o onto the stack - int rao = - switch (params.relPos) { - case DISJOINT -> cds; - case OVERLAP -> 0; - }; - program.push(rao); - - // pushing cds onto the stack - program.push(cds); - - // pushing cdo onto the stack - program.push(0); - - // pushing value onto the stack - if (params.call.callHasValueArgument()) { - program.push(1); - } - - // pushing MODEXP address onto the stack - program.push(Address.MODEXP); - - int modexpGasCost = params.callData.gasCost(variant); - int gasParam = - (params.call.callHasValueArgument() - && modexpGasCost >= GlobalConstants.GAS_CONST_G_CALL_STIPEND) - ? modexpGasCost - GlobalConstants.GAS_CONST_G_CALL_STIPEND - : modexpGasCost; - - // pushing gas onto the stack - switch (params.gas) { - case ZERO -> program.push(0); - case COST_MO -> program.push(gasParam - 1); - case COST -> program.push(gasParam); - case FULL -> program.op(GAS); - case MAX -> program.push("ff".repeat(32)); - } - - program.op(params.call); - } -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java similarity index 85% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java index 2692458b6c..93c4b9e566 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallDataParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java @@ -19,38 +19,26 @@ import java.math.BigInteger; +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; -public class CallDataParameter { +public class MemoryContents implements PrecompileCallMemoryContents { - private static final String BASE_512_a = - "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; - private static final String EXPN_512_a = - "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; - private static final String MDLS_512_a = - "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; - - private static final String BASE_512_b = - "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; - private static final String EXPN_512_b = - "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; - private static final String MDLS_512_b = - "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; + @Override + public void switchVariant() { + variant = !variant; + } - /** base byte size. */ public final ByteSizeParameter bbs; - - /** exponent byte size. */ public final ByteSizeParameter ebs; - - /** modulus byte size. */ public final ByteSizeParameter mbs; - - /** call data size. */ public final CallDataSizeParameter cds; - public CallDataParameter( + public boolean variant = false; + + public MemoryContents( ByteSizeParameter bbs, ByteSizeParameter ebs, ByteSizeParameter mbs, @@ -61,18 +49,10 @@ public CallDataParameter( this.cds = cds; } - public int gasCost(boolean variant) { - return gasCost( - this.bbsShort(variant), this.ebsShort(variant), this.mbsShort(variant), expn(variant)); + public int gasCost() { + return gasCost(this.bbsShort(), this.ebsShort(), this.mbsShort(), expn()); } - /** - * @param bbs - * @param ebs - * @param mbs - * @param Exponent must be a hex string without the 0x prefix - * @return - */ private int gasCost(short bbs, short ebs, short mbs, String Exponent) { int maxBbsMbs = Math.max(bbs, mbs); @@ -94,8 +74,8 @@ private int f(int x) { return ceil * ceil; } - public int memorySize(boolean variant) { - return 3 * WORD_SIZE + this.bbsShort(variant) + this.ebsShort(variant) + this.mbsShort(variant); + public int memorySize() { + return 3 * WORD_SIZE + this.bbsShort() + this.ebsShort() + this.mbsShort(); } /** @@ -109,35 +89,35 @@ public int memorySize(boolean variant) { * * @return */ - public String wellFormedCallDataForModexpCall(boolean variant) { + public BytecodeCompiler memoryContents() { // starting at index 2 eliminates the 0x prefix - String memoryContents = - this.bbs(variant).substring(2) - + this.ebs(variant).substring(2) - + this.mbs(variant).substring(2); + String byteSizes = this.bbs().substring(2) + this.ebs().substring(2) + this.mbs().substring(2); // every byte is represented by two hexadecimal characters, whence the factor of 2 - return memoryContents - + base(variant).substring(0, 2 * this.bbsShort(variant)) - + expn(variant).substring(0, 2 * this.ebsShort(variant)) - + mdls(variant).substring(0, 2 * this.mbsShort(variant)); + String memoryContents = + byteSizes + + base().substring(0, 2 * this.bbsShort()) + + expn().substring(0, 2 * this.ebsShort()) + + mdls().substring(0, 2 * this.mbsShort()); + + return BytecodeCompiler.newProgram().immediate(Bytes.fromHexString(memoryContents)); } - private String base(boolean variant) { + private String base() { return variant ? BASE_512_a : BASE_512_b; } - private String expn(boolean variant) { + private String expn() { return variant ? EXPN_512_a : EXPN_512_b; } - private String mdls(boolean variant) { + private String mdls() { return variant ? MDLS_512_a : MDLS_512_b; } - private short bbsShort(boolean variant) { - return switch (this.bbs) { + private short bbsShort() { + return switch (bbs) { case ZERO -> 0; case ONE -> 1; case SHORT -> 0x1f; @@ -146,8 +126,8 @@ private short bbsShort(boolean variant) { }; } - private short ebsShort(boolean variant) { - return switch (this.ebs) { + private short ebsShort() { + return switch (ebs) { case ZERO -> 0x00; case ONE -> 0x01; case SHORT -> 0x12; @@ -156,8 +136,8 @@ private short ebsShort(boolean variant) { }; } - private short mbsShort(boolean variant) { - return switch (this.mbs) { + private short mbsShort() { + return switch (mbs) { case ZERO -> 0x00; case ONE -> 0x01; case SHORT -> 0x0d; @@ -166,15 +146,29 @@ private short mbsShort(boolean variant) { }; } - private String bbs(boolean variant) { - return Bytes32.leftPad(Bytes.ofUnsignedShort(bbsShort(variant))).toString(); + private String bbs() { + return Bytes32.leftPad(Bytes.ofUnsignedShort(bbsShort())).toString(); } - private String ebs(boolean variant) { - return Bytes32.leftPad(Bytes.ofUnsignedShort(ebsShort(variant))).toString(); + private String ebs() { + return Bytes32.leftPad(Bytes.ofUnsignedShort(ebsShort())).toString(); } - private String mbs(boolean variant) { - return Bytes32.leftPad(Bytes.ofUnsignedShort(mbsShort(variant))).toString(); + private String mbs() { + return Bytes32.leftPad(Bytes.ofUnsignedShort(mbsShort())).toString(); } + + private static final String BASE_512_a = + "15d1ba637430de62c88abfddb0e8d6abc6f5660d2a4293b4184981ef6b9f178701abdb3f9b392b300c1457d8b8b4ce57c2473f301ac199431fd06b5c914438a9eb2315e2f0f0686c2b57e5cca793667dd45935364e59ed920ec3a40d37799f68f49e097f763ca64a8038fe3061b09a6051867eb779e72eb9b9ecc468788ecb29266c1c02ebaafa98bd2c1d69166548ac84d6bfa06a4ca606540e90231bffb53e48ffe7981a43129f8e54bd74dffa2e4024566078bd0e8afe1f1caf44e66b233828b87057fb4d6d8d83e7c682fab9b5c9cfc82142e6f150a41ffdbfa7163bdb210d2274a20e055604d6704228fcc6a05da1bf9487d26c9d791fdd2d48a934328995acbf32eba94c0edbcd8cf8688c45685e1c9f3188d143c9c2ed456c8e68f480fb851f587d3eee03635e4e3cf34e521192513157da5968d776528391f246e650a7f0e8683df8560e6cdbc9e15c562f57ae1b12e17eaaae1181462e702d5ffa9a9fb2d0dc5e02a2ca8d2dcc76dbb5a768fcac1f32a36447b11206e6024a7f72ab81b98738395376cda72fcbad77be565a757703f6dbf0c6a68d9af9f8f0d6f6002e53e995908361792e16b5624a25ecd5c799763b33acd4e5ebec1f8028c1cc903800e781f35b339df589d0f324933e23af337eedaed4273c0a842b41f71691670c02a3f0fd2355690574c5a38237e426da6bb6bd0f0797e502b498e8870d6032"; + private static final String EXPN_512_a = + "bce258eac6ba5f6ebde23fa3a88c322230f7a104249495389dc9587519f028353ba6ec5cecc8d07d7184749f24894ffb8c41ac83a8ad1409fffe530c72c16d1a91fb7597a2d9796581e77f9199e2595328f543fffdc20db91889ecd20ea260ba6af38466f418630b74f57a032720922508590047aa7292fafd0587d94065df031e3e7ef123c347cb16c822646f4d564b724cb98643b91d1cf56d55672263345f6caea42ca3c25a69a54de58d9a45fef0cb80d650c1e549e6e7ff867023117300f553e2ad3484763e281c6229240d44ceae10177712e02a57f32f2cd9a7f8d0ef5fdeb79ea629af3614c8ce0fcdedb4c3d6ab6c1afeac40105c34eb4057b22342df320e21a619835e792d8e2701b759157d4ef0b7872fad66372481c124118ff54db223a476ffb69842f90d5b66ad1dfb4fc86e6c8ffdd6a324051c0ec69c1d99d38d5ff8a12f1e1b724833bdcd9171c30f191b99992233f9a35476d78efecf4e99ddf05c83dd6bdf43c8bd5244657c3493d6035c713fa93976960dc62526506c91593c8edc7f8d10bdc041da70e4cc5eff830cb65b1d2cffef2a147696bcccae23c2a2c07dff40e671b0d16fcda339ca0a00b71124a52978370025fe5d67949b1f9ca20230e3b83b74345c77f835626cbce252eb48a6eb89f16f8cd2f3b36ef84d41f3d1b97e9a4e3a0edee1d41f9b8ca11abbd1b436a713c4c8ef17f38764ad"; + private static final String MDLS_512_a = + "e92a1304e5e9dfdcb0cb08acddcc25691f84581794b48daace8202718341e071cc98b84d4e0a7102958b5a4b85e9487cf6bd8c03e1cc70eadf5dee58e2caf2d738c6bcce89e59024f16a481bc32252cbbf17183c899b52182b01645500a9a56c06b2807c259100072500eacb12c9aecda64ce58d6b4ef7d335aaeffd1c794440d3fe7d8eba6d5b9cfbd7b4178dabf2045fd1cde509b7c8d9bcb77e3dbfb9ecd8fdaa2db10f24a765485cf455ae221637ef859577e6d5cf18e5fe11c736037b44dda3da3c37bd116d0c775c41f74993dcd503cc23d0b178c22d5e38e776f4c72b4391ddd15b3dc95dd3525cdd58227d86f5e2ca5b661fa18fd9556df478d2ac5719bbd8657e0555799f531f85a07ba174e8232d123a132e65bfa1e622bfa77034b45ebb57359a38721da39365bfec4a889f0b0d13e2971019cf6f14ae2d959212502cfef1e69d8238b4972c898895f2783db45e5410f15a648a02de3ce40e264d24ee409aa2296e0cf43a749cb39d6342d68b1e85aca442a4f4af67295ee06a90d74f10ef19a2698def6deecf19784c8e511165aeec3009c6effd8e9aee1cf7b9bb23e4266ba62eab3ac2f3796cecbdf800dae6f74c0c9abcf227b4bdb1e5a10f6dba2284934fe7593f8058d5a74113baba19b6a59cd371dc0669ac48af4093f02d10d947239fceaf124860b4d123878b77564ea491b543c89417c9c3f2d39527"; + + private static final String BASE_512_b = + "4c594c0a14b26df4357980b0e3daf7b4c7e5c85c703f529a0a5d7a3bda9854d738b54bad23c6e9c4674b503d17ad60dda0fc68789aebfadf64e1c0b4f5e0917edbace443548bfb65755828da15e17b0c672c05d0de0f0d516ef2b1b23842fdcd96a181eff693851ef41cfbdab3eb1664cee9d0ad7fc78a70aa112f71f4a3311eda30a1c1adc62251154382b555df4b22aabef45d8dfb417262bb5da9a45ba5d6bcb1542f24cddb58b1fc56102a57f296fe125bf5ead5b115b2e7317f7950e869fa19e7becd516015428f0e67da4aaca0ccd7cfe6e00072f9b63830ffac60e13cf8e4b31db0f2464f35c9f1650f1edcc3ac424a9e7f3509e270a606428209d7522f3a7e35ebef7cb267c87cf8805c48eba6cca87ec44e81112ad25ef72d487be71cb6a021eb7ded009d3f7536a6f47d9362fdf22f0b01c9071f0ae05b3afc04574dce57f9219d821296f5067c5814bd95a22cf1b4d4aec3bceaea8ccb6abb318228306e9c6433795241796a844403dea79be8e5df88fb54134f73ffddfbae3b6e995fb582c5638a17cd7c7a957dc0ad36ec5e04815ec293f544bb13ad73270eafb5220c02173d8ff78ea774887ef2a119f7625d4866d131a05a9c4df2537a56bd623ea338f5b2aeb026c395318d7957a29558a4844a0a7ca31ad77ab0dc77a5d31d54df598a2ac0fad9db855ab299c0546ca2545729ae41584b82b55d6b061f9c"; + private static final String EXPN_512_b = + "0003e59f9eb9de451161f0f2a5bfebcce1422179e69258468b74a98fcca79f2a156eae7aaa5418b2bc45b33d643cee08b1228ebf08ea29995019689ffad602473c52276d91d04abe3bdeb0f48324da2ddd43e6dcdde860c6ca9dd9d8232b0b4db931b2391a86b20400aaa96e085b6b90b8a562a7fa6a052a389660e99169ca065e12b939b0647e0ae6c762d61e0739ee06f862abbd5fe72f46092fb15505114194fc82435cacb1500a1b6a677200101809e5e701e7bd2385853183e3d5b2167a5f006d801940c620ec7d8763084272a76a23b8c401adee3efa424fa1702f1b936fa0d6017328339f54e1aa64919aaaff6333fe148c60ad57de2f62c2d05b2b73aef9f18088cb3141d7be05739723303b1761aaa9459507f1cf5118fc306e0854bf42f9ded226417f7ccae38e4222239236d4f33edff6e53012f4e0b0a8316b966aa75908dcb40a703c2688cffb33a940851556dfc08b151461726c88293b9f77199c5c9e4dec70fbf3ef0d84e2328ab48e15fb20cc0aa8dba18b2ddf901de27c4af3d74bcbd1ff606fe0434218c6e3966657bd0f375f8aad5ed178887e3d37159d109cf30ee961a20090d17e33075c9da626402a04901c7364abc222dcd883f65a72e649972a23f8b55c79515e8f5b8c0149fc816c91214fda785bce80042c0170c5c0a1467a569a61f380eb47e0b299d2848bb2b7ae22cfe472a4e5a3614fc6"; + private static final String MDLS_512_b = + "52c17a8a52b76004c769c98ae510914b17c516f5d9b1fecf0a3b4b89c0f4c415ef31699855362601b4991b2b3ced962c7c23e8ea958ffc28e59711d270cebf7709de66cb29f8e6dcf7161745529444073dbce14d5a99dea405da9472d66d26abacba626e1c797c155a8119058afbdfd2923cb91cd18c37ebfc736d0c0457041c24822031bea6b09e3b8e9b7f1f724121be221d399ef7f2070b16b3b37b953bc19ab46cafb13a742b185e1a126f22d89373a8b09c57de4d7c5a556e6bc9de527134b7b1b7fd6ad883889f96f3253b2b90de4cf82dc35d1b839fd0ca308cd7e4d950d2890a6af5c7f7fbff9a11892cdd90f058e2e719ec91d990c9f53e19607f7a7a105be37083be8e6ec78fed09170399a58963dc5f2d0457f1b311036eba270b44e88bbf5f3b0704d79e37e4ed9a901416a8495f502c39bdfe5aded946ae55f59b6285fc05b8e0ea50710e50cbf896001cb1fdc0c8bbbc3629f8a901dc3d3c3d5aff0112b2adae83119692f12b4c1f36e1b0628d1522804c15360ea9413a702079412a29f60c578052f7cf02a86b28a9d8e95785fa6d7d2fb2964e8d25489ff0077fa5776ac32bef08bf84a7f172ab21ac8817b79bf83a565209820193cd307451dc6f5a01f29e795e27b4d82a87d8a6eeeab3fa06c914b0e05c240acf9ac51a7f863ec8fb246d78b576ffa4426ff31dbe08dd8d81ce2fe69c191c8a13486e51"; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java index 25eed4d314..7b0ef65f96 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/ParameterGeneration.java @@ -51,7 +51,7 @@ public class ParameterGeneration { * * @return Stream of test parameters */ - public static Stream happyPathParameterGeneration() { + public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List argumentsList = new ArrayList<>(); @@ -70,7 +70,7 @@ public static Stream happyPathParameterGeneration() { new CallParameters( opCode, gas, - new CallDataParameter(bbs, ebs, mbs, cds), + new MemoryContents(bbs, ebs, mbs, cds), returnAt, relPos, true))); @@ -80,7 +80,7 @@ public static Stream happyPathParameterGeneration() { new CallParameters( opCode, gas, - new CallDataParameter(bbs, ebs, mbs, cds), + new MemoryContents(bbs, ebs, mbs, cds), returnAt, relPos, false))); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java new file mode 100644 index 0000000000..3ebe08f910 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java @@ -0,0 +1,83 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.modexp.ByteSizeParameter.*; +import static net.consensys.linea.zktracer.opcode.OpCode.*; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul.ParameterGeneration; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; + +@Tag("weekly") +public class Tests extends PrecompileCallTests { + + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest() { + MemoryContents memoryContents = + new MemoryContents( + MODERATE, // bbs + MODERATE, // ebs + MAX, // mbs + CallDataSizeParameter.MODULUS_FULL // cds + ); + CallParameters params = + new CallParameters( + CALL, + GasParameter.COST_MO, + memoryContents, + ReturnAtParameter.FULL, + RelativeRangePosition.OVERLAP, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } + + /** Non-parametric test to make sure things are working as expected. */ + @Test + public void singleMessageCallTransactionTest2() { + MemoryContents memoryContents = + new MemoryContents( + MAX, // bbs + SHORT, // ebs + MODERATE, // mbs + CallDataSizeParameter.MODULUS_FULL // cds + ); + CallParameters params = + new CallParameters( + STATICCALL, + GasParameter.COST, + memoryContents, + ReturnAtParameter.FULL, + RelativeRangePosition.OVERLAP, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } +} From 0f3ec3b4b3a0b8b3d9ea101eff069d798da50c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 01:43:23 +0100 Subject: [PATCH 43/57] ras --- .../callTests/prc/GasParameter.java | 2 +- .../callTests/prc/ecadd/CallParameters.java | 9 ++++----- .../callTests/prc/ecadd/MemoryContents.java | 2 +- .../callTests/prc/ecadd/Tests.java | 2 +- .../callTests/prc/ecmul/CallParameters.java | 4 ++-- .../callTests/prc/ecmul/MemoryContents.java | 2 +- .../callTests/prc/ecmul/Tests.java | 2 +- .../prc/ecpairing/CallDataParameter.java | 17 +++++++++++++++++ .../prc/ecpairing/LargePointCandidate.java | 17 +++++++++++++++++ .../callTests/prc/ecpairing/MemoryContents.java | 17 +++++++++++++++++ .../prc/ecpairing/SmallPointCandidate.java | 17 +++++++++++++++++ .../callTests/prc/ecrecover/CallParameters.java | 4 ++-- .../callTests/prc/ecrecover/MemoryContents.java | 2 +- .../callTests/prc/ecrecover/Tests.java | 2 +- .../PrecompileCallMemoryContents.java | 2 +- .../PrecompileCallParameters.java | 2 +- .../PrecompileCallTests.java | 2 +- .../callTests/prc/hash/CallParameters.java | 4 ++-- .../callTests/prc/hash/MemoryContents.java | 2 +- .../callTests/prc/hash/Tests.java | 2 +- .../callTests/prc/modexp/CallParameters.java | 4 ++-- .../callTests/prc/modexp/MemoryContents.java | 2 +- .../callTests/prc/modexp/Tests.java | 2 +- 23 files changed, 94 insertions(+), 27 deletions(-) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{frameWork => framework}/PrecompileCallMemoryContents.java (98%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{frameWork => framework}/PrecompileCallParameters.java (99%) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/{frameWork => framework}/PrecompileCallTests.java (99%) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java index c8765f2006..9b58e620aa 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/GasParameter.java @@ -19,6 +19,6 @@ public enum GasParameter { ZERO, COST_MO, // MO ≡ minus one COST, - FULL, + PLENTY, MAX } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java index 241892f29f..66bb42a036 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/CallParameters.java @@ -15,14 +15,13 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.GAS; -import static net.consensys.linea.zktracer.opcode.OpCode.MSIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; import org.hyperledger.besu.datatypes.Address; @@ -105,7 +104,7 @@ public void appendCustomPrecompileCall(BytecodeCompiler program) { case ZERO -> program.push(0); // interesting in the nonzero value case case COST_MO -> program.push(149); case COST -> program.push(150); - case FULL -> program.op(GAS); + case PLENTY -> program.push(2).op(GAS).op(DIV); // provide half of available gas default -> throw new RuntimeException("Unsupported gas parameter"); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java index 785cf98ba5..2245f99d6b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/MemoryContents.java @@ -19,7 +19,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE_MO; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; public enum MemoryContents implements PrecompileCallMemoryContents { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java index d5362a6759..1547dbd196 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/Tests.java @@ -23,7 +23,7 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java index 81f106daec..2e175269d2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java @@ -21,8 +21,8 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; import org.hyperledger.besu.datatypes.Address; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java index c4a57af6a9..7930a9b1fc 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/MemoryContents.java @@ -19,7 +19,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; /** diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java index cdc007ffaa..3bec0a75ac 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/Tests.java @@ -25,7 +25,7 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java new file mode 100644 index 0000000000..6e935ef370 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +public class CallDataParameter { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java new file mode 100644 index 0000000000..eaeac33fbe --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.module.ecdata.ecpairing; +public class LargePointCandidate { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java new file mode 100644 index 0000000000..01c4e72113 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +public class MemoryContents { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java new file mode 100644 index 0000000000..144ddf445b --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.module.ecdata.ecpairing; +public class SmallPointCandidate { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java index 3d6566fe1d..bc580d94ed 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java @@ -20,8 +20,8 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; import org.hyperledger.besu.datatypes.Address; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java index e2ae118039..adb1d4f3a2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/MemoryContents.java @@ -19,7 +19,7 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; /** * Memory for ECRECOVER testing will be made to contain inputs of the form diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java index ed4fd87292..8004c66f10 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/Tests.java @@ -16,7 +16,7 @@ import java.util.stream.Stream; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; import org.junit.jupiter.api.Tag; import org.junit.jupiter.params.provider.Arguments; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallMemoryContents.java similarity index 98% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallMemoryContents.java index b70af243b0..6a233b5331 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallMemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallMemoryContents.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder1; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolder2; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallParameters.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallParameters.java index 2d659d4739..b0a6e428db 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallParameters.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.*; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.memoryContentsHolderAddress1; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallTests.java similarity index 99% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallTests.java index a096a61fe2..dee0293c18 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/frameWork/PrecompileCallTests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/framework/PrecompileCallTests.java @@ -12,7 +12,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork; +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework; import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.revertWith; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.*; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java index 8435ace06c..1de56bd481 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java @@ -20,8 +20,8 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; public class CallParameters implements PrecompileCallParameters { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java index c0b85800fe..22df7ad899 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/MemoryContents.java @@ -17,7 +17,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.populateMemory; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; public class MemoryContents implements PrecompileCallMemoryContents { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java index 4b66572c4d..cda425521d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/Tests.java @@ -25,7 +25,7 @@ import net.consensys.linea.testing.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java index 3629fa3261..146d5e7b38 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/CallParameters.java @@ -18,8 +18,8 @@ import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallParameters; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; import net.consensys.linea.zktracer.opcode.OpCode; public class CallParameters implements PrecompileCallParameters { diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java index 93c4b9e566..29f61e2a35 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/MemoryContents.java @@ -20,7 +20,7 @@ import java.math.BigInteger; import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java index 3ebe08f910..884fdeb564 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/modexp/Tests.java @@ -23,7 +23,7 @@ import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul.ParameterGeneration; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.frameWork.PrecompileCallTests; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; From 52d7d17df282ec91713d4fb6f0126d6bf21cb511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 01:43:38 +0100 Subject: [PATCH 44/57] feat: ECPAIRING wip --- .../prc/ecpairing/CallDataParameter.java | 6 +- .../prc/ecpairing/LargePointCandidate.java | 28 +++- .../prc/ecpairing/MemoryContents.java | 152 +++++++++++++++++- .../prc/ecpairing/SmallPointCandidate.java | 25 ++- 4 files changed, 205 insertions(+), 6 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java index 6e935ef370..a3a4b3aa53 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java @@ -13,5 +13,9 @@ * SPDX-License-Identifier: Apache-2.0 */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; -public class CallDataParameter { + +public enum CallDataParameter { + EMPTY, + SINGLE_PAIR_OF_POINTS, + RANGE_OF_PAIRS_OF_POINTS; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java index eaeac33fbe..41fb740325 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java @@ -12,6 +12,30 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.module.ecdata.ecpairing; -public class LargePointCandidate { +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; + +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +public enum LargePointCandidate { + // valid points + INFINITY, + VALID_LARGE_POINT, + // invalid points + RAND, + RE_X_NOT_IN_FIELD, + IM_X_NOT_IN_FIELD, + RE_Y_NOT_IN_FIELD, + IM_Y_NOT_IN_FIELD, + NOT_ON_CURVE, + NOT_IN_SUBGROUP; + + public boolean isValid() { + return this == INFINITY || this == VALID_LARGE_POINT; + } + + public boolean isInfinity() { + return this == INFINITY; + } + + public static String POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index 01c4e72113..5563c3cdb5 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -13,5 +13,155 @@ * SPDX-License-Identifier: Apache-2.0 */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; -public class MemoryContents { + +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import org.apache.tuweni.bytes.Bytes; + +/** + * Memory contents for the ECPAIRING precompile take on the following form: + * + *

[ λ∞ | ∞∞ | -P | ∞ρ | P | λ∞ | Q | R | ∞ρ | CENTER_PAIR | ∞ρ | S | ff .. ff ] + * + *

where CENTER_PAIR = τθ and: + * + *

    + *
  • represents the point at infinity one either curve + *
  • λ is a nontrivial and valid C1 point + *
  • ρ is a nontrivial and valid G2 point + *
  • P, Q, R, S are nontrivial pairs of points such that + *
      + *
    • "-P" (non standard notation) negates the C1 point in P + *
    • for {@link #variant} ≡ true e(P)∙e(Q)∙e(R) ≡ 1 + *
    • for {@link #variant} ≡ false e(P)∙e(Q)∙e(R)∙e(S) ≡ 1 + *
    + *
  • τ is a {@link SmallPointCandidate} which will vary + *
  • θ is a {@link LargePointCandidate} which will vary + *
+ * + * Note. The CENTER_PAIR is the only component in this setup which may cause failure + * in the precompile call. + * + *

Note. The trailing ff .. ff is where we will place the returnAt memory + * range. + */ +public class MemoryContents implements PrecompileCallMemoryContents { + public final SmallPointCandidate small; + public final LargePointCandidate large; + ; + + public boolean centerPairIsValid() { + return small.isValid() && large.isValid(); + } + + public boolean centerPairIsInconsequential() { + return centerPairIsValid() && (small.isInfinity() || large.isInfinity()); + } + + public MemoryContents(SmallPointCandidate small, LargePointCandidate large) { + this.small = small; + this.large = large; + } + + public final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; + private final String RETURN_DATA_STRIP = "ff".repeat(WORD_SIZE); + boolean variant = false; + + @Override + public void switchVariant() { + variant = !variant; + } + + @Override + public BytecodeCompiler memoryContents() { + String memoryContentsString = leftPairs() + CenterPair() + rightPairs() + RETURN_DATA_STRIP; + Bytes memoryContentsBytes = Bytes.fromHexString(memoryContentsString); + checkState( + memoryContentsBytes.size() == NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY * 192 + WORD_SIZE * 2); + + BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); + return memoryContents.immediate(memoryContentsBytes); + } + + private String leftPairs() { + throw new RuntimeException("memoryContents not implemented"); + } + + private String CenterPair() { + return small.toString() + large.toString(); + } + + private String rightPairs() { + throw new RuntimeException("memoryContents not implemented"); + } + + // All values below are obtained from Ivo's comment + // https://github.com/Consensys/linea-tracer/issues/822#issuecomment-2260511164 + + private static final String NEGATIVE_P = + "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" + + "127a664dd11342beb666506dac296731e404de80a25e05f40b2405c4c00c28fc" + + "2bd236cb7a7b0e0543e6b6e0d7308576aeeec4dea2f740654854215d7813826f" + + "1b28f411c2931b52b2ad62de524be4eaac555dfed67d59e2d0f6c4607b23526b" + + "181c4319cc974dd174c5918ac1892326badb2603a04bc8f565221c06eec8a126"; + + private static final String TRIPLE_P = + "01395d002b3ca9180fb924650ef0656ead838fd027d487fed681de0d674c30da" + + "097c3a9a072f9c85edf7a36812f8ee05e2cc73140749dcd7d29ceb34a8412188" + + "2bd3295ff81c577fe772543783411c36f463676d9692ca4250588fbad0b44dc7" + + "07d8d8329e62324af8091e3a4ffe5a57cb8664d1f5f6838c55261177118e9313" + + "230f1851ba0d3d7d36c8603c7118c86bd2b6a7a1610c4af9e907cb702beff1d8" + + "12843e703009c1c1a2f1088dcf4d91e9ed43189aa6327cae9a68be22a1aee5cb"; + + private static final String TRIPLE_Q = + "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" + + "12618811f3e9fa06644d43cfe3f69c6c17a738128de60f8f3ebb4266bab29be6" + + "00a5a6c2ec01c4d1374078ae1bbea91dea8e938c1275226a1ce51db5e7de53d1" + + "2da43ecc11a0095a72454bb08fb4d1116facadcab482a1107ae67a12bb3c19f2" + + "1e2f128bf79945a370324b82c36c1e63509b122c023bd8163495526bb030a216"; + + private static final String TRIPLE_R = + "1296d042f33ccbb814746e187aa20af49bd503356de4846abee08da9e32ae2ac" + + "0b980019d2af83b353aa8c2efda45f16ce523b99452118be7ae5dd1e92e0e4ec" + + "012cd1b1242354b35cd8d2493c487b52411d111c80e8cfb97080e2db1af5f705" + + "20ca232ed2582feeca2d56a589eec30c27075a44aced8382d87cd43c011aeeb0" + + "2df7d0d9ae47467ca500b528f38ac38433885d6a59db6ecd7d27d37145e75360" + + "1e4d8d4d8878cad4de8dbb31ec11d1ecd7b40617c46bb7189ccab201b9bdbaab"; + + private static final String QUADRUPLE_P = + "01395d002b3ca9180fb924650ef0656ead838fd027d487fed681de0d674c30da" + + "097c3a9a072f9c85edf7a36812f8ee05e2cc73140749dcd7d29ceb34a8412188" + + "2bd3295ff81c577fe772543783411c36f463676d9692ca4250588fbad0b44dc7" + + "07d8d8329e62324af8091e3a4ffe5a57cb8664d1f5f6838c55261177118e9313" + + "230f1851ba0d3d7d36c8603c7118c86bd2b6a7a1610c4af9e907cb702beff1d8" + + "12843e703009c1c1a2f1088dcf4d91e9ed43189aa6327cae9a68be22a1aee5cb"; + + private static final String QUADRUPLE_Q = + "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" + + "12618811f3e9fa06644d43cfe3f69c6c17a738128de60f8f3ebb4266bab29be6" + + "00a5a6c2ec01c4d1374078ae1bbea91dea8e938c1275226a1ce51db5e7de53d1" + + "2da43ecc11a0095a72454bb08fb4d1116facadcab482a1107ae67a12bb3c19f2" + + "1e2f128bf79945a370324b82c36c1e63509b122c023bd8163495526bb030a216"; + + private static final String QUADRUPLE_R = + "1296d042f33ccbb814746e187aa20af49bd503356de4846abee08da9e32ae2ac" + + "0b980019d2af83b353aa8c2efda45f16ce523b99452118be7ae5dd1e92e0e4ec" + + "0cdc14ed1231209df350fbf71c359fa338955c8e4b10678b33237e54473e7b0f" + + "2c5be308b741fee6607eea4980779483339372c80494a43189ab6613f2ac6b00" + + "0a56a2a107cc154cade228f3da75a714a7de0738b9ebd455f3f73c4c3c43136b" + + "1d98bf24e00f830334bdf3334135c5aa55b6fd4e88e87b1aee72fb1550970879"; + + private static final String QUADRUPLE_S = + "0baab17525d29e5d7c34a5cdb6558e8427f5c79206e009b4b1e8b91a4c827f1c" + + "18cb7444434d59d126ccc48244daa9a3709140bfa58bff81751d42b647211a91" + + "27f28ec95a4937c625a4fa28551ba8b7010511313699acb72d5eb0a0a208df2b" + + "2e04f5f992061adf169ef7423bc2f8748ca8fe437036e44a5a24b32bdbae8754" + + "056d39d4c664d7bf3417673a870f94749311be2f4e4c5fdfe6563b1593fcc00e" + + "18b849ea2b045d9b94d2e1d8daa843ef2c98577bb7c98d6004eb8982f561fd0f"; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java index 144ddf445b..1c236acdc8 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java @@ -12,6 +12,27 @@ * * SPDX-License-Identifier: Apache-2.0 */ -package net.consensys.linea.zktracer.module.ecdata.ecpairing; -public class SmallPointCandidate { +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; + +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +public enum SmallPointCandidate { + // valid points + INFINITY, + VALID_SMALL_POINT, + // invalid points + X_NOT_IN_FIELD, + Y_NOT_IN_FIELD, + NOT_ON_CURVE, + RAND; + + public boolean isValid() { + return this == INFINITY || this == VALID_SMALL_POINT; + } + + public boolean isInfinity() { + return this == INFINITY; + } + + public static String POINT_AT_INFINITY = "00".repeat(2 * WORD_SIZE); } From 106f77fccd27ca1bc3f2894f33afe0fe1e170ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 01:52:46 +0100 Subject: [PATCH 45/57] spotless --- .../callTests/prc/ecpairing/MemoryContents.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index 5563c3cdb5..f82b471bb6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -49,9 +49,10 @@ * range. */ public class MemoryContents implements PrecompileCallMemoryContents { + public final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; + private final String RETURN_DATA_STRIP = "ff".repeat(WORD_SIZE); public final SmallPointCandidate small; public final LargePointCandidate large; - ; public boolean centerPairIsValid() { return small.isValid() && large.isValid(); @@ -66,8 +67,6 @@ public MemoryContents(SmallPointCandidate small, LargePointCandidate large) { this.large = large; } - public final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; - private final String RETURN_DATA_STRIP = "ff".repeat(WORD_SIZE); boolean variant = false; @Override @@ -77,8 +76,9 @@ public void switchVariant() { @Override public BytecodeCompiler memoryContents() { - String memoryContentsString = leftPairs() + CenterPair() + rightPairs() + RETURN_DATA_STRIP; - Bytes memoryContentsBytes = Bytes.fromHexString(memoryContentsString); + Bytes memoryContentsBytes = + Bytes.fromHexString(leftPairs() + CenterPair() + rightPairs() + RETURN_DATA_STRIP); + // TODO: replace 192 with the appropriate constant (maybe add to GlobalConstants) checkState( memoryContentsBytes.size() == NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY * 192 + WORD_SIZE * 2); @@ -100,7 +100,7 @@ private String rightPairs() { // All values below are obtained from Ivo's comment // https://github.com/Consensys/linea-tracer/issues/822#issuecomment-2260511164 - + private static final String NEGATIVE_P = "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" From 49672e4f1ee6d3cb9770d99bbfc8860c4723f050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 02:25:03 +0100 Subject: [PATCH 46/57] feat: ECPAIRING wip --- .../prc/ecpairing/LargePointCandidate.java | 27 ++++++- .../prc/ecpairing/MemoryContents.java | 70 +++++++++++++++++-- .../prc/ecpairing/SmallPointCandidate.java | 21 +++++- 3 files changed, 112 insertions(+), 6 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java index 41fb740325..e195255d41 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java @@ -37,5 +37,30 @@ public boolean isInfinity() { return this == INFINITY; } - public static String POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); + public static String LARGE_POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); + + public String hexString() { + switch (this) { + case INFINITY: + return LARGE_POINT_AT_INFINITY; + case VALID_LARGE_POINT: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case RAND: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case RE_X_NOT_IN_FIELD: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case IM_X_NOT_IN_FIELD: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case RE_Y_NOT_IN_FIELD: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case IM_Y_NOT_IN_FIELD: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case NOT_ON_CURVE: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + case NOT_IN_SUBGROUP: + return "0x1" + "00".repeat(4 * WORD_SIZE - 1); + default: + throw new RuntimeException("Invalid point candidate"); + } + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index f82b471bb6..a51657d415 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -15,6 +15,8 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.LargePointCandidate.LARGE_POINT_AT_INFINITY; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPointCandidate.SMALL_POINT_AT_INFINITY; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; @@ -49,8 +51,9 @@ * range. */ public class MemoryContents implements PrecompileCallMemoryContents { - public final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; + private final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; private final String RETURN_DATA_STRIP = "ff".repeat(WORD_SIZE); + public final SmallPointCandidate small; public final LargePointCandidate large; @@ -87,20 +90,71 @@ public BytecodeCompiler memoryContents() { } private String leftPairs() { - throw new RuntimeException("memoryContents not implemented"); + return (C1_POINT_1 + LARGE_POINT_AT_INFINITY) + + (SMALL_POINT_AT_INFINITY + LARGE_POINT_AT_INFINITY) + + NEGATIVE_P + + (SMALL_POINT_AT_INFINITY + G2_POINT_1) + + (variant ? TRIPLE_P : QUADRUPLE_P) + + (C1_POINT_2 + LARGE_POINT_AT_INFINITY) + + (variant ? TRIPLE_R : QUADRUPLE_R) + + (variant ? TRIPLE_Q : QUADRUPLE_Q) + + (SMALL_POINT_AT_INFINITY + G2_POINT_2); } private String CenterPair() { - return small.toString() + large.toString(); + return small.hexString() + large.hexString(); } private String rightPairs() { - throw new RuntimeException("memoryContents not implemented"); + return (SMALL_POINT_AT_INFINITY + G2_POINT_3) + + (variant ? C1_POINT_3 + G2_POINT_4 : QUADRUPLE_S); } // All values below are obtained from Ivo's comment // https://github.com/Consensys/linea-tracer/issues/822#issuecomment-2260511164 + private static final String C1_POINT_1 = + "26d7d8759964ac70b4d5cdf698ad5f70da246752481ea37da637551a60a2a57f" + + "13991eda70bd3bd91c43e7c93f8f89c949bd271ba8f9f5a38bce7248f1f6056b"; + private static final String C1_POINT_2 = + "1760ca14c35b8978c10ba226b4654e4c925218417ec23731c29da60f481c2c0a" + + "16206149ae732094afbc9921444e04cae6e093a0e73f3212a5e9f93a04f7f07a"; + private static final String C1_POINT_3 = + "214eb4ed76fa9ea509001fa6d4a1ddc86ac42da639fba6e4956b4045dd74fa26" + + "0a847e7fee1a9b1c6166724ec7eea284fd71506e31371674164f860ac641b0e4"; + private static final String C1_POINT_4 = + "1cbcc5ae2ad1e062ffbfe7858b0f962d24656075da7f168779afb5167da8e946" + + "1504db20d014e62edf9b2105d8fc6c62919351144cfdd8c6e12c3290d9903a79"; + private static final String C1_POINT_5 = + "117e59d40acc2608b961101994f76516f4cd4204af85de7d499c2b9043e0d771" + + "2c76b5677261cc2851a41b75f03497ef99522c1c29a4f4d2aba921997cec664a"; + + private static final String G2_POINT_1 = + "13eb8555f322c3885846df8a505693a0012493a30c34196a529f964a684c0cb2" + + "18335a998f3db61d3d0b63cd1371789a9a8a5ed4fb1a4adaa20ab9573251a9d0" + + "20494259608bfb4cd04716ba62e1350ce90d00d8af00a5170f46f59ae72d060c" + + "257a64fbc5a9cf9c3f7be349d09efa099305fe61f364c31c082ef6a81c815c1d"; + private static final String G2_POINT_2 = + "2f1e9fe1d767c3ee1f801d43e4238a28cb4f94d3e644b2c43e236a503eade386" + + "14675488459758a6e2f0bebcf5cd4c70c0c6d9733575c999a09418ae773ae6b5" + + "0ae82edaac30d3ff28ea0c4d8e43e39622b47a19beb334a4216994e3a98a796a" + + "237392d458d5e3a479ebb4feac87c4371150ea86ee61f3268f5b65bca02daa4a"; + private static final String G2_POINT_3 = + "210c2d4972a76beee46732b60ed998e2e60769847350553f274523a7a9b23d17" + + "0dd0cf966d5a0ef6d560e7dc949b48839e14e26bb8e22d08029b17e1f916de8b" + + "22a8f09fd8c34454c77a7aeb7d7d6e00e160cdf03700c1e503b7e0cabf9aba3c" + + "2090ce9e959dcf086d024dd626111301fd559aab1b4a475bb4c59cd7f598af83"; + private static final String G2_POINT_4 = + "15746a21d15b2ffb960a9cb93426fc05f20921467c23f89494966d13e1507e87" + + "29670f195cd081b64b28dae6420ad919a7ca8a5c3a0ae5c313420cd4aca339af" + + "056e6142247149ea3505c5adbd6f3d1af9f51d50fdd2cdcd637221ee9ef80a3c" + + "025f9828f38707d5cb94e8905be933d4ae03e7f084e250a2c65f0c856035a2a4"; + private static final String G2_POINT_5 = + "22007e1404f2d2f0a9b676095daef5b4d49be05df224ef98a2cd00da756900d9" + + "1d8281748ef6cd4dd40149ce6f2afbcc26f3d2499cb484b0a4c21872f9816171" + + "191fc3a7eb19e1f750c5c3dc7a008c8d35dc08feb1de5dd24f293bc2fd84a739" + + "16dca8731c250e792423469ab23a2f7d4891d55d43da021f6ce572f268e2cab9"; + private static final String NEGATIVE_P = "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" @@ -164,4 +218,12 @@ private String rightPairs() { + "2e04f5f992061adf169ef7423bc2f8748ca8fe437036e44a5a24b32bdbae8754" + "056d39d4c664d7bf3417673a870f94749311be2f4e4c5fdfe6563b1593fcc00e" + "18b849ea2b045d9b94d2e1d8daa843ef2c98577bb7c98d6004eb8982f561fd0f"; + + @Override + public String String() { + return "MemoryContents{" + + "small=" + small + + ", large=" + large + + '}'; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java index 1c236acdc8..d76b667d0c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java @@ -34,5 +34,24 @@ public boolean isInfinity() { return this == INFINITY; } - public static String POINT_AT_INFINITY = "00".repeat(2 * WORD_SIZE); + public static String SMALL_POINT_AT_INFINITY = "00".repeat(2 * WORD_SIZE); + + public String hexString() { + switch (this) { + case INFINITY: + return SMALL_POINT_AT_INFINITY; + case VALID_SMALL_POINT: + return "0x1" + "00".repeat(2 * WORD_SIZE - 1); + case X_NOT_IN_FIELD: + return "0x1" + "00".repeat(2 * WORD_SIZE - 1); + case Y_NOT_IN_FIELD: + return "0x1" + "00".repeat(2 * WORD_SIZE - 1); + case NOT_ON_CURVE: + return "0x1" + "00".repeat(2 * WORD_SIZE - 1); + case RAND: + return "0x1" + "00".repeat(2 * WORD_SIZE - 1); + default: + throw new IllegalArgumentException("Invalid point candidate"); + } + } } From d1cb7622944b80641b3619da0d60f6034079e9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 13:49:02 +0100 Subject: [PATCH 47/57] wip ECPAIRING --- .../prc/ecpairing/LargePointCandidate.java | 78 +++++++++++++------ .../prc/ecpairing/MemoryContents.java | 12 +-- .../prc/ecpairing/SmallPointCandidate.java | 49 +++++++----- 3 files changed, 89 insertions(+), 50 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java index e195255d41..4ecf44f42c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java @@ -14,6 +14,10 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; public enum LargePointCandidate { @@ -37,30 +41,56 @@ public boolean isInfinity() { return this == INFINITY; } - public static String LARGE_POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); - + // various hex strings are taken from Ivo's comment + // public String hexString() { - switch (this) { - case INFINITY: - return LARGE_POINT_AT_INFINITY; - case VALID_LARGE_POINT: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case RAND: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case RE_X_NOT_IN_FIELD: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case IM_X_NOT_IN_FIELD: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case RE_Y_NOT_IN_FIELD: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case IM_Y_NOT_IN_FIELD: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case NOT_ON_CURVE: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - case NOT_IN_SUBGROUP: - return "0x1" + "00".repeat(4 * WORD_SIZE - 1); - default: - throw new RuntimeException("Invalid point candidate"); - } + final String result = switch (this) { + case INFINITY -> LARGE_POINT_AT_INFINITY; + case VALID_LARGE_POINT -> G2_POINT_5; + case RAND -> RND.substring(36, 36 + 4 * WORD_HEX_SIZE); + case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; + case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; + case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; + case IM_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_Y; + case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; + case NOT_IN_SUBGROUP -> ON_CURVE_BUT_NOT_ON_SUBGROUP; + default -> throw new RuntimeException("Invalid point candidate"); + }; + checkState(result.length() == 4 * WORD_HEX_SIZE, "Invalid hex string length"); + + return result; } + + public final static String LARGE_POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); + public final static String IN_RANGE_SAVE_FOR_LARGE_RE_X = + "268294ac35af168840b758c749a19a7b1ffcb3df81e0047f2a4a3a68549fe8b9" + + "facbb907b18555b9fa34efaa266ab946e1c7eadfe9d8f0cd821e7448e8a8053a" + + "2fe08b1ff6a7fbe4cc3f0bfc309ae33bca35e9b29de0b2b3a73a829f3b9393cf" + + "1b38210130d62850704dfeeee59e982308d9c976e583ad20a4289145cfcf3b1d"; + public final static String IN_RANGE_SAVE_FOR_LARGE_IM_X = + "4dbf7d5e29252a3f871fe6ec7bbb736a82c6a92e1f383988fbf1993fd254535c" + + "28747a6a24cce55f56d4847a08e45f2b19a575097915bfb39048be362f605ff8" + + "031b86886f00782d83503db96caf1bb0ed6f68a907464fbb5b0de864b80c1ffd" + + "302ca42cef622575199921b4f82e95009d09aba8e18c2240b9d084ac8bfd27de"; + public final static String IN_RANGE_SAVE_FOR_LARGE_RE_Y = + "0fefff1654529948ddff9422011555b212236211766ce7674f9de0867248bec0" + + "101dce57329a75b870c3ed82911561dddc38337d9de49c1a201e42097074d358" + + "0b9a97e4531fb7c625ba34bf2939bc22a8ad8b2e03d0bd4cc9def5fdf96f30dc" + + "5786a896704be805b5301789420715b9e6c4608d6bbf593b8c2bdc27b504eb91"; + public final static String IN_RANGE_SAVE_FOR_LARGE_IM_Y = + "2ab1c49ae7628ad0ef94a9e181a47f7ebbf697173af1587ee152684b98b3b0d5" + + "0efd3c694ab7d704b3f241402397b340a509ba863775d7b8ee1e8c99eddec530" + + "5b2a592225a2ce715a205171f503ae70024f4842b4888407d67e0c580d3459d3" + + "06433c581782ec0072e2185740924ac1fa2cf74905b40a901d3a7dfc7edb10e0"; + public final static String IN_RANGE_BUT_NOT_ON_CURVE = + "1d3df5be6084324da6333a6ad1367091ca9fbceb70179ec484543a58b8cb5d63" + + "119606e6d3ea97cea4eff54433f5c7dbc026b8d0670ddfbe6441e31225028d31" + + "49fe60975e8c78b7b31a6ed16a338ac8b28cf6a065cfd2ca47e9402882518ba0" + + "1b9a36ea373fe2c5b713557042ce6deb2907d34e12be595f9bbe84c144de86ef"; + public final static String ON_CURVE_BUT_NOT_ON_SUBGROUP = + "15ce93f1b1c4946dd6cfbb3d287d9c9a1cdedb264bda7aada0844416d8a47a63" + + "07192b9fd0e2a32e3e1caa8e59462b757326d48f641924e6a1d00d66478913eb" + + "06e1f5e20f68f6dfa8a91a3bea048df66d9eaf56cc7f11215401f7e05027e0c6" + + "0fa65a9b48ba018361ed081e3b9e958451de5d9e8ae0bd251833ebb4b2fafc96"; + } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index a51657d415..2d4f314a88 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -15,6 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.LargePointCandidate.LARGE_POINT_AT_INFINITY; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPointCandidate.SMALL_POINT_AT_INFINITY; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; @@ -122,7 +123,7 @@ private String rightPairs() { private static final String C1_POINT_3 = "214eb4ed76fa9ea509001fa6d4a1ddc86ac42da639fba6e4956b4045dd74fa26" + "0a847e7fee1a9b1c6166724ec7eea284fd71506e31371674164f860ac641b0e4"; - private static final String C1_POINT_4 = + public static final String C1_POINT_4 = "1cbcc5ae2ad1e062ffbfe7858b0f962d24656075da7f168779afb5167da8e946" + "1504db20d014e62edf9b2105d8fc6c62919351144cfdd8c6e12c3290d9903a79"; private static final String C1_POINT_5 = @@ -149,7 +150,7 @@ private String rightPairs() { + "29670f195cd081b64b28dae6420ad919a7ca8a5c3a0ae5c313420cd4aca339af" + "056e6142247149ea3505c5adbd6f3d1af9f51d50fdd2cdcd637221ee9ef80a3c" + "025f9828f38707d5cb94e8905be933d4ae03e7f084e250a2c65f0c856035a2a4"; - private static final String G2_POINT_5 = + public static final String G2_POINT_5 = "22007e1404f2d2f0a9b676095daef5b4d49be05df224ef98a2cd00da756900d9" + "1d8281748ef6cd4dd40149ce6f2afbcc26f3d2499cb484b0a4c21872f9816171" + "191fc3a7eb19e1f750c5c3dc7a008c8d35dc08feb1de5dd24f293bc2fd84a739" @@ -170,7 +171,6 @@ private String rightPairs() { + "07d8d8329e62324af8091e3a4ffe5a57cb8664d1f5f6838c55261177118e9313" + "230f1851ba0d3d7d36c8603c7118c86bd2b6a7a1610c4af9e907cb702beff1d8" + "12843e703009c1c1a2f1088dcf4d91e9ed43189aa6327cae9a68be22a1aee5cb"; - private static final String TRIPLE_Q = "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" @@ -178,7 +178,6 @@ private String rightPairs() { + "00a5a6c2ec01c4d1374078ae1bbea91dea8e938c1275226a1ce51db5e7de53d1" + "2da43ecc11a0095a72454bb08fb4d1116facadcab482a1107ae67a12bb3c19f2" + "1e2f128bf79945a370324b82c36c1e63509b122c023bd8163495526bb030a216"; - private static final String TRIPLE_R = "1296d042f33ccbb814746e187aa20af49bd503356de4846abee08da9e32ae2ac" + "0b980019d2af83b353aa8c2efda45f16ce523b99452118be7ae5dd1e92e0e4ec" @@ -194,7 +193,6 @@ private String rightPairs() { + "07d8d8329e62324af8091e3a4ffe5a57cb8664d1f5f6838c55261177118e9313" + "230f1851ba0d3d7d36c8603c7118c86bd2b6a7a1610c4af9e907cb702beff1d8" + "12843e703009c1c1a2f1088dcf4d91e9ed43189aa6327cae9a68be22a1aee5cb"; - private static final String QUADRUPLE_Q = "05dcb6449ff95e1a04c3132ce3be82a897811d2087e082e0399985449942a45b" + "0cb5122006e9b7ceb5307fa4015b132b3945bb972c83459f598659fc4b5a9d32" @@ -202,7 +200,6 @@ private String rightPairs() { + "00a5a6c2ec01c4d1374078ae1bbea91dea8e938c1275226a1ce51db5e7de53d1" + "2da43ecc11a0095a72454bb08fb4d1116facadcab482a1107ae67a12bb3c19f2" + "1e2f128bf79945a370324b82c36c1e63509b122c023bd8163495526bb030a216"; - private static final String QUADRUPLE_R = "1296d042f33ccbb814746e187aa20af49bd503356de4846abee08da9e32ae2ac" + "0b980019d2af83b353aa8c2efda45f16ce523b99452118be7ae5dd1e92e0e4ec" @@ -210,7 +207,6 @@ private String rightPairs() { + "2c5be308b741fee6607eea4980779483339372c80494a43189ab6613f2ac6b00" + "0a56a2a107cc154cade228f3da75a714a7de0738b9ebd455f3f73c4c3c43136b" + "1d98bf24e00f830334bdf3334135c5aa55b6fd4e88e87b1aee72fb1550970879"; - private static final String QUADRUPLE_S = "0baab17525d29e5d7c34a5cdb6558e8427f5c79206e009b4b1e8b91a4c827f1c" + "18cb7444434d59d126ccc48244daa9a3709140bfa58bff81751d42b647211a91" @@ -220,7 +216,7 @@ private String rightPairs() { + "18b849ea2b045d9b94d2e1d8daa843ef2c98577bb7c98d6004eb8982f561fd0f"; @Override - public String String() { + public String toString() { return "MemoryContents{" + "small=" + small + ", large=" + large + diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java index d76b667d0c..e6a0d53d00 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java @@ -14,6 +14,10 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.C1_POINT_4; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; public enum SmallPointCandidate { @@ -34,24 +38,33 @@ public boolean isInfinity() { return this == INFINITY; } - public static String SMALL_POINT_AT_INFINITY = "00".repeat(2 * WORD_SIZE); - public String hexString() { - switch (this) { - case INFINITY: - return SMALL_POINT_AT_INFINITY; - case VALID_SMALL_POINT: - return "0x1" + "00".repeat(2 * WORD_SIZE - 1); - case X_NOT_IN_FIELD: - return "0x1" + "00".repeat(2 * WORD_SIZE - 1); - case Y_NOT_IN_FIELD: - return "0x1" + "00".repeat(2 * WORD_SIZE - 1); - case NOT_ON_CURVE: - return "0x1" + "00".repeat(2 * WORD_SIZE - 1); - case RAND: - return "0x1" + "00".repeat(2 * WORD_SIZE - 1); - default: - throw new IllegalArgumentException("Invalid point candidate"); - } + final String result = + switch (this) { + case INFINITY -> SMALL_POINT_AT_INFINITY; + case VALID_SMALL_POINT -> C1_POINT_4; + case X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_X; + case Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_Y; + case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; + case RAND -> RND.substring(147, 147 + 2 * WORD_HEX_SIZE); + default -> throw new IllegalArgumentException("Invalid point candidate"); + }; + checkState(result.length() == 2 * WORD_HEX_SIZE, "Invalid hex string length"); + + return result; } + + // All values below are obtained from Ivo's comment + // https://github.com/Consensys/linea-tracer/issues/822#issuecomment-2260511164 + + public static final String SMALL_POINT_AT_INFINITY = "00".repeat(2 * WORD_SIZE); + public static final String IN_RANGE_SAVE_FOR_LARGE_X = + "b3a1cca4c86cdc017597bb5e39705666199eccabc367f8c6aa5e713921c0886e" + + "2018c3b9c5993f6e66a53edf1524775bd337cd82931b44760bdb4e0f557fcf55"; + public static final String IN_RANGE_SAVE_FOR_LARGE_Y = + "29c5b47fbe82856ac08cfc5e72ee76f9ca909a4360ceafdbb058792b4dea2380" + + "ced846e53d3564f9d059532c94207b64cba68393988bb0bd26711c828f68cd64"; + public static final String IN_RANGE_BUT_NOT_ON_CURVE = + "1dac6eed25388228c5542dfc2c0b30bd5afbb4fb091791052ad8ca6a8e1c94fb" + + "0b35150d9fe2b8cff4e81fd7445b6d529f68ca798d16618adf0f1d319e772987"; } From da4f47c98d7faea53a8593cdc75e9dd1493f4ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 15:56:15 +0100 Subject: [PATCH 48/57] feat: the PLENTY GasParameter now only provides GAS/2 --- .../callTests/prc/ecmul/CallParameters.java | 5 +- .../prc/ecmul/ParameterGeneration.java | 4 +- ...lDataParameter.java => CallDataRange.java} | 1 - .../prc/ecpairing/CallParameters.java | 17 ++++ .../callTests/prc/ecpairing/LargePoint.java | 96 +++++++++++++++++++ .../prc/ecpairing/LargePointCandidate.java | 96 ------------------- .../prc/ecpairing/ParameterGeneration.java | 17 ++++ ...allPointCandidate.java => SmallPoint.java} | 0 .../callTests/prc/ecpairing/Tests.java | 17 ++++ 9 files changed, 151 insertions(+), 102 deletions(-) rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/{CallDataParameter.java => CallDataRange.java} (96%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java delete mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java rename arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/{SmallPointCandidate.java => SmallPoint.java} (100%) create mode 100644 arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java index 2e175269d2..29e664e9b2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/CallParameters.java @@ -15,8 +15,7 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.GAS; -import static net.consensys.linea.zktracer.opcode.OpCode.MSIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.*; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; @@ -102,7 +101,7 @@ public void appendCustomPrecompileCall(BytecodeCompiler program) { case ZERO -> program.push(0); // interesting in the nonzero value case case COST_MO -> program.push(6_000 - callStipend - 1); case COST -> program.push(6_000 - callStipend); - case FULL -> program.op(GAS); + case PLENTY -> program.push(2).op(GAS).op(DIV); // half of gas default -> throw new RuntimeException("Unsupported gas parameter"); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java index d9dd613a13..85aab14dd2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecmul/ParameterGeneration.java @@ -14,6 +14,7 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecmul; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; import static net.consensys.linea.zktracer.opcode.OpCode.*; import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; @@ -30,8 +31,7 @@ public class ParameterGeneration { public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - List GasParameters = - List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); + List GasParameters = List.of(ZERO, COST_MO, COST, PLENTY); List ReturnAtParameters = List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java similarity index 96% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java index a3a4b3aa53..9f4704444c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataParameter.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java @@ -16,6 +16,5 @@ public enum CallDataParameter { EMPTY, - SINGLE_PAIR_OF_POINTS, RANGE_OF_PAIRS_OF_POINTS; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java new file mode 100644 index 0000000000..de29bde727 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +public class CallParameters { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java new file mode 100644 index 0000000000..878315ff33 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java @@ -0,0 +1,96 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; + +import static com.google.common.base.Preconditions.checkState; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; + +public enum LargePointCandidate { + // valid points + INFINITY, + VALID_LARGE_POINT, + // invalid points + RAND, + RE_X_NOT_IN_FIELD, + IM_X_NOT_IN_FIELD, + RE_Y_NOT_IN_FIELD, + IM_Y_NOT_IN_FIELD, + NOT_ON_CURVE, + NOT_IN_SUBGROUP; + + public boolean isValid() { + return this == INFINITY || this == VALID_LARGE_POINT; + } + + public boolean isInfinity() { + return this == INFINITY; + } + + // various hex strings are taken from Ivo's comment + // + public String hexString() { + final String result = + switch (this) { + case INFINITY -> LARGE_POINT_AT_INFINITY; + case VALID_LARGE_POINT -> G2_POINT_5; + case RAND -> RND.substring(36, 36 + 4 * WORD_HEX_SIZE); + case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; + case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; + case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; + case IM_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_Y; + case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; + case NOT_IN_SUBGROUP -> ON_CURVE_BUT_NOT_ON_SUBGROUP; + default -> throw new RuntimeException("Invalid point candidate"); + }; + checkState(result.length() == 4 * WORD_HEX_SIZE, "Invalid hex string length"); + + return result; + } + + public static final String LARGE_POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); + public static final String IN_RANGE_SAVE_FOR_LARGE_RE_X = + "268294ac35af168840b758c749a19a7b1ffcb3df81e0047f2a4a3a68549fe8b9" + + "facbb907b18555b9fa34efaa266ab946e1c7eadfe9d8f0cd821e7448e8a8053a" + + "2fe08b1ff6a7fbe4cc3f0bfc309ae33bca35e9b29de0b2b3a73a829f3b9393cf" + + "1b38210130d62850704dfeeee59e982308d9c976e583ad20a4289145cfcf3b1d"; + public static final String IN_RANGE_SAVE_FOR_LARGE_IM_X = + "4dbf7d5e29252a3f871fe6ec7bbb736a82c6a92e1f383988fbf1993fd254535c" + + "28747a6a24cce55f56d4847a08e45f2b19a575097915bfb39048be362f605ff8" + + "031b86886f00782d83503db96caf1bb0ed6f68a907464fbb5b0de864b80c1ffd" + + "302ca42cef622575199921b4f82e95009d09aba8e18c2240b9d084ac8bfd27de"; + public static final String IN_RANGE_SAVE_FOR_LARGE_RE_Y = + "0fefff1654529948ddff9422011555b212236211766ce7674f9de0867248bec0" + + "101dce57329a75b870c3ed82911561dddc38337d9de49c1a201e42097074d358" + + "0b9a97e4531fb7c625ba34bf2939bc22a8ad8b2e03d0bd4cc9def5fdf96f30dc" + + "5786a896704be805b5301789420715b9e6c4608d6bbf593b8c2bdc27b504eb91"; + public static final String IN_RANGE_SAVE_FOR_LARGE_IM_Y = + "2ab1c49ae7628ad0ef94a9e181a47f7ebbf697173af1587ee152684b98b3b0d5" + + "0efd3c694ab7d704b3f241402397b340a509ba863775d7b8ee1e8c99eddec530" + + "5b2a592225a2ce715a205171f503ae70024f4842b4888407d67e0c580d3459d3" + + "06433c581782ec0072e2185740924ac1fa2cf74905b40a901d3a7dfc7edb10e0"; + public static final String IN_RANGE_BUT_NOT_ON_CURVE = + "1d3df5be6084324da6333a6ad1367091ca9fbceb70179ec484543a58b8cb5d63" + + "119606e6d3ea97cea4eff54433f5c7dbc026b8d0670ddfbe6441e31225028d31" + + "49fe60975e8c78b7b31a6ed16a338ac8b28cf6a065cfd2ca47e9402882518ba0" + + "1b9a36ea373fe2c5b713557042ce6deb2907d34e12be595f9bbe84c144de86ef"; + public static final String ON_CURVE_BUT_NOT_ON_SUBGROUP = + "15ce93f1b1c4946dd6cfbb3d287d9c9a1cdedb264bda7aada0844416d8a47a63" + + "07192b9fd0e2a32e3e1caa8e59462b757326d48f641924e6a1d00d66478913eb" + + "06e1f5e20f68f6dfa8a91a3bea048df66d9eaf56cc7f11215401f7e05027e0c6" + + "0fa65a9b48ba018361ed081e3b9e958451de5d9e8ae0bd251833ebb4b2fafc96"; +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java deleted file mode 100644 index 4ecf44f42c..0000000000 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePointCandidate.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright Consensys Software Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - */ -package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; - -import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; - -public enum LargePointCandidate { - // valid points - INFINITY, - VALID_LARGE_POINT, - // invalid points - RAND, - RE_X_NOT_IN_FIELD, - IM_X_NOT_IN_FIELD, - RE_Y_NOT_IN_FIELD, - IM_Y_NOT_IN_FIELD, - NOT_ON_CURVE, - NOT_IN_SUBGROUP; - - public boolean isValid() { - return this == INFINITY || this == VALID_LARGE_POINT; - } - - public boolean isInfinity() { - return this == INFINITY; - } - - // various hex strings are taken from Ivo's comment - // - public String hexString() { - final String result = switch (this) { - case INFINITY -> LARGE_POINT_AT_INFINITY; - case VALID_LARGE_POINT -> G2_POINT_5; - case RAND -> RND.substring(36, 36 + 4 * WORD_HEX_SIZE); - case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; - case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; - case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; - case IM_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_Y; - case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; - case NOT_IN_SUBGROUP -> ON_CURVE_BUT_NOT_ON_SUBGROUP; - default -> throw new RuntimeException("Invalid point candidate"); - }; - checkState(result.length() == 4 * WORD_HEX_SIZE, "Invalid hex string length"); - - return result; - } - - public final static String LARGE_POINT_AT_INFINITY = "00".repeat(4 * WORD_SIZE); - public final static String IN_RANGE_SAVE_FOR_LARGE_RE_X = - "268294ac35af168840b758c749a19a7b1ffcb3df81e0047f2a4a3a68549fe8b9" - + "facbb907b18555b9fa34efaa266ab946e1c7eadfe9d8f0cd821e7448e8a8053a" - + "2fe08b1ff6a7fbe4cc3f0bfc309ae33bca35e9b29de0b2b3a73a829f3b9393cf" - + "1b38210130d62850704dfeeee59e982308d9c976e583ad20a4289145cfcf3b1d"; - public final static String IN_RANGE_SAVE_FOR_LARGE_IM_X = - "4dbf7d5e29252a3f871fe6ec7bbb736a82c6a92e1f383988fbf1993fd254535c" - + "28747a6a24cce55f56d4847a08e45f2b19a575097915bfb39048be362f605ff8" - + "031b86886f00782d83503db96caf1bb0ed6f68a907464fbb5b0de864b80c1ffd" - + "302ca42cef622575199921b4f82e95009d09aba8e18c2240b9d084ac8bfd27de"; - public final static String IN_RANGE_SAVE_FOR_LARGE_RE_Y = - "0fefff1654529948ddff9422011555b212236211766ce7674f9de0867248bec0" - + "101dce57329a75b870c3ed82911561dddc38337d9de49c1a201e42097074d358" - + "0b9a97e4531fb7c625ba34bf2939bc22a8ad8b2e03d0bd4cc9def5fdf96f30dc" - + "5786a896704be805b5301789420715b9e6c4608d6bbf593b8c2bdc27b504eb91"; - public final static String IN_RANGE_SAVE_FOR_LARGE_IM_Y = - "2ab1c49ae7628ad0ef94a9e181a47f7ebbf697173af1587ee152684b98b3b0d5" - + "0efd3c694ab7d704b3f241402397b340a509ba863775d7b8ee1e8c99eddec530" - + "5b2a592225a2ce715a205171f503ae70024f4842b4888407d67e0c580d3459d3" - + "06433c581782ec0072e2185740924ac1fa2cf74905b40a901d3a7dfc7edb10e0"; - public final static String IN_RANGE_BUT_NOT_ON_CURVE = - "1d3df5be6084324da6333a6ad1367091ca9fbceb70179ec484543a58b8cb5d63" - + "119606e6d3ea97cea4eff54433f5c7dbc026b8d0670ddfbe6441e31225028d31" - + "49fe60975e8c78b7b31a6ed16a338ac8b28cf6a065cfd2ca47e9402882518ba0" - + "1b9a36ea373fe2c5b713557042ce6deb2907d34e12be595f9bbe84c144de86ef"; - public final static String ON_CURVE_BUT_NOT_ON_SUBGROUP = - "15ce93f1b1c4946dd6cfbb3d287d9c9a1cdedb264bda7aada0844416d8a47a63" - + "07192b9fd0e2a32e3e1caa8e59462b757326d48f641924e6a1d00d66478913eb" - + "06e1f5e20f68f6dfa8a91a3bea048df66d9eaf56cc7f11215401f7e05027e0c6" - + "0fa65a9b48ba018361ed081e3b9e958451de5d9e8ae0bd251833ebb4b2fafc96"; - -} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java new file mode 100644 index 0000000000..98ab8f5aff --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +public class ParameterGeneration { +} diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java similarity index 100% rename from arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPointCandidate.java rename to arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java new file mode 100644 index 0000000000..e4f42d3362 --- /dev/null +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java @@ -0,0 +1,17 @@ +/* + * Copyright Consensys Software Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +public class Tests { +} From 34116589affa47d9e290c632fdb7a67aac937662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 15:56:26 +0100 Subject: [PATCH 49/57] wip ECPAIRING --- .../prc/ecpairing/CallDataRange.java | 45 ++++++- .../prc/ecpairing/CallParameters.java | 110 +++++++++++++++++- .../callTests/prc/ecpairing/LargePoint.java | 2 +- .../prc/ecpairing/MemoryContents.java | 26 ++--- .../prc/ecpairing/ParameterGeneration.java | 76 ++++++++++++ .../callTests/prc/ecpairing/SmallPoint.java | 2 +- .../callTests/prc/ecpairing/Tests.java | 27 +++++ 7 files changed, 268 insertions(+), 20 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java index 9f4704444c..a05ad3eecc 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java @@ -14,7 +14,46 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; -public enum CallDataParameter { - EMPTY, - RANGE_OF_PAIRS_OF_POINTS; +import static com.google.common.base.Preconditions.checkArgument; + +public class CallDataRange { + + private final int firstPoint; + private final int finalPoint; + public boolean isEmpty = false; + + public CallDataRange(int firstPoint, int finalPoint) { + checkArgument(finalPoint >= firstPoint, "final point must be greater than or equal to first point"); + this.firstPoint = firstPoint; + this.finalPoint = finalPoint; + } + + public CallDataRange() { + this.firstPoint = 0; + this.finalPoint = 0; + this.isEmpty = true; + } + + public boolean isEmpty() { + return isEmpty; + } + + public int firstPoint() { + return firstPoint; + } + + public int finalPoint() { + return finalPoint; + } + + public int numberOfPairsOfPoints() { + return isEmpty() + ? 0 + : (finalPoint() - firstPoint() + 1); + } + + @Override + public String toString() { + return "CallDataRange{" + "first point=" + firstPoint + ", final point=" + finalPoint + '}'; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java index de29bde727..43c1e5fb8d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallParameters.java @@ -13,5 +13,113 @@ * SPDX-License-Identifier: Apache-2.0 */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; -public class CallParameters { + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.SIZE_OF_PAIR_OF_POINTS; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.*; +import static net.consensys.linea.zktracer.opcode.OpCode.DIV; +import static net.consensys.linea.zktracer.opcode.OpCode.GAS; + +import net.consensys.linea.testing.BytecodeCompiler; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallMemoryContents; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallParameters; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.hyperledger.besu.datatypes.Address; + +public class CallParameters implements PrecompileCallParameters { + public final OpCode call; + public final GasParameter gas; + public final MemoryContents memoryContents; + public final CallDataRange callDataRange; + public final ReturnAtParameter returnAt; + public final boolean willRevert; + + public CallParameters( + OpCode call, + GasParameter gas, + MemoryContents memoryContents, + CallDataRange callDataRange, + ReturnAtParameter returnAt, + boolean willRevert) { + this.call = call; + this.gas = gas; + this.memoryContents = memoryContents; + this.callDataRange = callDataRange; + this.returnAt = returnAt; + this.willRevert = willRevert; + } + + @Override + public boolean willRevert() { + return willRevert; + } + + @Override + public PrecompileCallMemoryContents memoryContents() { + return memoryContents; + } + + @Override + public void appendCustomPrecompileCall(BytecodeCompiler program) { + // push r@c onto the stack + switch (this.returnAt) { + case EMPTY -> program.push(0); + case PARTIAL -> program.push(13); + case FULL -> program.push(WORD_SIZE); + default -> throw new RuntimeException("Unsupported returnAt parameter"); + } + + // push the r@o onto the stack + program.push(TOTAL_NUMBER_OF_PAIRS_OF_POINTS * SIZE_OF_PAIR_OF_POINTS); + + // push the cds onto the stack + final int cds = callDataRange.numberOfPairsOfPoints() * SIZE_OF_PAIR_OF_POINTS; + program.push(cds); + + // push the cdo onto the stack; + final int cdo = + callDataRange.isEmpty() ? 0 : callDataRange.firstPoint() * SIZE_OF_PAIR_OF_POINTS; + program.push(cdo); + + // if appropriate, push the value onto the stack + if (call.callHasValueArgument()) { + program.push(0x0a00); + } + + program.push(Address.ALTBN128_MUL); + + // push gas onto the stack + int callStipend = call.callHasValueArgument() ? 2_300 : 0; + int prcCost = + GAS_CONST_ECPAIRING + callDataRange.numberOfPairsOfPoints() * GAS_CONST_ECPAIRING_PAIR; + switch (gas) { + case ZERO -> program.push(0); // interesting in the nonzero value case + case COST_MO -> program.push(prcCost - callStipend - 1); + case COST -> program.push(prcCost - callStipend); + case PLENTY -> program.push(2).op(GAS).op(DIV); // half of gas + default -> throw new RuntimeException("Unsupported gas parameter"); + } + + program.op(call); + } + + @Override + public String toString() { + return "CallParameters{" + + "call=" + + call + + ", gas=" + + gas + + ", memoryContents=" + + memoryContents + + ", callDataRange=" + + (callDataRange.isEmpty() ? "∅" : callDataRange) + + ", returnAt=" + + returnAt + + ", willRevert=" + + willRevert + + '}'; + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java index 878315ff33..0241999abc 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java @@ -20,7 +20,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -public enum LargePointCandidate { +public enum LargePoint { // valid points INFINITY, VALID_LARGE_POINT, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index 2d4f314a88..30f6bbd46e 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -15,9 +15,8 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.LargePointCandidate.LARGE_POINT_AT_INFINITY; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPointCandidate.SMALL_POINT_AT_INFINITY; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.LargePoint.LARGE_POINT_AT_INFINITY; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPoint.SMALL_POINT_AT_INFINITY; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; import net.consensys.linea.testing.BytecodeCompiler; @@ -41,8 +40,8 @@ *

  • for {@link #variant} ≡ true e(P)∙e(Q)∙e(R) ≡ 1 *
  • for {@link #variant} ≡ false e(P)∙e(Q)∙e(R)∙e(S) ≡ 1 * - *
  • τ is a {@link SmallPointCandidate} which will vary - *
  • θ is a {@link LargePointCandidate} which will vary + *
  • τ is a {@link SmallPoint} which will vary + *
  • θ is a {@link LargePoint} which will vary * * * Note. The CENTER_PAIR is the only component in this setup which may cause failure @@ -52,11 +51,12 @@ * range. */ public class MemoryContents implements PrecompileCallMemoryContents { - private final int NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY = 12; + public static final int TOTAL_NUMBER_OF_PAIRS_OF_POINTS = 12; + public static final int SIZE_OF_PAIR_OF_POINTS = 192; private final String RETURN_DATA_STRIP = "ff".repeat(WORD_SIZE); - public final SmallPointCandidate small; - public final LargePointCandidate large; + public final SmallPoint small; + public final LargePoint large; public boolean centerPairIsValid() { return small.isValid() && large.isValid(); @@ -66,7 +66,7 @@ public boolean centerPairIsInconsequential() { return centerPairIsValid() && (small.isInfinity() || large.isInfinity()); } - public MemoryContents(SmallPointCandidate small, LargePointCandidate large) { + public MemoryContents(SmallPoint small, LargePoint large) { this.small = small; this.large = large; } @@ -84,7 +84,8 @@ public BytecodeCompiler memoryContents() { Bytes.fromHexString(leftPairs() + CenterPair() + rightPairs() + RETURN_DATA_STRIP); // TODO: replace 192 with the appropriate constant (maybe add to GlobalConstants) checkState( - memoryContentsBytes.size() == NUMBER_OF_PAIRS_OF_POINTS_IN_MEMORY * 192 + WORD_SIZE * 2); + memoryContentsBytes.size() + == TOTAL_NUMBER_OF_PAIRS_OF_POINTS * SIZE_OF_PAIR_OF_POINTS + WORD_SIZE * 2); BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); return memoryContents.immediate(memoryContentsBytes); @@ -217,9 +218,6 @@ private String rightPairs() { @Override public String toString() { - return "MemoryContents{" + - "small=" + small + - ", large=" + large + - '}'; + return "MemoryContents{" + "small=" + small + ", large=" + large + '}'; } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java index 98ab8f5aff..9c8f7fd7ab 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java @@ -13,5 +13,81 @@ * SPDX-License-Identifier: Apache-2.0 */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.PLENTY; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter.*; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; +import static net.consensys.linea.zktracer.opcode.OpCode.*; +import static net.consensys.linea.zktracer.opcode.OpCode.STATICCALL; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.opcode.OpCode; +import org.junit.jupiter.params.provider.Arguments; + public class ParameterGeneration { + + public static Stream parameterGeneration() { + List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); + List GasParameters = List.of(ZERO, COST_MO, COST, PLENTY); + List ReturnAtParameters = List.of(EMPTY, PARTIAL, FULL); + + List argumentsList = new ArrayList<>(); + + for (OpCode opCode : CallOpCodes) { // 4 + for (GasParameter gas : GasParameters) { // 4 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + + // empty call data cases + argumentsList.add( + Arguments.of( + new CallParameters( + opCode, + gas, + new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + new CallDataRange(), + returnAt, + true))); + + argumentsList.add( + Arguments.of( + new CallParameters( + opCode, + gas, + new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + new CallDataRange(), + returnAt, + false))); + for (int i = 0; i < TOTAL_NUMBER_OF_PAIRS_OF_POINTS; i++) { + for (int j = i; j < TOTAL_NUMBER_OF_PAIRS_OF_POINTS; j++) { + CallDataRange callDataRange = new CallDataRange(i, j); + for (SmallPoint small : SmallPoint.values()) { + for (LargePoint large : LargePoint.values()) { + + MemoryContents memoryContent = new MemoryContents(small, large); + + // nonempty call data cases + argumentsList.add( + Arguments.of( + new CallParameters( + opCode, gas, memoryContent, callDataRange, returnAt, true))); + + argumentsList.add( + Arguments.of( + new CallParameters( + opCode, gas, memoryContent, callDataRange, returnAt, false))); + } + } + } + } + } + } + } + return argumentsList.stream(); + } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java index e6a0d53d00..a20412c0d0 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java @@ -20,7 +20,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.C1_POINT_4; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -public enum SmallPointCandidate { +public enum SmallPoint { // valid points INFINITY, VALID_SMALL_POINT, diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java index e4f42d3362..51a2b8b2d3 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java @@ -13,5 +13,32 @@ * SPDX-License-Identifier: Apache-2.0 */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; + +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.provider.Arguments; + +import java.util.stream.Stream; + +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; +import static net.consensys.linea.zktracer.opcode.OpCode.CALL; + public class Tests { + + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } + + @Test + public void singleMessageCallTransactionTest() { + new CallParameters( + CALL, + COST, + new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), + ReturnAtParameter.FULL, + true); + ); + } } From 4a0f4137716d5c68ba1014eab0cfa83627c26532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 16:18:03 +0100 Subject: [PATCH 50/57] wip ECPAIRING (nearly there) --- .../prc/ecpairing/CallDataRange.java | 7 ++- .../callTests/prc/ecpairing/Tests.java | 53 +++++++++++-------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java index a05ad3eecc..9740393aa1 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java @@ -23,7 +23,8 @@ public class CallDataRange { public boolean isEmpty = false; public CallDataRange(int firstPoint, int finalPoint) { - checkArgument(finalPoint >= firstPoint, "final point must be greater than or equal to first point"); + checkArgument( + finalPoint >= firstPoint, "final point must be greater than or equal to first point"); this.firstPoint = firstPoint; this.finalPoint = finalPoint; } @@ -47,9 +48,7 @@ public int finalPoint() { } public int numberOfPairsOfPoints() { - return isEmpty() - ? 0 - : (finalPoint() - firstPoint() + 1); + return isEmpty() ? 0 : (finalPoint() - firstPoint() + 1); } @Override diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java index 51a2b8b2d3..0f1dd560d6 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java @@ -14,31 +14,42 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.revertWith; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.runMessageCallTransactionWithProvidedCodeAsRootCode; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; +import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; +import static net.consensys.linea.zktracer.opcode.OpCode.CALL; + +import java.util.stream.Stream; + +import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; +import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; -import java.util.stream.Stream; +@Tag("weekly") +public class Tests extends PrecompileCallTests { -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; -import static net.consensys.linea.zktracer.opcode.OpCode.CALL; + public static Stream parameterGeneration() { + return ParameterGeneration.parameterGeneration(); + } + + @Test + public void singleMessageCallTransactionTest() { + CallParameters params = new CallParameters( + CALL, + COST, + new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), + ReturnAtParameter.FULL, + true); + + BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); -public class Tests { - - public static Stream parameterGeneration() { - return ParameterGeneration.parameterGeneration(); - } - - @Test - public void singleMessageCallTransactionTest() { - new CallParameters( - CALL, - COST, - new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), - new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), - ReturnAtParameter.FULL, - true); - ); - } + runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + } } From ae627783dea83f8a2734e25a237643e6d4b7637d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 16:18:35 +0100 Subject: [PATCH 51/57] spotless --- .../callTests/prc/ecpairing/Tests.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java index 0f1dd560d6..53df82f784 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java @@ -39,13 +39,14 @@ public static Stream parameterGeneration() { @Test public void singleMessageCallTransactionTest() { - CallParameters params = new CallParameters( - CALL, - COST, - new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), - new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), - ReturnAtParameter.FULL, - true); + CallParameters params = + new CallParameters( + CALL, + COST, + new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), + ReturnAtParameter.FULL, + true); BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); From ed7439007c0bac56245fdd8c4e163d3faf1cb8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 16:55:45 +0100 Subject: [PATCH 52/57] ECPAIRING ok + various --- .../callTests/prc/ecadd/ParameterGeneration.java | 2 +- .../callTests/prc/ecpairing/LargePoint.java | 3 ++- .../callTests/prc/ecpairing/MemoryContents.java | 2 +- .../callTests/prc/ecpairing/SmallPoint.java | 5 ++++- .../callTests/prc/ecrecover/CallParameters.java | 2 +- .../callTests/prc/ecrecover/ParameterGeneration.java | 2 +- .../callTests/prc/hash/CallParameters.java | 4 ++-- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java index 37da6fc41d..ee6839ce44 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecadd/ParameterGeneration.java @@ -55,7 +55,7 @@ public class ParameterGeneration { public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); List GasParameters = - List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.FULL); + List.of(GasParameter.ZERO, GasParameter.COST_MO, GasParameter.COST, GasParameter.PLENTY); List ReturnAtParameters = List.of(ReturnAtParameter.EMPTY, ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java index 0241999abc..e587adc36c 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java @@ -18,6 +18,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; +import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPoint.RANDOM_HEX_STRING; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; public enum LargePoint { @@ -48,7 +49,7 @@ public String hexString() { switch (this) { case INFINITY -> LARGE_POINT_AT_INFINITY; case VALID_LARGE_POINT -> G2_POINT_5; - case RAND -> RND.substring(36, 36 + 4 * WORD_HEX_SIZE); + case RAND -> RANDOM_HEX_STRING.substring(31, 31 + 4 * WORD_HEX_SIZE); case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java index 30f6bbd46e..636eaf24d2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/MemoryContents.java @@ -85,7 +85,7 @@ public BytecodeCompiler memoryContents() { // TODO: replace 192 with the appropriate constant (maybe add to GlobalConstants) checkState( memoryContentsBytes.size() - == TOTAL_NUMBER_OF_PAIRS_OF_POINTS * SIZE_OF_PAIR_OF_POINTS + WORD_SIZE * 2); + == TOTAL_NUMBER_OF_PAIRS_OF_POINTS * SIZE_OF_PAIR_OF_POINTS + WORD_SIZE); BytecodeCompiler memoryContents = BytecodeCompiler.newProgram(); return memoryContents.immediate(memoryContentsBytes); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java index a20412c0d0..fe1f9b6b5b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java @@ -46,7 +46,7 @@ public String hexString() { case X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_X; case Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_Y; case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; - case RAND -> RND.substring(147, 147 + 2 * WORD_HEX_SIZE); + case RAND -> RANDOM_HEX_STRING.substring(131, 131 + 2 * WORD_HEX_SIZE); default -> throw new IllegalArgumentException("Invalid point candidate"); }; checkState(result.length() == 2 * WORD_HEX_SIZE, "Invalid hex string length"); @@ -67,4 +67,7 @@ public String hexString() { public static final String IN_RANGE_BUT_NOT_ON_CURVE = "1dac6eed25388228c5542dfc2c0b30bd5afbb4fb091791052ad8ca6a8e1c94fb" + "0b35150d9fe2b8cff4e81fd7445b6d529f68ca798d16618adf0f1d319e772987"; + + public static final String RANDOM_HEX_STRING = + "5b715e0b8ee221775e11207b0e08b43ac5c2005a980303465dd90d321499242d6245977f7b7b2cbfe4275637425e058731b66ab18907df88f3e76e207ede232238443a4e0f7dd7f72381ecb6005f4ca18ed70e5773c511568ad10dbf079f4f4b39e0265c45f23e3d8aaa6bd1119a63663af56960cf29c5af84b419a5f3c61fe1acba71b7b83528c3d35053516b4ed779638c2b3c82b07f0755d488e635a84d925eab59be05280155242d2481493d0ab85bbe1386328b54893149b2c02c2ac61a9397b12318adcc280249e8b8e2eb8ca8b06c41abd89efa24ef836b38a686e5242cd98fa00fec1500ac439697e38b79293c580bf731f273dd8b3e16a0c37db08b14436f9c0d009a81fca876bf0e08fd60cbcde26f2caeea76e135015d48d20813d15979b635a3173ecc3fae9c6a1f3edc38537a12327a1a79f38d8bba974ec7279504762c2a86f21015e20e1ff21c601896c232b1fdc998df42f71cd6863c3c7eb7fe8867fc531a817873892e6793f42ad6a37f3148cb34dd8bc05b83296ea9c7b5199dbb498cc11dea8444823f51c553725516adb00d63b20aa09ba2c445aee03484765c95b8b1969dc0688bec46594b43b3d4636f79da7fd0d03256249d8ae9a1b3ba040a242dfc11b93994503afbb9e7dcec5982c8e75346cbb0fc07afd992e5659a570ebedbcdd4bdd5f52db9b823c5a2a974ba97fc036f3cbaf7aeaeebe0"; } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java index bc580d94ed..a3930c8a70 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/CallParameters.java @@ -94,7 +94,7 @@ public void appendCustomPrecompileCall(BytecodeCompiler program) { case ZERO -> program.push(0); // interesting in the nonzero value case case COST_MO -> program.push(3000 - callStipend - 1); case COST -> program.push(3000 - callStipend); - case FULL -> program.op(GAS); + case PLENTY -> program.push(2).op(GAS).op(DIV); // half of gas default -> throw new RuntimeException("Unsupported gas parameter"); } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java index ba2d8f6ad0..d367ae4491 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecrecover/ParameterGeneration.java @@ -30,7 +30,7 @@ public class ParameterGeneration { public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - List GasParameters = List.of(ZERO, COST_MO, COST, FULL); + List GasParameters = List.of(ZERO, COST_MO, COST, PLENTY); List ReturnAtParameters = List.of(ReturnAtParameter.PARTIAL, ReturnAtParameter.FULL); diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java index 1de56bd481..6f72d3a8cd 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/hash/CallParameters.java @@ -16,7 +16,7 @@ import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.RelativeRangePosition.OVERLAP; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.GAS; +import static net.consensys.linea.zktracer.opcode.OpCode.*; import net.consensys.linea.testing.BytecodeCompiler; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.*; @@ -126,7 +126,7 @@ public void appendCustomPrecompileCall(BytecodeCompiler program) { case ZERO -> program.push(0); case COST_MO -> program.push(cost - 1); case COST -> program.push(cost); - case FULL -> program.op(GAS); + case PLENTY -> program.push(2).op(GAS).op(DIV); // half of gas case MAX -> program.push("ff".repeat(32)); } From a4f5162042f15546f4e906e67c643b82aa9ec9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 19:46:00 +0100 Subject: [PATCH 53/57] feat: fewer test cases still far too many it seems --- .../callTests/prc/ecpairing/CallDataRange.java | 2 +- .../callTests/prc/ecpairing/LargePoint.java | 6 ++---- .../callTests/prc/ecpairing/ParameterGeneration.java | 8 ++++---- .../callTests/prc/ecpairing/SmallPoint.java | 6 +++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java index 9740393aa1..b403644a8f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/CallDataRange.java @@ -53,6 +53,6 @@ public int numberOfPairsOfPoints() { @Override public String toString() { - return "CallDataRange{" + "first point=" + firstPoint + ", final point=" + finalPoint + '}'; + return "{" + "first point=" + firstPoint + ", final point=" + finalPoint + '}'; } } diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java index e587adc36c..95567aad2d 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java @@ -15,10 +15,8 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.G2_POINT_5; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.SmallPoint.RANDOM_HEX_STRING; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; public enum LargePoint { @@ -26,7 +24,7 @@ public enum LargePoint { INFINITY, VALID_LARGE_POINT, // invalid points - RAND, + // RAND, RE_X_NOT_IN_FIELD, IM_X_NOT_IN_FIELD, RE_Y_NOT_IN_FIELD, @@ -49,7 +47,7 @@ public String hexString() { switch (this) { case INFINITY -> LARGE_POINT_AT_INFINITY; case VALID_LARGE_POINT -> G2_POINT_5; - case RAND -> RANDOM_HEX_STRING.substring(31, 31 + 4 * WORD_HEX_SIZE); + // case RAND -> RANDOM_HEX_STRING.substring(31, 31 + 4 * WORD_HEX_SIZE); case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java index 9c8f7fd7ab..822412e9b2 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/ParameterGeneration.java @@ -34,14 +34,14 @@ public class ParameterGeneration { public static Stream parameterGeneration() { List CallOpCodes = List.of(CALL, CALLCODE, DELEGATECALL, STATICCALL); - List GasParameters = List.of(ZERO, COST_MO, COST, PLENTY); - List ReturnAtParameters = List.of(EMPTY, PARTIAL, FULL); + List GasParameters = List.of(COST_MO, COST, PLENTY); + List ReturnAtParameters = List.of(PARTIAL, FULL); List argumentsList = new ArrayList<>(); for (OpCode opCode : CallOpCodes) { // 4 - for (GasParameter gas : GasParameters) { // 4 - for (ReturnAtParameter returnAt : ReturnAtParameters) { // 3 + for (GasParameter gas : GasParameters) { // 3 + for (ReturnAtParameter returnAt : ReturnAtParameters) { // 2 // empty call data cases argumentsList.add( diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java index fe1f9b6b5b..d1e60f377f 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java @@ -25,10 +25,10 @@ public enum SmallPoint { INFINITY, VALID_SMALL_POINT, // invalid points + // RAND, X_NOT_IN_FIELD, Y_NOT_IN_FIELD, - NOT_ON_CURVE, - RAND; + NOT_ON_CURVE; public boolean isValid() { return this == INFINITY || this == VALID_SMALL_POINT; @@ -46,7 +46,7 @@ public String hexString() { case X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_X; case Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_Y; case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; - case RAND -> RANDOM_HEX_STRING.substring(131, 131 + 2 * WORD_HEX_SIZE); + // case RAND -> RANDOM_HEX_STRING.substring(131, 131 + 2 * WORD_HEX_SIZE); default -> throw new IllegalArgumentException("Invalid point candidate"); }; checkState(result.length() == 2 * WORD_HEX_SIZE, "Invalid hex string length"); From b84cb3d9e067ab4b029b1da599fcb4c22d3dbc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 22:28:50 +0100 Subject: [PATCH 54/57] ras --- .../callTests/prc/ecpairing/LargePoint.java | 2 +- .../callTests/prc/ecpairing/SmallPoint.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java index 95567aad2d..c06609b11b 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/LargePoint.java @@ -47,7 +47,7 @@ public String hexString() { switch (this) { case INFINITY -> LARGE_POINT_AT_INFINITY; case VALID_LARGE_POINT -> G2_POINT_5; - // case RAND -> RANDOM_HEX_STRING.substring(31, 31 + 4 * WORD_HEX_SIZE); + // case RAND -> RANDOM_HEX_STRING.substring(31, 31 + 4 * WORD_HEX_SIZE); case RE_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_X; case IM_X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_IM_X; case RE_Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_RE_Y; diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java index d1e60f377f..b939915e97 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/SmallPoint.java @@ -15,7 +15,6 @@ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; import static com.google.common.base.Preconditions.checkState; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.RND; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecadd.MemoryContents.WORD_HEX_SIZE; import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.C1_POINT_4; import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; @@ -46,7 +45,7 @@ public String hexString() { case X_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_X; case Y_NOT_IN_FIELD -> IN_RANGE_SAVE_FOR_LARGE_Y; case NOT_ON_CURVE -> IN_RANGE_BUT_NOT_ON_CURVE; - // case RAND -> RANDOM_HEX_STRING.substring(131, 131 + 2 * WORD_HEX_SIZE); + // case RAND -> RANDOM_HEX_STRING.substring(131, 131 + 2 * WORD_HEX_SIZE); default -> throw new IllegalArgumentException("Invalid point candidate"); }; checkState(result.length() == 2 * WORD_HEX_SIZE, "Invalid hex string length"); @@ -69,5 +68,5 @@ public String hexString() { + "0b35150d9fe2b8cff4e81fd7445b6d529f68ca798d16618adf0f1d319e772987"; public static final String RANDOM_HEX_STRING = - "5b715e0b8ee221775e11207b0e08b43ac5c2005a980303465dd90d321499242d6245977f7b7b2cbfe4275637425e058731b66ab18907df88f3e76e207ede232238443a4e0f7dd7f72381ecb6005f4ca18ed70e5773c511568ad10dbf079f4f4b39e0265c45f23e3d8aaa6bd1119a63663af56960cf29c5af84b419a5f3c61fe1acba71b7b83528c3d35053516b4ed779638c2b3c82b07f0755d488e635a84d925eab59be05280155242d2481493d0ab85bbe1386328b54893149b2c02c2ac61a9397b12318adcc280249e8b8e2eb8ca8b06c41abd89efa24ef836b38a686e5242cd98fa00fec1500ac439697e38b79293c580bf731f273dd8b3e16a0c37db08b14436f9c0d009a81fca876bf0e08fd60cbcde26f2caeea76e135015d48d20813d15979b635a3173ecc3fae9c6a1f3edc38537a12327a1a79f38d8bba974ec7279504762c2a86f21015e20e1ff21c601896c232b1fdc998df42f71cd6863c3c7eb7fe8867fc531a817873892e6793f42ad6a37f3148cb34dd8bc05b83296ea9c7b5199dbb498cc11dea8444823f51c553725516adb00d63b20aa09ba2c445aee03484765c95b8b1969dc0688bec46594b43b3d4636f79da7fd0d03256249d8ae9a1b3ba040a242dfc11b93994503afbb9e7dcec5982c8e75346cbb0fc07afd992e5659a570ebedbcdd4bdd5f52db9b823c5a2a974ba97fc036f3cbaf7aeaeebe0"; + "5b715e0b8ee221775e11207b0e08b43ac5c2005a980303465dd90d321499242d6245977f7b7b2cbfe4275637425e058731b66ab18907df88f3e76e207ede232238443a4e0f7dd7f72381ecb6005f4ca18ed70e5773c511568ad10dbf079f4f4b39e0265c45f23e3d8aaa6bd1119a63663af56960cf29c5af84b419a5f3c61fe1acba71b7b83528c3d35053516b4ed779638c2b3c82b07f0755d488e635a84d925eab59be05280155242d2481493d0ab85bbe1386328b54893149b2c02c2ac61a9397b12318adcc280249e8b8e2eb8ca8b06c41abd89efa24ef836b38a686e5242cd98fa00fec1500ac439697e38b79293c580bf731f273dd8b3e16a0c37db08b14436f9c0d009a81fca876bf0e08fd60cbcde26f2caeea76e135015d48d20813d15979b635a3173ecc3fae9c6a1f3edc38537a12327a1a79f38d8bba974ec7279504762c2a86f21015e20e1ff21c601896c232b1fdc998df42f71cd6863c3c7eb7fe8867fc531a817873892e6793f42ad6a37f3148cb34dd8bc05b83296ea9c7b5199dbb498cc11dea8444823f51c553725516adb00d63b20aa09ba2c445aee03484765c95b8b1969dc0688bec46594b43b3d4636f79da7fd0d03256249d8ae9a1b3ba040a242dfc11b93994503afbb9e7dcec5982c8e75346cbb0fc07afd992e5659a570ebedbcdd4bdd5f52db9b823c5a2a974ba97fc036f3cbaf7aeaeebe0"; } From 41513c0846255203c7fb13ceb9b76281a3be36dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 22:28:58 +0100 Subject: [PATCH 55/57] constraints commit update --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index c7fabb54e3..e8352b388f 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit c7fabb54e3fd6e868a638cdc05efc85ca927b944 +Subproject commit e8352b388f790328c568b4424db8080155dc0559 From 6a43edf2a7b20ea7fa3f8d1954e8af3c687cb723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Sat, 22 Feb 2025 22:55:55 +0100 Subject: [PATCH 56/57] constraints commit update (again) --- linea-constraints | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linea-constraints b/linea-constraints index e8352b388f..20bdc815f0 160000 --- a/linea-constraints +++ b/linea-constraints @@ -1 +1 @@ -Subproject commit e8352b388f790328c568b4424db8080155dc0559 +Subproject commit 20bdc815f048584bec05cbff7ee31000120e7715 From 48d5dbca04b91e5fde6778c52782ca70618e04b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20B=C3=A9gassat?= Date: Mon, 24 Feb 2025 13:36:34 +0100 Subject: [PATCH 57/57] feat: disable ECPAIRING tests + reduce GOMEMLIMIT --- .github/workflows/gradle-weekly-tests.yml | 2 +- .../callTests/prc/ecpairing/Tests.java | 43 ++++++++----------- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/.github/workflows/gradle-weekly-tests.yml b/.github/workflows/gradle-weekly-tests.yml index e17ac0b664..25a63ed091 100644 --- a/.github/workflows/gradle-weekly-tests.yml +++ b/.github/workflows/gradle-weekly-tests.yml @@ -26,7 +26,7 @@ jobs: go-corset: true - name: Run Weekly tests - run: GOMEMLIMIT=96GiB ./gradlew weeklyTests + run: GOMEMLIMIT=20GiB ./gradlew weeklyTests env: JAVA_OPTS: -Dorg.gradle.daemon=false WEEKLY_TESTS_PARALLELISM: 4 diff --git a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java index 53df82f784..6dc7d54b46 100644 --- a/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java +++ b/arithmetization/src/test/java/net/consensys/linea/zktracer/instructionprocessing/callTests/prc/ecpairing/Tests.java @@ -14,43 +14,34 @@ */ package net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.Utilities.revertWith; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.CodeExecutionMethods.runMessageCallTransactionWithProvidedCodeAsRootCode; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.GasParameter.COST; -import static net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ecpairing.MemoryContents.TOTAL_NUMBER_OF_PAIRS_OF_POINTS; -import static net.consensys.linea.zktracer.module.constants.GlobalConstants.WORD_SIZE; -import static net.consensys.linea.zktracer.opcode.OpCode.CALL; - import java.util.stream.Stream; -import net.consensys.linea.testing.BytecodeCompiler; -import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.ReturnAtParameter; import net.consensys.linea.zktracer.instructionprocessing.callTests.prc.framework.PrecompileCallTests; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.provider.Arguments; @Tag("weekly") +@Disabled public class Tests extends PrecompileCallTests { public static Stream parameterGeneration() { return ParameterGeneration.parameterGeneration(); } - @Test - public void singleMessageCallTransactionTest() { - CallParameters params = - new CallParameters( - CALL, - COST, - new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), - new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), - ReturnAtParameter.FULL, - true); - - BytecodeCompiler rootCode = params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); - if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); - - runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); - } + // @Test + // public void singleMessageCallTransactionTest() { + // CallParameters params = + // new CallParameters( + // CALL, + // COST, + // new MemoryContents(SmallPoint.INFINITY, LargePoint.INFINITY), + // new CallDataRange(0, TOTAL_NUMBER_OF_PAIRS_OF_POINTS - 1), + // ReturnAtParameter.FULL, + // true); + // BytecodeCompiler rootCode = + // params.customPrecompileCallsSeparatedByReturnDataWipingOperation(); + // if (params.willRevert()) revertWith(rootCode, 3 * WORD_SIZE, 2 * WORD_SIZE); + // runMessageCallTransactionWithProvidedCodeAsRootCode(rootCode); + // } }