diff --git a/patches/0001-aere-pqc-precompiles-mainnet.patch b/patches/0001-aere-pqc-precompiles-mainnet.patch index 620b460..bf7d3db 100644 --- a/patches/0001-aere-pqc-precompiles-mainnet.patch +++ b/patches/0001-aere-pqc-precompiles-mainnet.patch @@ -1,15 +1,115 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Thu, 10 Sep 2026 21:47:55 +0300 +Date: Thu, 10 Sep 2026 22:39:39 +0300 Subject: [PATCH] Aere Network: post-quantum signature verification precompiles + (mainnet 0x0ae1-0x0ae5) -Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. +Adds five native precompiled contracts exposing post-quantum signature +verification to the EVM, and registers them in populateForFutureEIPs so they +activate by fork timestamp rather than at genesis. + 0x0ae1 Falcon-512 verify NIST Falcon round 3 + 0x0ae2 Falcon-1024 verify NIST Falcon round 3 + 0x0ae3 ML-DSA-44 verify FIPS 204 + 0x0ae4 SLH-DSA-SHA2-128s verify FIPS 205 + 0x0ae5 SHAKE256 XOF FIPS 202 + +Live on Aere Network chain 2800 from block 9,189,161. + +Scope: these precompiles verify post-quantum signatures inside the EVM. They +do not change consensus. Block sealing and validator identity on chain 2800 +remain classical secp256k1 ECDSA QBFT. + +populateForFutureEIPs is additionally repointed from populateForCancun to +populateForOsaka, so the fork carries the full Osaka precompile set. + +No build file change is required: bcprov-jdk18on is already exposed to the evm +module as an api dependency of crypto:algorithms, and jakarta.validation-api is +a global subproject dependency. +Modified upstream files. Two files touched by this patch are modified copies +of Hyperledger Besu sources, not new work by Aere Network: + + datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java + evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java + +Aere Network changed both, against upstream commit +d2032017bb3b8cb215a97303980a1e4a643f7180. Both keep their original +"Copyright contributors to Hyperledger Besu" headers unchanged, which is what +Apache License 2.0 section 4(c) requires, and this patch adds to each a +separate "Modifications Copyright" block naming exactly what was changed. That +in-file block is the notice required by Apache License 2.0 section 4(b). It +travels inside the diff, so a tree with this patch applied carries the notice +whether you used git am or git apply. Every other file this patch touches is +new and was written by Aere Network, and each carries its own Apache-2.0 +header. + +Regenerated 2026-09-10 from the production tree over the same file set, so that +the public recipe carries the same Apache-2.0 section 4(b) modification notices +that the production sources carry; measured the same day: a build from this +recipe reproduces the fleet's consensus jars class for class. +--- diff --git a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java -index 950cd59e3..0f486dfcf 100644 +index 950cd59e3..3a63362d7 100644 --- a/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java +++ b/datatypes/src/main/java/org/hyperledger/besu/datatypes/Address.java -@@ -91,6 +91,21 @@ public class Address extends BytesHolder { +@@ -1,33 +1,39 @@ + /* + * Copyright contributors to Hyperledger Besu. + * + * 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 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0001-aere-pqc-precompiles-mainnet.patch. + */ + package org.hyperledger.besu.datatypes; + + import static com.google.common.base.Preconditions.checkArgument; + import static org.hyperledger.besu.crypto.Hash.keccak256; + + import org.hyperledger.besu.crypto.SECPPublicKey; + import org.hyperledger.besu.ethereum.rlp.RLP; + import org.hyperledger.besu.ethereum.rlp.RLPException; + import org.hyperledger.besu.ethereum.rlp.RLPInput; + + import java.util.concurrent.ExecutionException; + + import com.fasterxml.jackson.annotation.JsonCreator; + import com.google.common.cache.CacheBuilder; + import com.google.common.cache.CacheLoader; + import com.google.common.cache.LoadingCache; + import org.apache.tuweni.bytes.Bytes; + import org.apache.tuweni.bytes.Bytes32; + +@@ -74,40 +80,55 @@ public class Address extends BytesHolder { + public static final Address BLS12_G1MULTIEXP = Address.precompiled(0xC); + + /** The constant BLS12_G2ADD. */ + public static final Address BLS12_G2ADD = Address.precompiled(0xD); + + /** The constant BLS12_G2MULTIEXP. */ + public static final Address BLS12_G2MULTIEXP = Address.precompiled(0xE); + + /** The constant BLS12_PAIRING. */ + public static final Address BLS12_PAIRING = Address.precompiled(0xF); + + /** The constant BLS12_MAP_FP_TO_G1. */ + public static final Address BLS12_MAP_FP_TO_G1 = Address.precompiled(0x10); + + /** The constant BLS12_MAP_FP2_TO_G2. */ + public static final Address BLS12_MAP_FP2_TO_G2 = Address.precompiled(0x11); + /** Precompile address for P256_VERIFY. */ public static final Address P256_VERIFY = Address.precompiled(0x0100); @@ -31,6 +131,23 @@ index 950cd59e3..0f486dfcf 100644 /** The constant ZERO. */ public static final Address ZERO = Address.fromHexString("0x0"); + static LoadingCache hashCache = + CacheBuilder.newBuilder() + .maximumSize(4000) + // .weakKeys() // unless we "intern" all addresses we cannot use weak or soft keys. + .build( + new CacheLoader<>() { + @Override + public Hash load(final Address key) { + return Hash.hash(key.getBytes()); + } + }); + + /** + * Instantiates a new Address. + * + * @param bytes the bytes + */ diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/AereFalconSupport.java new file mode 100644 index 000000000..1dbb2b85c @@ -358,10 +475,67 @@ index 000000000..f25be641f + } +} diff --git a/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java -index 28d84abf1..43d9fb73a 100644 +index 28d84abf1..554a1e111 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/precompile/MainnetPrecompiledContracts.java -@@ -226,6 +226,15 @@ public interface MainnetPrecompiledContracts { +@@ -1,33 +1,39 @@ + /* + * Copyright contributors to Hyperledger Besu. + * + * 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 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0001-aere-pqc-precompiles-mainnet.patch.patch. + */ + package org.hyperledger.besu.evm.precompile; + + import static org.hyperledger.besu.datatypes.Address.P256_VERIFY; + + import org.hyperledger.besu.datatypes.Address; + import org.hyperledger.besu.evm.gascalculator.GasCalculator; + + /** Provides the various precompiled contracts used on mainnet hard forks. */ + public interface MainnetPrecompiledContracts { + + /** + * Frontier precompile contract registry. + * + * @param gasCalculator the gas calculator + * @return the precompile contract registry + */ + static PrecompileContractRegistry frontier(final GasCalculator gasCalculator) { + PrecompileContractRegistry precompileContractRegistry = new PrecompileContractRegistry(); + populateForFrontier(precompileContractRegistry, gasCalculator); +@@ -209,23 +215,32 @@ public interface MainnetPrecompiledContracts { + /** + * FutureEIPs precompile contract registry. + * + * @param gasCalculator the gas calculator + * @return the precompile contract registry + */ + static PrecompileContractRegistry futureEIPs(final GasCalculator gasCalculator) { + PrecompileContractRegistry precompileContractRegistry = new PrecompileContractRegistry(); + populateForFutureEIPs(precompileContractRegistry, gasCalculator); + return precompileContractRegistry; + } + + /** + * Populate registry for Future EIPs. + * + * @param registry the registry + * @param gasCalculator the gas calculator */ static void populateForFutureEIPs( final PrecompileContractRegistry registry, final GasCalculator gasCalculator) { diff --git a/patches/0003-aere-pq-anchor.patch b/patches/0003-aere-pq-anchor.patch index 1b66521..7bd65af 100644 --- a/patches/0003-aere-pq-anchor.patch +++ b/patches/0003-aere-pq-anchor.patch @@ -1,10 +1,36 @@ From 65a97c099634691fed1c2ee619b74b5cf0254739 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Thu, 10 Sep 2026 21:47:55 +0300 +Date: Thu, 10 Sep 2026 22:36:08 +0300 Subject: [PATCH] Aere Network: post-quantum certificate anchor for QBFT -Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. +Puts a 32-byte digest of the validator certificate into vanityData, which is +already covered by the block hash, so that the hash commits to the certificate. +The certificate itself still rides outside the hash and is pinned by the digest. +Apache License 2.0, section 4(b): the files this patch modifies are the work of +Hyperledger Besu and carry its copyright notice. This patch changes them. The +modifications are by contributors to the Aere Network and are offered under the +same Apache License 2.0; the upstream copyright headers are left as found. + +The slhdsa/ package under consensus/common is derived from Bouncy Castle 1.80 +and stays under the Bouncy Castle licence; its notice is carried alongside +(LICENSE-BouncyCastle.txt). + +Updated 2026-09-05: the v2, scheme-tagged hybrid certificate (Falcon-512 and +SLH-DSA-SHA2-128s seals, live on chain 2800 since block 17,047,600), the in-tree +SLH-DSA engine on the JDK digest, the seal-store repair (a commit heard before +the round held its proposal, or a late commit, was dropped from the store; the +round-0 proposer of an anchor then refused to propose), and the anchor interval +schedule (aere.pq.anchorIntervalSchedule, 17225968:128 on chain 2800). The +post-quantum message layers (PROPOSAL, PREPARE, COMMIT, ROUND-CHANGE seals with +per-type domains) are included with their emission and enforcement height +switches; see anchor/README.md for what is armed on chain 2800. + +Regenerated 2026-09-10 from the production tree over the same file set, so that +the public recipe carries the same Apache-2.0 section 4(b) modification notices +that the production sources carry; measured the same day: a build from this +recipe reproduces the fleet's consensus jars class for class. +--- diff --git a/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index 2767db2eb..df19c1dd2 100644 --- a/app/src/main/java/org/hyperledger/besu/cli/BesuCommand.java diff --git a/patches/0004-aere-basefee-floor.patch b/patches/0004-aere-basefee-floor.patch index 7380324..b334078 100644 --- a/patches/0004-aere-basefee-floor.patch +++ b/patches/0004-aere-basefee-floor.patch @@ -1,15 +1,70 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aere Network -Date: Thu, 10 Sep 2026 21:47:56 +0300 +Date: Thu, 10 Sep 2026 22:39:39 +0300 Subject: [PATCH] Aere Network: base-fee floor for chain 2800 (production form) -Regenerated 2026-09-10 from the production tree (overlay applied) over the same file set. +Apache License 2.0, section 4(b): the files this patch modifies are the work of +Hyperledger Besu and carry its copyright notice; the modifications are by +contributors to the Aere Network under the same licence. +Regenerated 2026-09-05 from the production tree, so that the public recipe +reproduces the live binary class for class: the floor and its fork height are +read from the system properties aere.basefee.floor.forkBlock and +aere.basefee.floor.value (or the AERE_BASEFEE_FLOOR_* environment variables), +absent = disarmed, exactly as RUN-A-NODE.md tells an operator to set them. +The previous revision of this patch hard-coded both as constants, so the +operator's property was dead on a node built from the public recipe (found +2026-09-05 by comparing the fleet's jars with the public build class by class). + +Regenerated 2026-09-10 from the production tree over the same file set, so that +the public recipe carries the same Apache-2.0 section 4(b) modification notices +that the production sources carry; measured the same day: a build from this +recipe reproduces the fleet's consensus jars class for class. +--- diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java -index 0ee4f7409..558076166 100644 +index 0ee4f7409..e7c8c9724 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/feemarket/LondonFeeMarket.java -@@ -34,11 +34,36 @@ public class LondonFeeMarket implements BaseFeeMarket { +@@ -1,137 +1,252 @@ + /* + * Copyright ConsenSys AG. + * + * 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 ++ * ++ * Modifications Copyright contributors to the Aere Network. ++ * ++ * This file was modified by contributors to the Aere Network, as required by section 4(b) of the ++ * Apache License 2.0. The copyright header above is the upstream one and is left exactly as it was ++ * found, as section 4(c) requires. The change itself is in patches/0004-aere-basefee-floor.patch. + */ + package org.hyperledger.besu.ethereum.mainnet.feemarket; + + import org.hyperledger.besu.config.GenesisConfig; + import org.hyperledger.besu.datatypes.Wei; + import org.hyperledger.besu.ethereum.core.Transaction; + import org.hyperledger.besu.ethereum.core.feemarket.TransactionPriceCalculator; + + import java.util.Optional; + + import org.apache.tuweni.units.bigints.UInt256s; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + + public class LondonFeeMarket implements BaseFeeMarket { + private static final Logger LOG = LoggerFactory.getLogger(LondonFeeMarket.class); + + static final Wei DEFAULT_BASEFEE_INITIAL_VALUE = GenesisConfig.BASEFEE_AT_GENESIS_DEFAULT_VALUE; + static final long DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR = 8L; + static final long DEFAULT_SLACK_COEFFICIENT = 2L; private static final Wei DEFAULT_BASEFEE_FLOOR = Wei.of(7L); @@ -46,7 +101,8 @@ index 0ee4f7409..558076166 100644 LondonFeeMarket(final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { this(TransactionPriceCalculator.eip1559(), londonForkBlockNumber, baseFeePerGasOverride); } -@@ -47,10 +72,94 @@ public class LondonFeeMarket implements BaseFeeMarket { + + LondonFeeMarket( final TransactionPriceCalculator txPriceCalculator, final long londonForkBlockNumber, final Optional baseFeePerGasOverride) { @@ -141,7 +197,28 @@ index 0ee4f7409..558076166 100644 } @Override -@@ -79,7 +188,7 @@ public class LondonFeeMarket implements BaseFeeMarket { + public long getBasefeeMaxChangeDenominator() { + return DEFAULT_BASEFEE_MAX_CHANGE_DENOMINATOR; + } + + @Override + public Wei getInitialBasefee() { + return baseFeeInitialValue; + } + + @Override + public long getSlackCoefficient() { + return DEFAULT_SLACK_COEFFICIENT; + } + + @Override + public TransactionPriceCalculator getTransactionPriceCalculator() { + return txPriceCalculator; + } + + @Override + public boolean satisfiesFloorTxFee(final Transaction txn) { + // ensure effective baseFee is at least above floor return txn.getGasPrice() .map(Optional::of) .orElse(txn.getMaxFeePerGas()) @@ -150,7 +227,10 @@ index 0ee4f7409..558076166 100644 .isPresent(); } -@@ -90,13 +199,13 @@ public class LondonFeeMarket implements BaseFeeMarket { + @Override + public Wei computeBaseFee( + final long blockNumber, + final Wei parentBaseFee, final long parentBlockGasUsed, final long targetGasUsed) { if (londonForkBlockNumber == blockNumber) { @@ -166,7 +246,20 @@ index 0ee4f7409..558076166 100644 } else if (parentBlockGasUsed > targetGasUsed) { gasDelta = parentBlockGasUsed - targetGasUsed; final long denominator = getBasefeeMaxChangeDenominator(); -@@ -117,7 +226,7 @@ public class LondonFeeMarket implements BaseFeeMarket { + feeDelta = + UInt256s.max( + parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator), Wei.ONE); + baseFee = parentBaseFee.add(feeDelta); + } else { + gasDelta = targetGasUsed - parentBlockGasUsed; + final long denominator = getBasefeeMaxChangeDenominator(); + feeDelta = parentBaseFee.multiply(gasDelta).divide(targetGasUsed).divide(denominator); + baseFee = parentBaseFee.subtract(feeDelta); + } + LOG.trace( + "block #{} parentBaseFee: {} parentGasUsed: {} parentGasTarget: {} baseFee: {}", + blockNumber, + parentBaseFee, parentBlockGasUsed, targetGasUsed, baseFee); @@ -175,3 +268,17 @@ index 0ee4f7409..558076166 100644 } @Override + public ValidationMode baseFeeValidationMode(final long blockNumber) { + return londonForkBlockNumber == blockNumber ? ValidationMode.INITIAL : ValidationMode.ONGOING; + } + + @Override + public ValidationMode gasLimitValidationMode(final long blockNumber) { + return londonForkBlockNumber == blockNumber ? ValidationMode.INITIAL : ValidationMode.ONGOING; + } + + @Override + public boolean isBeforeForkBlock(final long blockNumber) { + return londonForkBlockNumber > blockNumber; + } + }