Skip to content

Commit a080af6

Browse files
feat(sol): set and consume bit distribution
1 parent e57ab31 commit a080af6

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

solidity/src/base/Constants.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ uint256 constant VK_TAU_HY_REAL = 0x2bad9a374aec49d329ec66e8f530f68509313450580c
174174
uint256 constant VK_TAU_HY_IMAG = 0x219edfceee1723de674f5b2f6fdb69d9e32dd53b15844956a630d3c7cdaa6ed9;
175175

176176
/// @dev Size of the verification builder in bytes.
177-
uint256 constant VERIFICATION_BUILDER_SIZE = 0x20 * 13;
177+
uint256 constant VERIFICATION_BUILDER_SIZE = 0x20 * 14;
178178
/// @dev Offset of the pointer to the challenge queue in the verification builder.
179179
uint256 constant BUILDER_CHALLENGES_OFFSET = 0x20 * 0;
180180
/// @dev Offset of the pointer to the first round MLEs in the verification builder.
@@ -201,6 +201,8 @@ uint256 constant BUILDER_TABLE_CHI_EVALUATIONS_OFFSET = 0x20 * 10;
201201
uint256 constant BUILDER_FIRST_ROUND_COMMITMENTS_OFFSET = 0x20 * 11;
202202
/// @dev Offset of the pointer to the final round commitments in the verification builder.
203203
uint256 constant BUILDER_FINAL_ROUND_COMMITMENTS_OFFSET = 0x20 * 12;
204+
/// @dev Offset of the pointer to the final round bit distributions in the verification builder.
205+
uint256 constant BUILDER_FINAL_ROUND_BIT_DISTRIBUTIONS_OFFSET = 0x20 * 13;
204206

205207
/// @dev The initial transcript state. This is the hash of the empty string.
206208
uint256 constant INITIAL_TRANSCRIPT_STATE = 0x7c26f909f37b2c61df0bb3b19f76296469cb4d07b582a215c4e2b1f7a05527c3;

solidity/src/builder/VerificationBuilder.pre.sol

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ library VerificationBuilder {
2323
uint256[] tableChiEvaluations;
2424
uint256 firstRoundCommitmentsPtr;
2525
uint256 finalRoundCommitmentsPtr;
26+
uint256[] bitDistributions;
2627
}
2728

