Skip to content

Submit Fiat-Shamir #1462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft

Submit Fiat-Shamir #1462

wants to merge 20 commits into from

Conversation

yrong
Copy link
Contributor

@yrong yrong commented Apr 25, 2025

A prototype implementation based on the spec from Bhargav. Great thanks for that.

Resolves: https://linear.app/snowfork/issue/SNO-1489

Requires: #1457

Copy link

codecov bot commented Apr 25, 2025

Codecov Report

Attention: Patch coverage is 67.18750% with 21 lines in your changes missing coverage. Please review.

Project coverage is 79.82%. Comparing base (6993ef4) to head (b844164).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
contracts/src/BeefyClient.sol 67.18% 18 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1462      +/-   ##
==========================================
- Coverage   80.21%   79.82%   -0.39%     
==========================================
  Files          20       20              
  Lines         854      917      +63     
  Branches      120      160      +40     
==========================================
+ Hits          685      732      +47     
- Misses        146      159      +13     
- Partials       23       26       +3     
Flag Coverage Δ
solidity 79.82% <67.18%> (-0.39%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@acatangiu
Copy link

I believe you also need some mechanism to reset the interactive BEEFY protocol if it was in progress when a Fiat-Shamir-based BEEFY submission is accepted by the light-client.

also, make sure to do security audit for this feature :)

@yrong
Copy link
Contributor Author

yrong commented Apr 25, 2025

need some mechanism to reset the interactive BEEFY protocol if it was in progress when a Fiat-Shamir-based BEEFY submission is accepted by the light-client.

Though I'm not sure the reset is nessessary, as we won't accept an obsolete commitment anyway.

if (commitment.blockNumber <= latestBeefyBlock) {
// ticket is obsolete
revert StaleCommitment();
}

@yrong yrong changed the base branch from main to ron/benchmark-beefy-by-signatures April 30, 2025 15:40
@yrong
Copy link
Contributor Author

yrong commented May 2, 2025

forge test --match-path test/BeefyClient.t.sol -vvv --gas-report
Function Name Min Avg Median Max # Calls
commitPrevRandao 24200 43393 46808 46808 22
submitFinal 232936 361220 249643 797277 17
submitInitial 34704 113748 130279 132558 29
submitFiatShamir 1766534 1872289 1872289 1978045 2
...

Gas cost of PreRandao submission with 28 signatures across 3 calls:
132558 + 46808 + 797277 = 976643

Gas cost of submitFiatShamir with 101 signatures:
1978045

@yrong yrong marked this pull request as ready for review May 2, 2025 06:21
Copy link

@bhargavbh bhargavbh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall LGTM. Probably we write some tests for scenario when the relayers are calling fiatShamir and interactive random sampling concurrently. In theory, the staleCommitment check in the verifier should suffice.


bytes32 bitFieldHash = keccak256(abi.encodePacked(bitfield));
bytes32 commitmentHash = keccak256(encodeCommitment(commitment));
bytes32 fiatShamirHash = keccak256(bytes.concat(commitmentHash, bitFieldHash, vset.root));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we are to rely on relative security to bitcoin mining then we have to use the same hash function sha256 when generating the fiatshamir hash (instead of keccak256 here).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using keccak256 for bitFieldHash and commitmentHash is fine

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yrong just realised that bitcoin mining uses double-SHA256 (sha256d), and there is no sha256d precompile for evm. Hence, to compute fiatShamirHash, we need to hash the output of the first hash again, i.e., sha256(sha256(concatenated_bytes)).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know! Fixed in b94851e

bytes32 commitmentHash = keccak256(encodeCommitment(commitment));
bytes32 fiatShamirHash = keccak256(bytes.concat(commitmentHash, bitFieldHash, vset.root));
uint256 requiredSignatures =
Math.min(fiatShamirRequiredSignatures, computeQuorum(vset.length));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have 2/3rd +1 honesty assumption on polkadot validators. Hence it is sufficient to check 1/3rd +1 validator signatures to ensure at least 1 honest validator signed the payload. We can get away with min(fiatShamirRequiredSignature, n/3 +1) here. This also sufficient for the random sampling protocol.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -195,6 +195,8 @@ contract BeefyClient {
*/
uint256 public immutable minNumRequiredSignatures;

uint256 constant fiatShamirRequiredSignatures = 101;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be immutable and initialized via the constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yrong yrong changed the base branch from ron/benchmark-beefy-by-signatures to main May 9, 2025 02:43
@yrong yrong requested a review from vgeddes May 11, 2025 16:15
@vgeddes vgeddes marked this pull request as draft May 22, 2025 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants