Skip to content

SIMD-0387: BLS Pubkey Management in Vote Account.#387

Merged
simd-bot[bot] merged 44 commits into
solana-foundation:mainfrom
wen-coding:bls_pubkey_management_in_vote_account
Nov 21, 2025
Merged

SIMD-0387: BLS Pubkey Management in Vote Account.#387
simd-bot[bot] merged 44 commits into
solana-foundation:mainfrom
wen-coding:bls_pubkey_management_in_vote_account

Conversation

@wen-coding
Copy link
Copy Markdown
Contributor

  • Add BLS Pubkey Management in Vote Account for Alpenglow.

@wen-coding wen-coding changed the title SIMD-387: BLS Pubkey Management in Vote Account. SIMD-0387: BLS Pubkey Management in Vote Account. Oct 28, 2025
Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
Comment on lines +91 to +93
Since BLS verification is expensive (in the order of ~1 millisecond), these
operations changing BLS public key will need to have correct CU specified to
succeed (actual numbers to be measured and published later).
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are you saying we should change the Vote program to use different CU consumption amounts per-instruction? That should be specified in here, and we should probably include the new values themselves.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added. I don't think we have the actual numbers now, need to test that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@samkim-crypto confirmed it's about 801us to 1.15ms in benchmark. I'll check with @tao-stones the actual CU numbers we would need.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes it is 801us on my local machine and 1.15ms on my remote dev machine. My remote dev machine matches the ed25519 sigverify cost pretty closely, so 1.15 is probably a more correct number.

But the precise CU would depend on how/where we execute the verification: one syscall, multiple syscalls inside the vote program or CPI into a BLS program.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

To be consistent, using current conversion rate of 30cu per 1 micro-sec, 1.15ms converts to 34,500 CU. It exceeds 3,000 MAX builtin allocation CUs. (As a reference, currently all vote instructions have 2,100 CUs). So the v2 vote needs to be excluded from "builtin " list. Also, to echo @buffalojoec 's point, are all instructions do same BLS verifications therefore cost same CUs, or they can be different?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! The new instructions/new variants all do the same BLS verification and they should cost the same amount of CUs.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah we should exclude these from the builtin list.. We could exclude the vote program completely since AFAIK simple vote transactions don't go through that code path and other vote related transactions are relatively rare and then 3k -> 200k default cost per vote ix is not very impactful.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, do I need to write that into this SIMD?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, I think so — excluding the Vote program from the built-in list would affect consensus. It’d be great if you could include what @jstarry mentioned in the section where the Vote program is defined.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added, see if what I added make sense?

Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
Comment on lines +129 to +133
- AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS)

Changing the vote authority public key and BLS public key for existing vote
account without using seed: (we can also use it to add BLS public key to
existing vote account, just check vote authority public key didn’t change)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the BLS key is set, I can't use the old instruction to change my vote authority, right? Otherwise, the BLS key would be out-of-step. So, we need to deprecate and fully disable that instruction in order to add this one.

You could alternatively just add a new variant for the instruction input. Then you can use the existing instruction, and the SIMD can specify Vote program behavior that rejects updates to voter address without corresponding BLS proof of possession, if BLS key is set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think the alternative above would also allow AuthorizeCheckedWithSeed to just have a behavioral change and also capture the new variant in authorization_type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually only care about touching vote authority pubkey, for other changes I'm fine to have old instructions go through, but it's going to be confusing to user, so maybe better to move everything to new instructions.

If capturing the new variant in authorization_type does the work, then I'm fine with it. All I care is:

  • Must specify BLS pubkey when creating new account
  • Whenever vote authority pubkey changes, BLS pubkey must change with it

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't see why we couldn't do a new variant in VoteAuthorize. I think the program would just have to have a feature gate that changes its behavior once the new variant is activated. It should disallow changes to the Voter variant if a BLS pubkey is set.

We would need this behavior with the existing instruction anyway, so IMO it's cleaner to just add a variant to the input rather than a new instruction.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm totally fine with that. @jstarry what do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Chatted a bit with @buffalojoec about this. I don't mind either approach (new variant in VoteAuthorize or new instruction). But I think that if we go with a new instruction it would be pretty nice because we could remove the clock sysvar account input and make it specific to the vote authority and not need to worry about supporting "WithSeed" because that's really only useful for the withdraw authority anyways.

In either case, @buffalojoec is right that we can't allow voters to use the old instruction (or variant) to change the vote authority if a BLS key is already set. This behavior needs to be detailed in this SIMD.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While I can appreciate the ability to remove the sysvar accounts, my opinion is that it feels a bit like scope creep and I think the new VoteAuthorize variant is a cleaner solution right now. Vote and VoteSwitch will still need Clock anyway, and we can always just remove the need for such accounts, in a completely backwards-compatible way, either separate from this SIMD or whenever the program is migrated on-chain post-Alpenglow.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Does the current change look correct then?

@wen-coding wen-coding requested a review from apfitzge October 28, 2025 17:29
Comment on lines +96 to +98
corresponding BLS keypair. Then the vote program can do a syscall to actually
verify the validity of BLS public key. If the verification fails, the
transaction will fail.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There's no precedent for native programs making syscalls that I know of. We should probably add a BLS program which can verify the BLS key proof of possession. Then, the vote program can invoke the BLS program to verify the proof.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added that to "Alternatives Considered".

