diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/container/module/OperationSetModule.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/container/module/OperationSetModule.java index 1d27194ba..647c87374 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/container/module/OperationSetModule.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/container/module/OperationSetModule.java @@ -15,6 +15,9 @@ package net.consensys.linea.zktracer.container.module; +import java.util.Comparator; +import java.util.List; + import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.container.stacked.ModuleOperationStackedSet; import org.hyperledger.besu.evm.worldstate.WorldView; @@ -46,4 +49,8 @@ default int lineCount() { default void traceEndConflation(final WorldView state) { operations().finishConflation(); } + + default List sortOperations(Comparator comparator) { + return operations().sortOperations(comparator); + } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/container/stacked/ModuleOperationStackedSet.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/container/stacked/ModuleOperationStackedSet.java index d8eabe6ac..e4b7df557 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/container/stacked/ModuleOperationStackedSet.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/container/stacked/ModuleOperationStackedSet.java @@ -15,7 +15,10 @@ package net.consensys.linea.zktracer.container.stacked; +import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; +import java.util.List; import java.util.Set; import com.google.common.base.Preconditions; @@ -135,4 +138,10 @@ public void finishConflation() { operationsInTransaction().clear(); lineCounter.enter(); // this is not mandatory but it is more consistent } + + public List sortOperations(Comparator comparator) { + final List sortedOperations = new ArrayList<>(getAll()); + sortedOperations.sort(comparator); + return sortedOperations; + } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/Add.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/Add.java index aa6cb50ea..651b08a1e 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/Add.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/Add.java @@ -62,7 +62,7 @@ public List columnsHeaders() { public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (AddOperation op : operations.getAll()) { + for (AddOperation op : sortOperations(new AddOperationComparator())) { op.trace(++stamp, trace); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperation.java index 0ceb2c48e..ae42c7bba 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperation.java @@ -18,6 +18,8 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.bytestheta.BaseBytes; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.opcode.OpCode; @@ -27,13 +29,14 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public final class AddOperation extends ModuleOperation { private static final UInt256 TWO_TO_THE_128 = UInt256.ONE.shiftLeft(128); - @EqualsAndHashCode.Include private final OpCode opCode; - @EqualsAndHashCode.Include private final Bytes32 arg1; - @EqualsAndHashCode.Include private final Bytes32 arg2; + @EqualsAndHashCode.Include @Getter private final OpCode opCode; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg1; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg2; private BaseBytes res; private int ctMax; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperationComparator.java new file mode 100644 index 000000000..894b0aed6 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/add/AddOperationComparator.java @@ -0,0 +1,35 @@ +/* + * Copyright ConsenSys 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.add; + +import java.util.Comparator; + +public class AddOperationComparator implements Comparator { + public int compare(AddOperation op1, AddOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.arg1().compareTo(op2.arg1()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + return op1.arg2().compareTo(op2.arg2()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/Bin.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/Bin.java index 98e332f30..8c811f78f 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/Bin.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/Bin.java @@ -60,7 +60,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (BinOperation op : operations.getAll()) { + for (BinOperation op : operations.sortOperations(new BinOperationComparator())) { op.traceBinOperation(++stamp, trace); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/BinOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/BinOperationComparator.java new file mode 100644 index 000000000..6f1963266 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/bin/BinOperationComparator.java @@ -0,0 +1,35 @@ +/* + * Copyright ConsenSys 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.bin; + +import java.util.Comparator; + +public class BinOperationComparator implements Comparator { + public int compare(BinOperation op1, BinOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.arg1().getBytes32().compareTo(op2.arg1().getBytes32()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + return op1.arg2().getBytes32().compareTo(op2.arg2().getBytes32()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/blockhash/Blockhash.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/blockhash/Blockhash.java index ca7dadc2b..56df897b9 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/blockhash/Blockhash.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/blockhash/Blockhash.java @@ -20,7 +20,6 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.LLARGE; import java.nio.MappedByteBuffer; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -87,19 +86,19 @@ public void tracePreOpcode(MessageFrame frame) { opcodeArgument = Bytes32.leftPad(frame.getStackItem(0)); lowerBound = - this.wcp.callGEQ( - opcodeArgument, Bytes.ofUnsignedLong(this.absoluteBlockNumber - BLOCKHASH_MAX_HISTORY)); - upperBound = this.wcp.callLT(opcodeArgument, Bytes.ofUnsignedLong(this.absoluteBlockNumber)); + wcp.callGEQ( + opcodeArgument, Bytes.ofUnsignedLong(absoluteBlockNumber - BLOCKHASH_MAX_HISTORY)); + upperBound = wcp.callLT(opcodeArgument, Bytes.ofUnsignedLong(absoluteBlockNumber)); hub.defers().scheduleForPostExecution(this); /* To prove the lex order of BLOCK_NUMBER_HI/LO, we call WCP at endConflation, so we need to add rows in WCP now. If a BLOCK_NUMBER is already called at least two times, no need for additional rows in WCP*/ - final int numberOfCall = this.numberOfCall.getOrDefault(this.opcodeArgument, 0); + final int numberOfCall = this.numberOfCall.getOrDefault(opcodeArgument, 0); if (numberOfCall < 2) { wcp.additionalRows.add( - Math.max(Math.min(LLARGE, this.opcodeArgument.trimLeadingZeros().size()), 1)); - this.numberOfCall.replace(this.opcodeArgument, numberOfCall, numberOfCall + 1); + Math.max(Math.min(LLARGE, opcodeArgument.trimLeadingZeros().size()), 1)); + this.numberOfCall.replace(opcodeArgument, numberOfCall, numberOfCall + 1); } } @@ -111,14 +110,9 @@ public void resolvePostExecution( final Bytes32 result = Bytes32.leftPad(frame.getStackItem(0)); operations.add( new BlockhashOperation( - this.relativeBlock, - this.opcodeArgument, - this.absoluteBlockNumber, - lowerBound, - upperBound, - result)); + relativeBlock, opcodeArgument, absoluteBlockNumber, lowerBound, upperBound, result)); if (result != Bytes32.ZERO) { - blockHashMap.put(this.opcodeArgument, result); + blockHashMap.put(opcodeArgument, result); } } } @@ -126,10 +120,8 @@ public void resolvePostExecution( @Override public void traceEndConflation(WorldView state) { OperationSetModule.super.traceEndConflation(state); - sortedOperations = new ArrayList<>(operations.getAll()); + sortedOperations = sortOperations(new BlockhashComparator()); if (!sortedOperations.isEmpty()) { - final BlockhashComparator BLOCKHASH_COMPARATOR = new BlockhashComparator(); - sortedOperations.sort(BLOCKHASH_COMPARATOR); wcp.callGEQ(sortedOperations.getFirst().opcodeArgument(), Bytes32.ZERO); for (int i = 1; i < sortedOperations.size(); i++) { wcp.callGEQ( diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/Euc.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/Euc.java index 09396c99d..3ad5932b2 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/Euc.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/Euc.java @@ -52,7 +52,7 @@ public List columnsHeaders() { @Override public void commit(List buffers) { final Trace trace = new Trace(buffers); - for (EucOperation eucOperation : operations.getAll()) { + for (EucOperation eucOperation : operations.sortOperations(new EucOperationComparator())) { eucOperation.trace(trace); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/EucOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/EucOperationComparator.java new file mode 100644 index 000000000..51e078b6d --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/euc/EucOperationComparator.java @@ -0,0 +1,31 @@ +/* + * Copyright ConsenSys 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.euc; + +import java.util.Comparator; + +public class EucOperationComparator implements Comparator { + public int compare(EucOperation op1, EucOperation op2) { + // Second sort by Dividend + final int arg1Comp = op1.dividend().compareTo(op2.dividend()); + if (arg1Comp != 0) { + return arg1Comp; + } else { + // Second, sort by Divisor + return op1.divisor().compareTo(op2.divisor()); + } + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/Exp.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/Exp.java index 61e9a317d..bd0ecc097 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/Exp.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/Exp.java @@ -59,7 +59,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (ExpOperation expOp : operations.getAll()) { + for (ExpOperation expOp : operations.sortOperations(new ExpOperationComparator())) { expOp.traceComputation(++stamp, trace); expOp.traceMacro(stamp, trace); expOp.tracePreprocessing(stamp, trace); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperation.java index c813236e5..32dc2d806 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperation.java @@ -36,6 +36,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.module.constants.GlobalConstants; import net.consensys.linea.zktracer.module.hub.Hub; @@ -48,7 +49,9 @@ import net.consensys.linea.zktracer.types.UnsignedByte; import org.apache.tuweni.bytes.Bytes; +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) @Getter +@Accessors(fluent = true) public class ExpOperation extends ModuleOperation { @EqualsAndHashCode.Include ExpCall expCall; @@ -90,8 +93,8 @@ public ExpOperation(ExpCall expCall, Wcp wcp, Hub hub) { long dynCost = (long) GlobalConstants.GAS_CONST_G_EXP_BYTE * exponent.byteLength(); // Fill expCall - explogExpCall.setExponent(exponent); - explogExpCall.setDynCost(dynCost); + explogExpCall.exponent(exponent); + explogExpCall.dynCost(dynCost); // Execute preprocessing preComputeForExplog(explogExpCall); @@ -100,7 +103,7 @@ public ExpOperation(ExpCall expCall, Wcp wcp, Hub hub) { ModexpLogExpCall modexplogExpCall = (ModexpLogExpCall) expCall; // Extract inputs - ModexpMetadata modexpMetadata = modexplogExpCall.getModexpMetadata(); + final ModexpMetadata modexpMetadata = modexplogExpCall.getModexpMetadata(); final int bbsInt = modexpMetadata.bbs().toUnsignedBigInteger().intValueExact(); final int ebsInt = modexpMetadata.ebs().toUnsignedBigInteger().intValueExact(); checkArgument(modexpMetadata.callData().size() - 96 - bbsInt >= 0); @@ -123,28 +126,28 @@ public ExpOperation(ExpCall expCall, Wcp wcp, Hub hub) { public void preComputeForExplog(ExplogExpCall explogExpCall) { pMacroExpInst = EXP_INST_EXPLOG; - pMacroData1 = explogExpCall.getExponent().hi(); - pMacroData2 = explogExpCall.getExponent().lo(); - pMacroData5 = Bytes.ofUnsignedLong(explogExpCall.getDynCost()); + pMacroData1 = explogExpCall.exponent().hi(); + pMacroData2 = explogExpCall.exponent().lo(); + pMacroData5 = Bytes.ofUnsignedLong(explogExpCall.dynCost()); initArrays(CT_MAX_PRPRC_EXP_LOG + 1); // Preprocessing // First row pPreprocessingWcpFlag[0] = true; pPreprocessingWcpArg1Hi[0] = Bytes.EMPTY; - pPreprocessingWcpArg1Lo[0] = explogExpCall.getExponent().hi(); + pPreprocessingWcpArg1Lo[0] = explogExpCall.exponent().hi(); pPreprocessingWcpArg2Hi[0] = Bytes.EMPTY; pPreprocessingWcpArg2Lo[0] = Bytes.EMPTY; pPreprocessingWcpInst[0] = UnsignedByte.of(EVM_INST_ISZERO); - final boolean expnHiIsZero = wcp.callISZERO(explogExpCall.getExponent().hi()); + final boolean expnHiIsZero = wcp.callISZERO(explogExpCall.exponent().hi()); ; pPreprocessingWcpRes[0] = expnHiIsZero; // Linking constraints and fill rawAcc pComputationPltJmp = 16; - pComputationRawAcc = explogExpCall.getExponent().hi(); + pComputationRawAcc = explogExpCall.exponent().hi(); if (expnHiIsZero) { - pComputationRawAcc = explogExpCall.getExponent().lo(); + pComputationRawAcc = explogExpCall.exponent().lo(); } // Fill trimAcc diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperationComparator.java new file mode 100644 index 000000000..a4d0325ae --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/exp/ExpOperationComparator.java @@ -0,0 +1,31 @@ +/* + * Copyright ConsenSys 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.exp; + +import java.util.Comparator; + +public class ExpOperationComparator implements Comparator { + @Override + public int compare(ExpOperation op1, ExpOperation op2) { + final int instructionComp = + Integer.compare(op1.expCall().expInstruction(), op2.expCall().expInstruction()); + if (instructionComp != 0) { + return instructionComp; + } + + return op1.expCall.compareTo(op2.expCall); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/Ext.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/Ext.java index bbf6402c2..d46733652 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/Ext.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/Ext.java @@ -84,7 +84,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (ExtOperation operation : operations.getAll()) { + for (ExtOperation operation : operations.sortOperations(new ExtOperationComparator())) { operation.trace(trace, ++stamp); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java index aaa12d53e..e64e04d6d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperation.java @@ -19,6 +19,8 @@ import static net.consensys.linea.zktracer.module.constants.GlobalConstants.MMEDIUM; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.bytestheta.BaseBytes; import net.consensys.linea.zktracer.bytestheta.BaseTheta; import net.consensys.linea.zktracer.bytestheta.BytesArray; @@ -30,13 +32,14 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class ExtOperation extends ModuleOperation { - @EqualsAndHashCode.Include private final OpCode opCode; - @EqualsAndHashCode.Include private final BaseBytes arg1; - @EqualsAndHashCode.Include private final BaseBytes arg2; - @EqualsAndHashCode.Include private final BaseBytes arg3; + @EqualsAndHashCode.Include @Getter private final OpCode opCode; + @EqualsAndHashCode.Include @Getter private final BaseBytes arg1; + @EqualsAndHashCode.Include @Getter private final BaseBytes arg2; + @EqualsAndHashCode.Include @Getter private final BaseBytes arg3; private final boolean isOneLineInstruction; private BaseTheta result; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperationComparator.java new file mode 100644 index 000000000..96eed8b46 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/ext/ExtOperationComparator.java @@ -0,0 +1,41 @@ +/* + * Copyright ConsenSys 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.ext; + +import java.util.Comparator; + +public class ExtOperationComparator implements Comparator { + @Override + public int compare(ExtOperation op1, ExtOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.arg1().getBytes32().compareTo(op2.arg1().getBytes32()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + final int arg2Comp = op1.arg2().getBytes32().compareTo(op2.arg2().getBytes32()); + if (arg2Comp != 0) { + return arg2Comp; + } + // Fourth, sort by Arg3 + return op1.arg3().getBytes32().compareTo(op2.arg3().getBytes32()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/Gas.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/Gas.java index 7f9205369..c1a820069 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/Gas.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/Gas.java @@ -19,38 +19,25 @@ import java.nio.MappedByteBuffer; import java.util.List; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.ColumnHeader; -import net.consensys.linea.zktracer.container.module.Module; -import net.consensys.linea.zktracer.container.stacked.ModuleOperationStackedList; +import net.consensys.linea.zktracer.container.module.OperationSetModule; +import net.consensys.linea.zktracer.container.stacked.ModuleOperationStackedSet; import org.hyperledger.besu.evm.frame.MessageFrame; -public class Gas implements Module { +@Accessors(fluent = true) +public class Gas implements OperationSetModule { /** A list of the operations to trace */ - private final ModuleOperationStackedList operations = - new ModuleOperationStackedList<>(); - - // TODO: why a stackedList of GasOperation? It should be a StateLess module no ? + @Getter + private final ModuleOperationStackedSet operations = + new ModuleOperationStackedSet<>(); @Override public String moduleKey() { return "GAS"; } - @Override - public void enterTransaction() { - this.operations.enter(); - } - - @Override - public void popTransaction() { - this.operations.pop(); - } - - @Override - public int lineCount() { - return this.operations.lineCount(); - } - @Override public List columnsHeaders() { return null; @@ -71,7 +58,7 @@ private GasParameters extractGasParameters(MessageFrame frame) { public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (GasOperation gasOperation : this.operations.getAll()) { + for (GasOperation gasOperation : operations.sortOperations(new GasOperationComparator())) { // TODO: I thought we don't have stamp for gas anymore ? stamp++; gasOperation.trace(stamp, trace); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperation.java index 3bcf40c23..9d63a58ae 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperation.java @@ -22,12 +22,15 @@ import java.math.BigInteger; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.types.UnsignedByte; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class GasOperation extends ModuleOperation { - @EqualsAndHashCode.Include GasParameters gasParameters; + @EqualsAndHashCode.Include @Getter GasParameters gasParameters; BigInteger[] wcpArg1Lo; BigInteger[] wcpArg2Lo; UnsignedByte[] wcpInst; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperationComparator.java new file mode 100644 index 000000000..b2ff2680e --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasOperationComparator.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys 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.gas; + +import java.util.Comparator; + +public class GasOperationComparator implements Comparator { + @Override + public int compare(GasOperation o1, GasOperation o2) { + return o1.gasParameters().compareTo(o2.gasParameters()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasParameters.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasParameters.java index 04399f6a6..11ae45318 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasParameters.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/gas/GasParameters.java @@ -18,4 +18,24 @@ import java.math.BigInteger; public record GasParameters( - int ctMax, BigInteger gasActual, BigInteger gasCost, boolean xahoy, boolean oogx) {} + int ctMax, // TODO @Lorenzo this shouldn't be in gasParameters, because it shouldn't be in the + // EqualAndHAsh, it's a consequence of oogx and xahoy + BigInteger gasActual, + BigInteger gasCost, + boolean xahoy, + boolean oogx) { + + public int compareTo(GasParameters other) { + if (oogx() != other.oogx()) { + return oogx() ? 1 : -1; + } + if (xahoy() != other.xahoy()) { + return xahoy() ? 1 : -1; + } + final int gasActualComparison = gasActual().compareTo(other.gasActual()); + if (gasActualComparison != 0) { + return gasActualComparison; + } + return gasCost().compareTo(other.gasCost()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java index 8ff261aed..fff569bd5 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/Hub.java @@ -411,7 +411,7 @@ public Hub(final Address l2l1ContractAddress, final Bytes l2l1Topic) { add, bin, blakeModexpData, - blockhash, + blockhash, /* WARN: must be called BEFORE WCP (for traceEndConflation) */ ecData, euc, ext, diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java index 12a0e17a8..a671285b5 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/StpCall.java @@ -27,6 +27,7 @@ import java.math.BigInteger; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -44,19 +45,20 @@ @Getter @Setter @Accessors(fluent = true) +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class StpCall implements TraceSubFragment { final Hub hub; - final long memoryExpansionGas; - OpCode opCode; - long gasActual; - EWord gas; // for CALL's only - EWord value; - boolean exists; - boolean warm; - long upfrontGasCost; - boolean outOfGasException; - long gasPaidOutOfPocket; - long stipend; + @EqualsAndHashCode.Include final long memoryExpansionGas; + @EqualsAndHashCode.Include OpCode opCode; + @EqualsAndHashCode.Include long gasActual; + @EqualsAndHashCode.Include EWord gas; // for CALL's only + @EqualsAndHashCode.Include EWord value; + @EqualsAndHashCode.Include boolean exists; + @EqualsAndHashCode.Include boolean warm; + @EqualsAndHashCode.Include long upfrontGasCost; + @EqualsAndHashCode.Include boolean outOfGasException; + @EqualsAndHashCode.Include long gasPaidOutOfPocket; + @EqualsAndHashCode.Include long stipend; public StpCall(Hub hub, long memoryExpansionGas) { this.hub = hub; @@ -176,4 +178,58 @@ public Trace trace(Trace trace) { .pMiscStpGasPaidOutOfPocket(Bytes.ofUnsignedLong(gasPaidOutOfPocket)) .pMiscStpGasStipend(stipend); } + + public int compareTo(StpCall stpCall) { + final int opCodeComp = opCode.compareTo(stpCall.opCode); + if (opCodeComp != 0) { + return opCodeComp; + } + + final int gasActualComp = Long.compare(gasActual, stpCall.gasActual); + if (gasActualComp != 0) { + return gasActualComp; + } + + final int memoryExpansionGasComp = Long.compare(memoryExpansionGas, stpCall.memoryExpansionGas); + if (memoryExpansionGasComp != 0) { + return memoryExpansionGasComp; + } + + final int gasPaidOutOfPocketComp = Long.compare(gasPaidOutOfPocket, stpCall.gasPaidOutOfPocket); + if (gasPaidOutOfPocketComp != 0) { + return gasPaidOutOfPocketComp; + } + + final int stipendComp = Long.compare(stipend, stpCall.stipend); + if (stipendComp != 0) { + return stipendComp; + } + + final int upfrontGasCostComp = Long.compare(upfrontGasCost, stpCall.upfrontGasCost); + if (upfrontGasCostComp != 0) { + return upfrontGasCostComp; + } + + final boolean existsComp = exists == stpCall.exists; + if (!existsComp) { + return exists ? 1 : -1; + } + + final boolean warmComp = warm == stpCall.warm; + if (!warmComp) { + return warm ? 1 : -1; + } + + final boolean outOfGasExceptionComp = outOfGasException == stpCall.outOfGasException; + if (!outOfGasExceptionComp) { + return outOfGasException ? 1 : -1; + } + + final int valueComp = value.compareTo(stpCall.value); + if (valueComp != 0) { + return valueComp; + } + + return gas.compareTo(stpCall.gas); + } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExpCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExpCall.java index 4e0262065..1784e69f3 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExpCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExpCall.java @@ -19,5 +19,7 @@ /** This interface defines the API required to execute a call to the EXP module. */ public interface ExpCall extends TraceSubFragment { - public int expInstruction(); + int expInstruction(); + + int compareTo(ExpCall o); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExplogExpCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExplogExpCall.java index d7848b215..4ab3b4d18 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExplogExpCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ExplogExpCall.java @@ -19,10 +19,12 @@ import lombok.Getter; import lombok.Setter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.module.hub.Trace; import net.consensys.linea.zktracer.types.EWord; import org.apache.tuweni.bytes.Bytes; +@Accessors(fluent = true) @Getter @Setter public class ExplogExpCall implements ExpCall { @@ -34,6 +36,17 @@ public int expInstruction() { return EXP_INST_EXPLOG; } + @Override + public int compareTo(ExpCall op2) { + final ExplogExpCall o2 = (ExplogExpCall) op2; + + final int dynCostComp = Long.compare(dynCost, o2.dynCost()); + if (dynCostComp != 0) { + return dynCostComp; + } + return exponent.compareTo(o2.exponent()); + } + @Override public Trace trace(Trace trace) { return trace @@ -41,6 +54,6 @@ public Trace trace(Trace trace) { .pMiscExpInst(EXP_INST_EXPLOG) .pMiscExpData1(exponent.hi()) .pMiscExpData2(exponent.lo()) - .pMiscExpData5(Bytes.ofUnsignedLong(this.dynCost)); + .pMiscExpData5(Bytes.ofUnsignedLong(dynCost)); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ModexpLogExpCall.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ModexpLogExpCall.java index 764f9dd55..379818a3d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ModexpLogExpCall.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/hub/fragment/imc/exp/ModexpLogExpCall.java @@ -43,6 +43,26 @@ public int expInstruction() { return EXP_INST_MODEXPLOG; } + @Override + public int compareTo(ExpCall op2) { + final ModexpLogExpCall o2 = (ModexpLogExpCall) op2; + + final int cdsCutoffComp = Integer.compare(cdsCutoff, o2.getCdsCutoff()); + if (cdsCutoffComp != 0) { + return cdsCutoffComp; + } + final int ebsCutoffComp = Integer.compare(ebsCutoff, o2.getEbsCutoff()); + if (ebsCutoffComp != 0) { + return ebsCutoffComp; + } + final int leadLogComp = leadLog.compareTo(o2.getLeadLog()); + if (leadLogComp != 0) { + return leadLogComp; + } + + return rawLeadingWord.compareTo(o2.getRawLeadingWord()); + } + @Override public Trace trace(Trace trace) { return trace @@ -51,6 +71,6 @@ public Trace trace(Trace trace) { .pMiscExpData2(rawLeadingWord.lo()) .pMiscExpData3(Bytes.ofUnsignedShort(cdsCutoff)) .pMiscExpData4(Bytes.ofUnsignedShort(ebsCutoff)) - .pMiscExpData5(bigIntegerToBytes(this.leadLog)); + .pMiscExpData5(bigIntegerToBytes(leadLog)); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/Mod.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/Mod.java index 5f51faae4..6fc7713fc 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/Mod.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/Mod.java @@ -54,7 +54,7 @@ public void tracePreOpcode(final MessageFrame frame) { public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (ModOperation op : operations.getAll()) { + for (ModOperation op : operations.sortOperations(new ModOperationComparator())) { op.trace(trace, ++stamp); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperation.java index afdddc313..3c9ba88b1 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperation.java @@ -23,6 +23,8 @@ import java.util.Arrays; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.bytestheta.BaseBytes; import net.consensys.linea.zktracer.bytestheta.BaseTheta; import net.consensys.linea.zktracer.container.ModuleOperation; @@ -33,12 +35,13 @@ import org.apache.tuweni.units.bigints.UInt256; import org.apache.tuweni.units.bigints.UInt64; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class ModOperation extends ModuleOperation { - @EqualsAndHashCode.Include private final OpCode opCode; - @EqualsAndHashCode.Include private final Bytes32 rawArg1; - @EqualsAndHashCode.Include private final Bytes32 rawArg2; + @EqualsAndHashCode.Include @Getter private final OpCode opCode; + @EqualsAndHashCode.Include @Getter private final Bytes32 rawArg1; + @EqualsAndHashCode.Include @Getter private final Bytes32 rawArg2; private final boolean oli; private BaseBytes arg1; private BaseBytes arg2; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperationComparator.java new file mode 100644 index 000000000..25c7cac1f --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mod/ModOperationComparator.java @@ -0,0 +1,36 @@ +/* + * Copyright ConsenSys 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.mod; + +import java.util.Comparator; + +public class ModOperationComparator implements Comparator { + @Override + public int compare(ModOperation op1, ModOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.rawArg1().compareTo(op2.rawArg1()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + return op1.rawArg2().compareTo(op2.rawArg2()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/Mul.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/Mul.java index 4fe2edf3e..28983d2ee 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/Mul.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/Mul.java @@ -67,7 +67,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (MulOperation op : operations.getAll()) { + for (MulOperation op : operations.sortOperations(new MulOperationComparator())) { op.trace(trace, ++stamp); } (new MulOperation(OpCode.EXP, Bytes32.ZERO, Bytes32.ZERO)).trace(trace, stamp + 1); diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperation.java index 4789e1ee0..d0c31cdea 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperation.java @@ -27,6 +27,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.bytestheta.BaseBytes; import net.consensys.linea.zktracer.bytestheta.BaseTheta; import net.consensys.linea.zktracer.container.ModuleOperation; @@ -38,6 +39,7 @@ import org.apache.tuweni.bytes.Bytes32; import org.apache.tuweni.units.bigints.UInt256; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class MulOperation extends ModuleOperation { @@ -410,7 +412,7 @@ void trace(Trace trace, int stamp) { } case TRIVIAL_MUL, NON_TRIVIAL_MUL -> { - this.setHsAndBits(UInt256.fromBytes(this.getArg1()), UInt256.fromBytes(this.getArg2())); + this.setHsAndBits(UInt256.fromBytes(arg1), UInt256.fromBytes(arg2)); this.traceSubOp(trace, stamp); } @@ -423,55 +425,55 @@ private void traceSubOp(Trace trace, int stamp) { trace .mulStamp(stamp) .counter(UnsignedByte.of(i)) - .oli(this.isOneLineInstruction()) - .tinyBase(this.isTinyBase()) - .tinyExponent(this.isTinyExponent()) - .resultVanishes(this.res.isZero()) - .instruction(UnsignedByte.of(this.getOpCode().byteValue())) - .arg1Hi(this.getArg1Hi()) - .arg1Lo(this.getArg1Lo()) - .arg2Hi(this.getArg2Hi()) - .arg2Lo(this.getArg2Lo()) - .resHi(this.res.getHigh()) - .resLo(this.res.getLow()) - .bits(this.bits[i]) - .byteA3(UnsignedByte.of(this.aBytes.get(3, i))) - .byteA2(UnsignedByte.of(this.aBytes.get(2, i))) - .byteA1(UnsignedByte.of(this.aBytes.get(1, i))) - .byteA0(UnsignedByte.of(this.aBytes.get(0, i))) - .accA3(this.aBytes.getRange(3, 0, i + 1)) - .accA2(this.aBytes.getRange(2, 0, i + 1)) - .accA1(this.aBytes.getRange(1, 0, i + 1)) - .accA0(this.aBytes.getRange(0, 0, i + 1)) - .byteB3(UnsignedByte.of(this.bBytes.get(3, i))) - .byteB2(UnsignedByte.of(this.bBytes.get(2, i))) - .byteB1(UnsignedByte.of(this.bBytes.get(1, i))) - .byteB0(UnsignedByte.of(this.bBytes.get(0, i))) - .accB3(this.bBytes.getRange(3, 0, i + 1)) - .accB2(this.bBytes.getRange(2, 0, i + 1)) - .accB1(this.bBytes.getRange(1, 0, i + 1)) - .accB0(this.bBytes.getRange(0, 0, i + 1)) - .byteC3(UnsignedByte.of(this.cBytes.get(3, i))) - .byteC2(UnsignedByte.of(this.cBytes.get(2, i))) - .byteC1(UnsignedByte.of(this.cBytes.get(1, i))) - .byteC0(UnsignedByte.of(this.cBytes.get(0, i))) - .accC3(this.cBytes.getRange(3, 0, i + 1)) - .accC2(this.cBytes.getRange(2, 0, i + 1)) - .accC1(this.cBytes.getRange(1, 0, i + 1)) - .accC0(this.cBytes.getRange(0, 0, i + 1)) - .byteH3(UnsignedByte.of(this.hBytes.get(3, i))) - .byteH2(UnsignedByte.of(this.hBytes.get(2, i))) - .byteH1(UnsignedByte.of(this.hBytes.get(1, i))) - .byteH0(UnsignedByte.of(this.hBytes.get(0, i))) - .accH3(this.hBytes.getRange(3, 0, i + 1)) - .accH2(this.hBytes.getRange(2, 0, i + 1)) - .accH1(this.hBytes.getRange(1, 0, i + 1)) - .accH0(this.hBytes.getRange(0, 0, i + 1)) - .exponentBit(this.isExponentBitSet()) - .exponentBitAccumulator(this.expAcc) - .exponentBitSource(this.isExponentInSource()) - .squareAndMultiply(this.squareAndMultiply) - .bitNum(UnsignedByte.of(this.getBitNum())) + .oli(isOneLineInstruction()) + .tinyBase(tinyBase) + .tinyExponent(tinyExponent) + .resultVanishes(res.isZero()) + .instruction(UnsignedByte.of(opCode.byteValue())) + .arg1Hi(arg1Hi) + .arg1Lo(arg1Lo) + .arg2Hi(arg2Hi) + .arg2Lo(arg2Lo) + .resHi(res.getHigh()) + .resLo(res.getLow()) + .bits(bits[i]) + .byteA3(UnsignedByte.of(aBytes.get(3, i))) + .byteA2(UnsignedByte.of(aBytes.get(2, i))) + .byteA1(UnsignedByte.of(aBytes.get(1, i))) + .byteA0(UnsignedByte.of(aBytes.get(0, i))) + .accA3(aBytes.getRange(3, 0, i + 1)) + .accA2(aBytes.getRange(2, 0, i + 1)) + .accA1(aBytes.getRange(1, 0, i + 1)) + .accA0(aBytes.getRange(0, 0, i + 1)) + .byteB3(UnsignedByte.of(bBytes.get(3, i))) + .byteB2(UnsignedByte.of(bBytes.get(2, i))) + .byteB1(UnsignedByte.of(bBytes.get(1, i))) + .byteB0(UnsignedByte.of(bBytes.get(0, i))) + .accB3(bBytes.getRange(3, 0, i + 1)) + .accB2(bBytes.getRange(2, 0, i + 1)) + .accB1(bBytes.getRange(1, 0, i + 1)) + .accB0(bBytes.getRange(0, 0, i + 1)) + .byteC3(UnsignedByte.of(cBytes.get(3, i))) + .byteC2(UnsignedByte.of(cBytes.get(2, i))) + .byteC1(UnsignedByte.of(cBytes.get(1, i))) + .byteC0(UnsignedByte.of(cBytes.get(0, i))) + .accC3(cBytes.getRange(3, 0, i + 1)) + .accC2(cBytes.getRange(2, 0, i + 1)) + .accC1(cBytes.getRange(1, 0, i + 1)) + .accC0(cBytes.getRange(0, 0, i + 1)) + .byteH3(UnsignedByte.of(hBytes.get(3, i))) + .byteH2(UnsignedByte.of(hBytes.get(2, i))) + .byteH1(UnsignedByte.of(hBytes.get(1, i))) + .byteH0(UnsignedByte.of(hBytes.get(0, i))) + .accH3(hBytes.getRange(3, 0, i + 1)) + .accH2(hBytes.getRange(2, 0, i + 1)) + .accH1(hBytes.getRange(1, 0, i + 1)) + .accH0(hBytes.getRange(0, 0, i + 1)) + .exponentBit(isExponentBitSet()) + .exponentBitAccumulator(expAcc) + .exponentBitSource(isExponentInSource()) + .squareAndMultiply(squareAndMultiply) + .bitNum(UnsignedByte.of(getBitNum())) .validateRow(); } } @@ -493,7 +495,7 @@ protected int computeLineCount() { } case TRIVIAL_MUL, NON_TRIVIAL_MUL -> { - op.setHsAndBits(UInt256.fromBytes(op.getArg1()), UInt256.fromBytes(op.getArg2())); + op.setHsAndBits(UInt256.fromBytes(op.arg1), UInt256.fromBytes(op.arg2)); yield op.numberOfRows(); } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperationComparator.java new file mode 100644 index 000000000..41f445985 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/mul/MulOperationComparator.java @@ -0,0 +1,36 @@ +/* + * Copyright ConsenSys 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.mul; + +import java.util.Comparator; + +public class MulOperationComparator implements Comparator { + @Override + public int compare(MulOperation op1, MulOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.arg1().compareTo(op2.arg1()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + return op1.arg2().compareTo(op2.arg2()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java index c35486d49..d38d88357 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddr.java @@ -320,7 +320,7 @@ public List columnsHeaders() { public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (RlpAddrOperation op : operations.getAll()) { + for (RlpAddrOperation op : operations.sortOperations(new RlpAddrOperationComparator())) { traceOperation(op, ++stamp, trace); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java index 6c009fe8c..d54920c1d 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperation.java @@ -33,9 +33,9 @@ @RequiredArgsConstructor @Getter @Accessors(fluent = true) -@EqualsAndHashCode(callSuper = false) +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public final class RlpAddrOperation extends ModuleOperation { - private final Bytes32 rawHash; + @EqualsAndHashCode.Include private final Bytes32 rawHash; private final OpCode opCode; private final Optional nonce; private final Address address; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperationComparator.java new file mode 100644 index 000000000..dda61ecd4 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/rlpaddr/RlpAddrOperationComparator.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys 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.rlpaddr; + +import java.util.Comparator; + +public class RlpAddrOperationComparator implements Comparator { + @Override + public int compare(RlpAddrOperation op1, RlpAddrOperation op2) { + return op1.rawHash().compareTo(op2.rawHash()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomOperationComparator.java index 81803e54d..b73b1a8e8 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomOperationComparator.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/romlex/RomOperationComparator.java @@ -18,10 +18,10 @@ import java.util.Comparator; class RomOperationComparator implements Comparator { - // Initialize the ChunkList public int compare(RomOperation chunk1, RomOperation chunk2) { // First sort by Address - int addressComparison = chunk1.metadata().address().compareTo(chunk2.metadata().address()); + final int addressComparison = + chunk1.metadata().address().compareTo(chunk2.metadata().address()); if (addressComparison != 0) { return addressComparison; } else { diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/Shf.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/Shf.java index f8fcb5764..b953cc2d0 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/Shf.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/Shf.java @@ -57,13 +57,8 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (ShfOperation op : operations.getAll()) { + for (ShfOperation op : operations.sortOperations(new ShfOperationComparator())) { op.trace(trace, ++stamp); } } - - @Override - public ModuleOperationStackedSet operations() { - return operations; - } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperation.java index 6b005cfed..863da5418 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperation.java @@ -24,6 +24,8 @@ import java.util.List; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.opcode.OpCode; import net.consensys.linea.zktracer.types.Bytes16; @@ -31,12 +33,13 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +@Accessors(fluent = true) @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) final class ShfOperation extends ModuleOperation { - @EqualsAndHashCode.Include private final OpCode opCode; - @EqualsAndHashCode.Include private final Bytes32 arg1; - @EqualsAndHashCode.Include private final Bytes32 arg2; + @EqualsAndHashCode.Include @Getter private final OpCode opCode; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg1; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg2; private final boolean isOneLineInstruction; private boolean isNegative; private boolean isShiftRight; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperationComparator.java new file mode 100644 index 000000000..7ec9ead63 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/shf/ShfOperationComparator.java @@ -0,0 +1,35 @@ +/* + * Copyright ConsenSys 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.shf; + +import java.util.Comparator; + +public class ShfOperationComparator implements Comparator { + public int compare(ShfOperation op1, ShfOperation op2) { + // First sort by OpCode + final int opCodeComp = op1.opCode().compareTo(op2.opCode()); + if (opCodeComp != 0) { + return opCodeComp; + } + // Second sort by Arg1 + final int arg1Comp = op1.arg1().compareTo(op2.arg1()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Third, sort by Arg2 + return op1.arg2().compareTo(op2.arg2()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/Stp.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/Stp.java index a03402bba..671a9b983 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/Stp.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/Stp.java @@ -87,7 +87,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (StpOperation operation : operations.getAll()) { + for (StpOperation operation : operations.sortOperations(new StpOperationComparator())) { operation.trace(trace, ++stamp); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperation.java index 68d8c3b89..051e2c471 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperation.java @@ -19,6 +19,7 @@ import java.math.BigInteger; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.experimental.Accessors; import net.consensys.linea.zktracer.container.ModuleOperation; @@ -29,6 +30,7 @@ @Accessors(fluent = true) @Getter +@EqualsAndHashCode(callSuper = false) public final class StpOperation extends ModuleOperation { private final StpCall stpCall; diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperationComparator.java new file mode 100644 index 000000000..ddcc5d557 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/stp/StpOperationComparator.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys 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.stp; + +import java.util.Comparator; + +public class StpOperationComparator implements Comparator { + @Override + public int compare(StpOperation op1, StpOperation op2) { + return op1.stpCall().compareTo(op2.stpCall()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/Trm.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/Trm.java index b55c38b65..97532d739 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/Trm.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/Trm.java @@ -63,7 +63,7 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; - for (TrmOperation operation : operations.getAll()) { + for (TrmOperation operation : operations.sortOperations(new TrmOperationComparator())) { operation.trace(trace, ++stamp); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperation.java index f5fec68bf..5d1a54ab6 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperation.java @@ -25,17 +25,20 @@ import java.util.List; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.experimental.Accessors; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.types.EWord; import net.consensys.linea.zktracer.types.UnsignedByte; import org.apache.tuweni.bytes.Bytes; import org.hyperledger.besu.datatypes.Address; +@Accessors(fluent = true) @RequiredArgsConstructor @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class TrmOperation extends ModuleOperation { - @EqualsAndHashCode.Include private final EWord rawAddress; + @EqualsAndHashCode.Include @Getter private final EWord rawAddress; void trace(Trace trace, final int stamp) { final Bytes trmHiBytes = diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperationComparator.java new file mode 100644 index 000000000..4f8ed5055 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/trm/TrmOperationComparator.java @@ -0,0 +1,25 @@ +/* + * Copyright ConsenSys 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.trm; + +import java.util.Comparator; + +public class TrmOperationComparator implements Comparator { + @Override + public int compare(TrmOperation op1, TrmOperation op2) { + return op1.rawAddress().compareTo(op2.rawAddress()); + } +} diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/Wcp.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/Wcp.java index e2996a191..fc95bb8b6 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/Wcp.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/Wcp.java @@ -125,8 +125,9 @@ public void commit(List buffers) { final Trace trace = new Trace(buffers); int stamp = 0; + final WcpOperationComparator comparator = new WcpOperationComparator(); for (ModuleOperationStackedSet operationsSet : operations) { - for (WcpOperation operation : operationsSet.getAll()) { + for (WcpOperation operation : operationsSet.sortOperations(comparator)) { operation.trace(trace, ++stamp); } } diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperation.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperation.java index ffd6c4541..b15c18e36 100644 --- a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperation.java +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperation.java @@ -36,6 +36,8 @@ import java.util.List; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import net.consensys.linea.zktracer.container.ModuleOperation; import net.consensys.linea.zktracer.types.Bytes16; @@ -43,6 +45,7 @@ import org.apache.tuweni.bytes.Bytes; import org.apache.tuweni.bytes.Bytes32; +@Accessors(fluent = true) @Slf4j @EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false) public class WcpOperation extends ModuleOperation { @@ -56,8 +59,8 @@ public class WcpOperation extends ModuleOperation { static final byte ISZERObv = (byte) EVM_INST_ISZERO; private final byte wcpInst; - @EqualsAndHashCode.Include private final Bytes32 arg1; - @EqualsAndHashCode.Include private final Bytes32 arg2; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg1; + @EqualsAndHashCode.Include @Getter private final Bytes32 arg2; private int ctMax; // Note : is computed in computeLineCount, if the WCP operation is added to the // StackedSet diff --git a/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperationComparator.java b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperationComparator.java new file mode 100644 index 000000000..178648197 --- /dev/null +++ b/arithmetization/src/main/java/net/consensys/linea/zktracer/module/wcp/WcpOperationComparator.java @@ -0,0 +1,31 @@ +/* + * Copyright ConsenSys 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.wcp; + +import java.util.Comparator; + +public class WcpOperationComparator implements Comparator { + @Override + public int compare(WcpOperation op1, WcpOperation op2) { + // First sort by Arg1 + final int arg1Comp = op1.arg1().compareTo(op2.arg1()); + if (arg1Comp != 0) { + return arg1Comp; + } + // Second, sort by Arg2 + return op1.arg2().compareTo(op2.arg2()); + } +}