From 268fae9d881c58a62d1ff135463d81f796f1f0b4 Mon Sep 17 00:00:00 2001 From: Timofey Luin Date: Wed, 6 Dec 2023 12:16:14 +0100 Subject: [PATCH] use bls accumulator instances in contract --- contracts/src/RotateLib.sol | 14 +++++++++----- contracts/src/Spectre.sol | 4 ++-- .../src/interfaces/CommitteeUpdateVerifier.sol | 2 +- .../src/mocks/CommitteeUpdateMockVerifier.sol | 2 +- contracts/test/RotateExternal.sol | 6 +++--- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/contracts/src/RotateLib.sol b/contracts/src/RotateLib.sol index 5c8fb0cd..fa701805 100644 --- a/contracts/src/RotateLib.sol +++ b/contracts/src/RotateLib.sol @@ -16,20 +16,24 @@ library RotateLib { * @param args The arguments for the sync step * @return The public input commitment that can be sent to the verifier contract. */ - function toPublicInputs(RotateInput memory args, bytes32 finalizedHeaderRoot) internal pure returns (uint256[65] memory) { - uint256[65] memory inputs; + function toPublicInputs(RotateInput memory args, bytes32 finalizedHeaderRoot, uint256[12] memory blsAccumulator) internal pure returns (uint256[77] memory) { + uint256[77] memory inputs; - inputs[0] = uint256(EndianConversions.toLittleEndian(uint256(args.syncCommitteePoseidon))); + for (uint256 i = 0; i < blsAccumulator.length; i++) { + inputs[i] = blsAccumulator[i]; + } + + inputs[blsAccumulator.length] = uint256(EndianConversions.toLittleEndian(uint256(args.syncCommitteePoseidon))); uint256 syncCommitteeSSZNumeric = uint256(args.syncCommitteeSSZ); for (uint256 i = 0; i < 32; i++) { - inputs[32 - i] = syncCommitteeSSZNumeric % 2 ** 8; + inputs[blsAccumulator.length + 32 - i] = syncCommitteeSSZNumeric % 2 ** 8; syncCommitteeSSZNumeric = syncCommitteeSSZNumeric / 2 ** 8; } uint256 finalizedHeaderRootNumeric = uint256(finalizedHeaderRoot); for (uint256 j = 0; j < 32; j++) { - inputs[64 - j] = finalizedHeaderRootNumeric % 2 ** 8; + inputs[blsAccumulator.length + 64 - j] = finalizedHeaderRootNumeric % 2 ** 8; finalizedHeaderRootNumeric = finalizedHeaderRootNumeric / 2 ** 8; } diff --git a/contracts/src/Spectre.sol b/contracts/src/Spectre.sol index 61b2f8ab..c39a9efa 100644 --- a/contracts/src/Spectre.sol +++ b/contracts/src/Spectre.sol @@ -68,7 +68,7 @@ contract Spectre { /// @param rotateProof The proof for the rotation /// @param stepInput The input to the sync step. /// @param stepProof The proof for the sync step - function rotate(RotateLib.RotateInput calldata rotateInput, bytes calldata rotateProof, SyncStepLib.SyncStepInput calldata stepInput, bytes calldata stepProof) external { + function rotate(RotateLib.RotateInput calldata rotateInput, bytes calldata rotateProof, SyncStepLib.SyncStepInput calldata stepInput, bytes calldata stepProof, uint256[12] memory blsAccumulator) external { // *step phase* // This allows trusting that the current sync committee has signed off on the finalizedHeaderRoot which is used as the base of the SSZ proof // that checks the new committee is in the beacon state 'next_sync_committee' field. It also allows trusting the finalizedSlot which is @@ -85,7 +85,7 @@ contract Spectre { // that there exists an SSZ proof that can verify this SSZ commitment to the committee is in the state uint256 currentPeriod = getSyncCommitteePeriod(stepInput.finalizedSlot); uint256 nextPeriod = currentPeriod + 1; - uint256[65] memory verifierInput = rotateInput.toPublicInputs(stepInput.finalizedHeaderRoot); + uint256[77] memory verifierInput = rotateInput.toPublicInputs(stepInput.finalizedHeaderRoot, blsAccumulator); bool rotateSuccess = committeeUpdateVerifier.verify(verifierInput, rotateProof); if (!rotateSuccess) { revert("Rotation proof verification failed"); diff --git a/contracts/src/interfaces/CommitteeUpdateVerifier.sol b/contracts/src/interfaces/CommitteeUpdateVerifier.sol index f5c96262..981e8a6b 100644 --- a/contracts/src/interfaces/CommitteeUpdateVerifier.sol +++ b/contracts/src/interfaces/CommitteeUpdateVerifier.sol @@ -2,5 +2,5 @@ pragma solidity ^0.8.0; interface CommitteeUpdateVerifier { - function verify(uint256[65] calldata input, bytes calldata proof) external returns (bool); + function verify(uint256[77] calldata input, bytes calldata proof) external returns (bool); } diff --git a/contracts/src/mocks/CommitteeUpdateMockVerifier.sol b/contracts/src/mocks/CommitteeUpdateMockVerifier.sol index d3c9ab6d..0fdbe71a 100644 --- a/contracts/src/mocks/CommitteeUpdateMockVerifier.sol +++ b/contracts/src/mocks/CommitteeUpdateMockVerifier.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import { CommitteeUpdateVerifier } from "../interfaces/CommitteeUpdateVerifier.sol"; contract CommitteeUpdateMockVerifier is CommitteeUpdateVerifier { - function verify(uint256[65] calldata _input, bytes calldata _proof) external override returns (bool) { + function verify(uint256[77] calldata _input, bytes calldata _proof) external override returns (bool) { return true; } } diff --git a/contracts/test/RotateExternal.sol b/contracts/test/RotateExternal.sol index 07d601b5..78fd352d 100644 --- a/contracts/test/RotateExternal.sol +++ b/contracts/test/RotateExternal.sol @@ -11,10 +11,10 @@ import { RotateLib } from "../src/RotateLib.sol"; contract RotateExternal { using RotateLib for RotateLib.RotateInput; - function toPublicInputs(RotateLib.RotateInput calldata args, bytes32 finalizedHeaderRoot) public pure returns (uint256[] memory) { - uint256[65] memory commitment = args.toPublicInputs(finalizedHeaderRoot); + function toPublicInputs(RotateLib.RotateInput calldata args, bytes32 finalizedHeaderRoot, uint256[12] memory blsAccumulator) public pure returns (uint256[] memory) { + uint256[77] memory commitment = args.toPublicInputs(finalizedHeaderRoot, blsAccumulator); // copy all elements into a dynamic array. We need to do this because ethers-rs has a bug that can't support uint256[65] return types - uint256[] memory result = new uint256[](65); + uint256[] memory result = new uint256[](77); for (uint256 i = 0; i < commitment.length; i++) { result[i] = commitment[i]; }