Comment on lines +129 to +133
- AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS)

Changing the vote authority public key and BLS public key for existing vote
account without using seed: (we can also use it to add BLS public key to
existing vote account, just check vote authority public key didn’t change)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Chatted a bit with @buffalojoec about this. I don't mind either approach (new variant in VoteAuthorize or new instruction). But I think that if we go with a new instruction it would be pretty nice because we could remove the clock sysvar account input and make it specific to the vote authority and not need to worry about supporting "WithSeed" because that's really only useful for the withdraw authority anyways.

In either case, @buffalojoec is right that we can't allow voters to use the old instruction (or variant) to change the vote authority if a BLS key is already set. This behavior needs to be detailed in this SIMD.

Comment on lines +107 to +112
// Will be totally forbidden, use InitializeAccountV2
InitializeAccount(VoteInit),
// Forbidden when VoteAuthorize is VoteAuthorize::Voter
AuthorizeChecked(VoteAuthorize),
// Forbidden when authorization_type is VoteAuthorize::Voter
AuthorizeCheckedWithSeed(VoteAuthorizeWithSeedArgs),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should have a period of time where both legacy and alpenglow instructions are active to give us time to migrate offchain tooling like the CLI commands for creating vote accounts. But as discussed, we should not allow using the VoteAuthorize::Voter variant if the BLS pubkey is already configured for a vote account.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Changed, how does this look?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this comment still relevant if we don't do new instructions and instead do the new VoteAuthorize variant? I think no - since it appears outdated - but wanted to double-check as I review!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think forbid VoteAuthorize::Voter when the BLS pubkey is already configured is probably enough, this guarantees once you have a BLS pubkey it is always valid. For those people rejecting to write BLS pubkey to their vote account, allowing them to do VoteAuthorize::Voter is not end of the world, we will kick them out eventually per SIMD 357.

operations changing BLS public key will need to have correct CU specified to
succeed (actual numbers to be measured and added to this PR).

#### Disallow change of vote authority by old instructions
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

VoteInstruction::Authorize and AuthorizeWithSeed also exist. We need to address changes for those instructions as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added.

program, see "Alternatives Considered" for comparison with other solutions.

Since BLS verification is expensive (in the order of ~1 millisecond), these
operations changing BLS public key will need to have correct CU specified to
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you clarify that CU's must be consumed right before doing BLS signature verification? And cc @tao-stones for discussing the CU number given time for BLS verification.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yup, already asked Tao and he estimate 1.15ms running time translates to 34,500 CU. Updated that in the PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

34,500 CU for BLS verification is based on current 30cu per 1us - questioned here if vote program be excluded from "builtin". @jstarry if this is the case?

@wen-coding wen-coding requested a review from jstarry November 5, 2025 05:10
lidatong
lidatong previously approved these changes Nov 20, 2025
@simd-bot
Copy link
Copy Markdown

simd-bot Bot commented Nov 20, 2025

Thanks, @lidatong!

⚠️ Status: Cannot merge yet

Copy link
Copy Markdown
Contributor

@qkniep qkniep left a comment

Choose a reason for hiding this comment

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

Looks good to me, just some last nits. Thanks for adding the PoP specification.

Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
Comment thread proposals/0387-bls-pubkey-management-in-vote-account.md Outdated
- The attacker sees this PoP signature in the transaction and sends in another
transaction grabbing the BLS public key before user A

- Now user A cannot use the BLS public key generated for his own vote account
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we say that we check whether the public key is already in use? I don't see it.

Copy link
Copy Markdown
Contributor Author

@wen-coding wen-coding Nov 21, 2025

Choose a reason for hiding this comment

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

We don't enforce it anywhere, but we can emit a warning in CLI if the public key is already in use. The reasons being:

  1. it's hard to perform cross account check in vote program transactions
  2. it should be cryptographically hard to generate the same private key as others
  3. the PoP proof above guarantees you can't easily claim a BLS keypair you don't own by replay attack
    So without checking we should still be okay.

wen-coding and others added 2 commits November 21, 2025 08:04
Co-authored-by: Quentin Kniep <hello@quentinkniep.com>
Co-authored-by: Quentin Kniep <hello@quentinkniep.com>
@simd-bot
Copy link
Copy Markdown

simd-bot Bot commented Nov 21, 2025

Thanks, @bw-solana!

⚠️ Status: Cannot merge yet

@simd-bot
Copy link
Copy Markdown

simd-bot Bot commented Nov 21, 2025

✅ All approvals received! @wen-coding, you can now merge this by commenting /merge.

Status: Ready to merge

@wen-coding
Copy link
Copy Markdown
Contributor Author

✅ All approvals received! @wen-coding, you can now merge this by commenting /merge.

Status: Ready to merge

/merge

@wen-coding
Copy link
Copy Markdown
Contributor Author

/merge

@simd-bot simd-bot Bot merged commit a47c8f1 into solana-foundation:main Nov 21, 2025
2 checks passed
@simd-bot
Copy link
Copy Markdown

simd-bot Bot commented Nov 21, 2025

✅ Merge successful! @wen-coding's PR has been merged.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants