From 91b0110bc6d4e6f989b5fda88c82c8ca5ac6f98a Mon Sep 17 00:00:00 2001 From: JasonVranek Date: Thu, 7 Nov 2024 00:23:19 +0700 Subject: [PATCH] test deploy to pectra devnet --- script/BLSSignatureChecker.s.sol | 139 +++++++++++++++++++++++++++++++ script/Registry.s.sol | 27 ++++++ src/Registry.sol | 41 +++++++-- src/lib/BLS12381.sol | 2 +- src/lib/Merkelize.sol | 2 +- test/Registry.t.sol | 9 -- 6 files changed, 204 insertions(+), 16 deletions(-) create mode 100644 script/BLSSignatureChecker.s.sol create mode 100644 script/Registry.s.sol diff --git a/script/BLSSignatureChecker.s.sol b/script/BLSSignatureChecker.s.sol new file mode 100644 index 0000000..10cf5f3 --- /dev/null +++ b/script/BLSSignatureChecker.s.sol @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import "forge-std/Script.sol"; +import {console2} from "forge-std/console2.sol"; + +import {BLS12381} from "src/lib/BLS12381.sol"; + +contract BLSSignatureCheck is Script { + // forge script script/BLSSignatureChecker.s.sol:BLSSignatureCheck --rpc-url $RPC_URL --broadcast + function run() external { + // Retrieve the private key from environment variable + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + // Start broadcasting transactions + vm.startBroadcast(deployerPrivateKey); + + // Deploy the Registry contract + BLSSignatureChecker blsSignatureChecker = new BLSSignatureChecker(); + + // Log the deployed address + console.log("Registry deployed to:", address(blsSignatureChecker)); + + vm.stopBroadcast(); + } + + // forge script script/BLSSignatureChecker.s.sol:BLSSignatureChecker --func --rpc-url $RPC_URL --broadcast + function verifySignature() external { + // Retrieve the private key from environment variable + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + // Start broadcasting transactions + // vm.startBroadcast(deployerPrivateKey); + + BLSSignatureChecker blsSignatureChecker = BLSSignatureChecker( + 0xbc3e245F5616304E6F4Ad06dD553FcFdDad55BA9 + ); + + console2.log("blsSignatureChecker: ", address(blsSignatureChecker)); + + bytes memory message = bytes("Hello, World!"); + + // BLS12381.G1Point memory pubkey = BLS12381.G1Point({ + // x: [ + // 0x00000000000000000000000000000000101936a69d6fbd2feae29545220ad66e, + // 0xb60c3171b8d15de582dd2c645f67cb32377de0c97666e4b4fc7fad8a1c9a81af + // ], + // y: [ + // 0x0000000000000000000000000000000056cde7adcc8f412efa58ee343569d76a, + // 0x095176133a52fbf43979f46c0658010c573c093f3814a5d4dded92b52d197dff + // ] + // }); + + // BLS12381.G2Point memory signature = BLS12381.G2Point({ + // x: [ + // 0x0000000000000000000000000000000053551611fa07615a7c8928b6fd2bd6eb, + // 0x0081937c6d89bd162874603223c735ce5ea86eb23569cce2147a9c7041966b96 + // ], + // x_I: [ + // 0x0000000000000000000000000000000013fce717c9d6c37ffbd55e9097d6240b, + // 0x2eeafd7f72cc5191e8642c9cff28c224bf25a24cdc06b65f01ac627eb2882420 + // ], + // y: [ + // 0x0000000000000000000000000000000027846ac3f359dc4a47c6e677a9e17417, + // 0x0e33e07c097be6b0403f47aa40ea6d46b62d163952d92db1580f17ed3c9c0a9b + // ], + // y_I: [ + // 0x0000000000000000000000000000000013949b290fc3c66d4741d48ec37b359e, + // 0x781e7aff0ee1eddf15be1f73afafba6001689cb701ceda77b38d13a17b33c902 + // ] + // }); + BLS12381.G2Point memory signature = BLS12381.G2Point({ + x: [ + 0x00000000000000000000000000000000075785f1ffe7faabd27259035731c4ff, + 0x881c38e87fc963a47425ce52f12f18c348370eaea53008bc683206d7770f5bdf + ], + x_I: [ + 0x0000000000000000000000000000000002f8146bf138cbc35aeeccd4570d121c, + 0x8aec29661e8108e4094dc37b5a499272a6a680f015d0527c312a82457db8b979 + ], + y: [ + 0x000000000000000000000000000000000f5357626a9be51a0e689244b1a28d7b, + 0xe6132ad16f8d1852c2c75804fccf473902a5b8bbe6dd182d04643f34bb34fbe6 + ], + y_I: [ + 0x000000000000000000000000000000000544d2c2834eebb7cfbd5498cc0c328b, + 0x619d482161808b7e27dbb92941df85f704a6218ce9903af72eabdb3dbead70c7 + ] + }); + + BLS12381.G1Point memory pubkey = BLS12381.G1Point({ + x: [ + 0x00000000000000000000000000000000101936a69d6fbd2feae29545220ad66e, + 0xb60c3171b8d15de582dd2c645f67cb32377de0c97666e4b4fc7fad8a1c9a81af + ], + y: [ + 0x00000000000000000000000000000000056cde7adcc8f412efa58ee343569d76, + 0xa95176133a52fbf43979f46c0658010c573c093f3814a5d4dded92b52d197dff + ] + }); + + // bytes memory domainSeparator = bytes(""); + bytes memory domainSeparator = bytes("Taiko Based Rollup Preconfirmation v0.1.0"); + + vm.assertEq( + blsSignatureChecker.verifySignature( + message, + signature, + pubkey, + domainSeparator + ), + true + ); + + // vm.stopBroadcast(); + } +} + +contract BLSSignatureChecker { + using BLS12381 for *; + /** + * @notice Returns `true` if the BLS signature on the message matches against the public key + * @param message The message bytes + * @param sig The BLS signature + * @param pubkey The BLS public key of the expected signer + */ + function verifySignature( + bytes memory message, + BLS12381.G2Point memory sig, + BLS12381.G1Point memory pubkey, + bytes memory domainSeparator + ) public view returns (bool) { + // Hash the message bytes into a G2 point + BLS12381.G2Point memory msgG2 = message.hashToCurveG2(domainSeparator); + + // Return the pairing check that denotes the correctness of the signature + return BLS12381.pairing(pubkey, msgG2, BLS12381.negGeneratorG1(), sig); + } +} diff --git a/script/Registry.s.sol b/script/Registry.s.sol new file mode 100644 index 0000000..2c87730 --- /dev/null +++ b/script/Registry.s.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import "forge-std/Script.sol"; +import "../src/Registry.sol"; + +contract RegistryScript is Script { + + // forge script script/Registry.s.sol:RegistryScript --rpc-url $RPC_URL --broadcast + function run() external { + // Retrieve the private key from environment variable + uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY"); + + // Start broadcasting transactions + vm.startBroadcast(deployerPrivateKey); + + // Deploy the Registry contract + Registry registry = new Registry(); + + // Log the deployed address + console.log("Registry deployed to:", address(registry)); + + vm.stopBroadcast(); + } + + +} diff --git a/src/Registry.sol b/src/Registry.sol index 0864b85..879b790 100644 --- a/src/Registry.sol +++ b/src/Registry.sol @@ -38,10 +38,14 @@ contract Registry { error NotUnregistered(); error UnregistrationDelayNotMet(); error NoCollateralToClaim(); - + error FraudProofMerklePathInvalid(); + error FraudProofChallengeInvalid(); // Events event OperatorRegistered(bytes32 operatorCommitment, uint32 registeredAt); - event OperatorUnregistered(bytes32 operatorCommitment, uint32 unregisteredAt); + event OperatorUnregistered( + bytes32 operatorCommitment, + uint32 unregisteredAt + ); event OperatorDeleted(bytes32 operatorCommitment, uint72 amountToReturn); function register( @@ -116,10 +120,37 @@ contract Registry { function slashRegistration( bytes32 operatorCommitment, - bytes32[] calldata proof, BLS12381.G1Point calldata pubkey, - BLS12381.G2Point calldata signature - ) external {} + BLS12381.G2Point calldata signature, + bytes32 proxyKey, + bytes32[] calldata proof, + uint256 leafIndex + ) external { + Operator storage operator = commitments[operatorCommitment]; + + uint256[2] memory pubkeyBytes = pubkey.compress(); // compressed bls pubkey + uint256[8] memory signatureBytes = signature.flatten(); // flattened registration signature + + // reconstruct leaf + bytes32 leaf = sha256(abi.encodePacked( + pubkeyBytes, + sha256(abi.encodePacked(signatureBytes, proxyKey)) + )); + + // verify proof against operatorCommitment + if (MerkleUtils.verifyProof(proof, operatorCommitment, leaf, leafIndex)) { + revert FraudProofMerklePathInvalid(); + } + + // reconstruct message todo + bytes memory message = bytes(""); + + // verify signature + bytes memory domainSeparator = bytes(""); + if (verifySignature(message, signature, pubkey, domainSeparator)) { + revert FraudProofChallengeInvalid(); + } + } function unregister(bytes32 operatorCommitment) external { Operator storage operator = commitments[operatorCommitment]; diff --git a/src/lib/BLS12381.sol b/src/lib/BLS12381.sol index 4c0de44..0d4f291 100644 --- a/src/lib/BLS12381.sol +++ b/src/lib/BLS12381.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Functions in this library have been adapted from: // https://github.com/ethyla/bls12-381-hash-to-curve/blob/main/src/HashToCurve.sol -pragma solidity 0.8.25; +pragma solidity >=0.8.0 <0.9.0; library BLS12381 { using BLS12381 for *; diff --git a/src/lib/Merkelize.sol b/src/lib/Merkelize.sol index 49de88b..c52e1d4 100644 --- a/src/lib/Merkelize.sol +++ b/src/lib/Merkelize.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.25; +pragma solidity >=0.8.0 <0.9.0; library MerkleUtils { diff --git a/test/Registry.t.sol b/test/Registry.t.sol index aac4511..a2fbf14 100644 --- a/test/Registry.t.sol +++ b/test/Registry.t.sol @@ -76,15 +76,6 @@ contract RegistryTest is Test { 0xa95176133a52fbf43979f46c0658010c573c093f3814a5d4dded92b52d197dff ] }); - - /** - * Expected output using DST as empty string "": 0x0000000000000000000000000000000000000000000000000000000000000001 - */ - - // bytes memory domainSeparator = bytes("Taiko Based Rollup Preconfirmation v0.1.0"); - // bytes memory domainSeparator = bytes(0x0000000000000000000000000000000000000000000000000000000000000001); - // bytes memory domainSeparator = bytes(""); - // bytes memory domainSeparator = hex"0000000000000000000000000000000000000000000000000000000000000001"; bytes memory domainSeparator = hex""; require(registry.verifySignature(message, signature, pubkey, domainSeparator), "Signature verification failed");