2829
/// @notice Allocates and reserves a block of memory for a verification builder
@@ -771,15 +772,49 @@ library VerificationBuilder {
771772
/// @param __builder The builder struct
772773
/// @param __values The bit distributions array
773774
function __setBitDistributions(Builder memory __builder, uint256[] memory __values) internal pure {
775+
assembly {
776+
function builder_set_bit_distributions(builder_ptr, values_ptr) {
777+
mstore(add(builder_ptr, BUILDER_FINAL_ROUND_BIT_DISTRIBUTIONS_OFFSET), values_ptr)
778+
}
779+
builder_set_bit_distributions(__builder, __values)
780+
}
781+
}
782+
783+
/// @notice Consumes a final round bit distribution from the verification builder
784+
/// @custom:as-yul-wrapper
785+
/// #### Wrapped Yul Function
786+
/// ##### Signature
787+
/// ```yul
788+
/// builder_consume_bit_distribution(builder_ptr) -> vary_mask, leading_bit_mask
789+
/// ```
790+
/// ##### Parameters
791+
/// * `builder_ptr` - memory pointer to the builder struct region
792+
/// ##### Return Values
793+
/// * `vary_mask` - the vary mask of the bit distribution
794+
/// * `leading_bit_mask` - the leading bit mask of the bit distribution
795+
/// @dev Dequeues and returns a final round bit distribution. Reverts with Errors.EmptyQueue if no values remain
796+
/// @param __builder The builder struct
797+
/// @return __varyMask the vary mask of the consumed bit distribution
798+
/// @return __leadingBitMask the leading bit mask of the consumed bit distribution
799+
function __consumeBitDistribution(Builder memory __builder)
800+
internal
801+
pure
802+
returns (uint256 __varyMask, uint256 __leadingBitMask)
803+
{
774804
assembly {
775805
// IMPORT-YUL ../base/Errors.sol
776806
function err(code) {
777807
revert(0, 0)
778808
}
779-
function builder_set_bit_distributions(builder_ptr, values_ptr) {
780-
if mload(values_ptr) { err(ERR_UNSUPPORTED_PROOF) }
809+
// IMPORT-YUL ../base/Queue.pre.sol
810+
function dequeue(queue_ptr) -> value {
811+
revert(0, 0)
781812
}
782-
builder_set_bit_distributions(__builder, __values)
813+
function builder_consume_bit_distribution(builder_ptr) -> vary_mask, leading_bit_mask {
814+
vary_mask := dequeue(add(builder_ptr, BUILDER_FINAL_ROUND_BIT_DISTRIBUTIONS_OFFSET))
815+
leading_bit_mask := dequeue(add(builder_ptr, BUILDER_FINAL_ROUND_BIT_DISTRIBUTIONS_OFFSET))
816+
}
817+
__varyMask, __leadingBitMask := builder_consume_bit_distribution(__builder)
783818
}
784819
}
785820

solidity/test/base/Constants.t.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ contract ConstantsTest is Test {
8585
}
8686

8787
function testVerificationBuilderOffsetsAreValid() public pure {
88-
uint256[13] memory offsets = [
88+
uint256[14] memory offsets = [
8989
BUILDER_CHALLENGES_OFFSET,
9090
BUILDER_FIRST_ROUND_MLES_OFFSET,
9191
BUILDER_FINAL_ROUND_MLES_OFFSET,
@@ -98,7 +98,8 @@ contract ConstantsTest is Test {
9898
BUILDER_COLUMN_EVALUATIONS_OFFSET,
9999
BUILDER_TABLE_CHI_EVALUATIONS_OFFSET,
100100
BUILDER_FIRST_ROUND_COMMITMENTS_OFFSET,
101-
BUILDER_FINAL_ROUND_COMMITMENTS_OFFSET
101+
BUILDER_FINAL_ROUND_COMMITMENTS_OFFSET,
102+
BUILDER_FINAL_ROUND_BIT_DISTRIBUTIONS_OFFSET
102103
];
103104
uint256 offsetsLength = offsets.length;
104105
assert(VERIFICATION_BUILDER_SIZE == offsetsLength * WORD_SIZE);

solidity/test/builder/VerificationBuilder.t.pre.sol

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -851,27 +851,38 @@ contract VerificationBuilderTest is Test {
851851
assert(VerificationBuilder.__getFinalRoundCommitments(builder) == valuesPtr);
852852
}
853853

854-
/// forge-config: default.allow_internal_expect_revert = true
855-
function testSetBitDistributions() public {
854+
function testSetBitDistributions() public pure {
856855
VerificationBuilder.Builder memory builder = VerificationBuilder.__builderNew();
857856
uint256[] memory emptyValues = new uint256[](0);
858857
// Empty array should not revert
859858
VerificationBuilder.__setBitDistributions(builder, emptyValues);
860859

861860
uint256[] memory values = new uint256[](1);
862861
values[0] = 0x12345678;
863-
vm.expectRevert(Errors.UnsupportedProof.selector);
862+
// Populated array should not revert
864863
VerificationBuilder.__setBitDistributions(builder, values);
865864
}
866865

867-
/// forge-config: default.allow_internal_expect_revert = true
868-
function testFuzzSetBitDistributions(uint256[] memory values) public {
866+
function testFuzzSetBitDistributions(uint256[] memory values) public pure {
869867
vm.assume(values.length > 0);
870868
VerificationBuilder.Builder memory builder = VerificationBuilder.__builderNew();
871-
vm.expectRevert(Errors.UnsupportedProof.selector);
872869
VerificationBuilder.__setBitDistributions(builder, values);
873870
}
874871

872+
function testConsumeBitDistributions() public pure {
873+
VerificationBuilder.Builder memory builder = VerificationBuilder.__builderNew();
874+
uint256[] memory values = new uint256[](2);
875+
values[0] = 0x12345678;
876+
values[1] = 0x12345677;
877+
// Populated array should not revert
878+
VerificationBuilder.__setBitDistributions(builder, values);
879+
uint256 varyMask;
880+
uint256 leadingBitMask;
881+
(varyMask, leadingBitMask) = VerificationBuilder.__consumeBitDistribution(builder);
882+
assert(varyMask == 0x12345678);
883+
assert(leadingBitMask == 0x12345677);
884+
}
885+
875886
function testGetChiEvaluations() public pure {
876887
VerificationBuilder.Builder memory builder;
877888
uint256[] memory values = new uint256[](3);

0 commit comments

Comments
 (0)