From 6f8f19995fe92a879b0edac57d0806a0119efdde Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:06:48 -0700 Subject: [PATCH 01/44] SIMD-387: BLS Pubkey Management in Vote Account. --- ...7-bls-pubkey-management-in-vote-account.md | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 proposals/0387-bls-pubkey-management-in-vote-account.md diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md new file mode 100644 index 000000000..d332652df --- /dev/null +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -0,0 +1,163 @@ +--- +simd: '0387' +title: BLS Pubkey management in vote account +authors: + - Sam Kim (Anza) + - Quentin Kniep (Anza) + - Wen Xu (Anza) +category: Standard +type: Core +status: Review +created: 2025-10-27 +feature: (fill in with feature key and github tracking issues once accepted) +--- + +## Summary + +This proposal specifies in detail how a BLS public key can be generated by +users via updated existing tools and how they can put the generated BLS public +keys into their vote accounts for voting in Alpenglow per [SIMD 326](https://github.com/solana-foundation/solana-improvement-documents/pull/326) + +It also describes in detail the data structure changes needed. + +## Motivation + +The Alpenglow SIMD (326) described the new consensus protocol which will be +launched on Solana. The protocol requires efficient and safe aggregation of +validator votes to succinctly prove certain state transitions can safely happen +(for example, 60% of the validators voted to skip a slot). The ed25519 +signatures we currently use are not the best fit for this purpose, so instead +we will be using the Boneh–Lynn–Shacham (BLS) aggregate signature scheme to +sign Alpenglow votes. + +However, the BLS public key is entirely different from an ed25519 public key +(as BLS operates over a different elliptic curve), so we can’t naively reuse +the current ed25519 public keys in vote accounts either. We have to add a BLS +public key into each vote account and make that a requirement a little before +Alpenglow launches per [SIMD 357](https://github.com/solana-foundation/solana-improvement-documents/pull/357). + +## New Terminology + +- **BLS public key**: The public key used in BLS signatures. Its size is 48 +bytes in vote accounts, the field name is bls_pubkey_compressed (we will +uncompress it later into 96 bytes, but that’s internal implementation details). + +## Detailed Design + +BLS keypairs can be generated randomly like ed25519 keypairs. But to save the +users some trouble on keypair management, we chose to derive their BLS keypair +used in Alpenglow votes based on their ed25519 vote keypair. In other words, +with an existing ed25519 vote keypair, the users can safely regenerate the +associated BLS keypair on demand. + +### User Operations Support + +Since a user’s BLS keypair always changes with the vote authority keypair, we +list three different scenarios below. + +1. Creating a new vote account + +After VoteStateV4 (SIMD 185) is enabled everywhere, when users use +create-vote-account to create a new vote account, the correct BLS public key +will be automatically added to the new vote account. The BLS public key is +derived from the vote authority keypair (if authorized-voter is not specified, +identity keypair is used). + +2. Changing vote authority keypair on existing vote account + +After VoteStateV4 (SIMD 185) is enabled everywhere, when users use +vote-authorize-voter-checked to update vote authority keypair, the correct BLS +public key will be automatically updated in the vote account. The BLS public +key rotation happens at the same time when a new vote authority switch happens. + +3. Updating missing BLS public key on existing vote account + +This is a temporary work-around before all existing staked vote accounts have +proper BLS public keys specified. We will add update-bls-pubkey command so it +will use the given vote authority keypair to generate and update the BLS public +key in the vote account. When everyone has a proper BLS public key in their +vote accounts this command can be removed. + +### Validator Operation Considerations + +When starting a validator, the users are supposed to provide all ed25519 +keypairs like before. The BLS keypair will automatically be derived from the +vote authority keypair (if that’s missing, then the identity keypair is used +like now). The operations needed to switch the keypair and the operations +needed to switch to a standby node are the same as today. + +### New instructions to vote programs + +In the following instructions, there is a proof_of_knowledge field associated +with the new BLS public key. Since we need to verify the caller really holds +the BLS public key claimed, the caller needs to prove possession of the BLS +keypair to the vote program by signing the BLS public key with the +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. + +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). + +We will be adding the following three instructions: + +```rust +pub enum VoteInstruction { + InitializeAccountWithBLS(VoteInitWithBLS), + AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS), + AuthorizeCheckedWithSeedAndBLS(VoteAuthorizeCheckedWithSeedAndBLS) +} +``` + +- InitializeAccountWithBLS(VoteInitWithBLS) + +The main difference between this and InitializeAccount is that VoteInitWithBLS +will contain a new field in addition to the ones in VoteInit: + +```rust + +/// Size of a BLS signature in a compressed point representation +pub const BLS_SIGNATURE_COMPRESSED_SIZE: usize = 96; + +pub struct VoteInitWithBLS { + pub node_pubkey: Pubkey, + pub authorized_voter: Pubkey, + pub authorized_withdrawer: Pubkey, + pub commission: u8, + pub bls_pubkey_compressed: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], + // signing bls_pubkey with bls keypair + pub proof_of_knowledge: pub [u8; BLS_SIGNATURE_COMPRESSED_SIZE], +} +``` + +In addition to the original checks, it also checks that proof of knowledge is +correctly signed. + +- 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) + +```rust +pub enum VoteAuthorizeWithBLS { + Voter(bls_pubkey_compressed, proof_of_knowledge), + Withdrawer, +} +``` + +- AuthorizeCheckedWithSeedAndBLS(VoteAuthorizeCheckedWithSeedAndBLS) + +Changing the vote authority public key and BLS public key for existing vote +account 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) + +```rust +pub struct VoteAuthorizeCheckedWithSeedAndBLS { + pub authorization_type: VoteAuthorizeWithBLS, + pub current_authority_derived_key_owner: Pubkey, + pub current_authority_derived_key_seed: String, + pub new_authority: Pubkey, +} +``` \ No newline at end of file From 29a6d380347e9a22a7288464af588e0fc690a031 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:13:41 -0700 Subject: [PATCH 02/44] Add in missing sections. --- ...7-bls-pubkey-management-in-vote-account.md | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index d332652df..92014e308 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -78,14 +78,6 @@ will use the given vote authority keypair to generate and update the BLS public key in the vote account. When everyone has a proper BLS public key in their vote accounts this command can be removed. -### Validator Operation Considerations - -When starting a validator, the users are supposed to provide all ed25519 -keypairs like before. The BLS keypair will automatically be derived from the -vote authority keypair (if that’s missing, then the identity keypair is used -like now). The operations needed to switch the keypair and the operations -needed to switch to a standby node are the same as today. - ### New instructions to vote programs In the following instructions, there is a proof_of_knowledge field associated @@ -160,4 +152,20 @@ pub struct VoteAuthorizeCheckedWithSeedAndBLS { pub current_authority_derived_key_seed: String, pub new_authority: Pubkey, } -``` \ No newline at end of file +``` + +## Impact + +When starting a validator, the users are supposed to provide all ed25519 +keypairs like before. The BLS keypair will automatically be derived from the +vote authority keypair (if that’s missing, then the identity keypair is used +like now). The operations needed to switch the keypair and the operations +needed to switch to a standby node are the same as today. + +## Security Considerations + +The safety of BLS votes in Alpenglow is still guarded by the ed25519 vote +authority keypair, so users are supposed to safe guard it like before. + +## Alternatives Considered +NA \ No newline at end of file From 9c9ead5e8271a47350c1d82bf1f30cd1e0732e84 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:14:25 -0700 Subject: [PATCH 03/44] Make linter happy. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 1 + 1 file changed, 1 insertion(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 92014e308..049b036dc 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -168,4 +168,5 @@ The safety of BLS votes in Alpenglow is still guarded by the ed25519 vote authority keypair, so users are supposed to safe guard it like before. ## Alternatives Considered + NA \ No newline at end of file From 229b6018b7eb8ea3ff5ed70b81ccd5d7a0852dfa Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 15:16:22 -0700 Subject: [PATCH 04/44] Explain alternatives. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 049b036dc..713b643c5 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -169,4 +169,6 @@ authority keypair, so users are supposed to safe guard it like before. ## Alternatives Considered -NA \ No newline at end of file +We could randomly generate a new BLS keypair, it does mean users need to +separately maintain another different format of keypair. So we are deriving +the BLS keypair from the existing ed25519 keypair. \ No newline at end of file From eed2c3814ac55cb67f54c5e4d7f5567c5bbc5765 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 20:35:08 -0700 Subject: [PATCH 05/44] Mention BLS rogue-key attack in security considerations. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 713b643c5..d98763df9 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -167,6 +167,12 @@ needed to switch to a standby node are the same as today. The safety of BLS votes in Alpenglow is still guarded by the ed25519 vote authority keypair, so users are supposed to safe guard it like before. +We need to have the proof of knowledge in the instruction inputs so we can +guard against BLS rogue-key attack. If you allow anyone to randomly choose a +public key, then the attacker can select a particular key which interacts with +other participants' keys so a forged aggregate signature verifies even though +not all honest parties actually signed. + ## Alternatives Considered We could randomly generate a new BLS keypair, it does mean users need to From e8e24d3e67969c206d64a45fef278e571b01ece9 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 20:44:29 -0700 Subject: [PATCH 06/44] Reword the BLS rogue key attack a bit. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index d98763df9..689173fc8 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -168,10 +168,10 @@ The safety of BLS votes in Alpenglow is still guarded by the ed25519 vote authority keypair, so users are supposed to safe guard it like before. We need to have the proof of knowledge in the instruction inputs so we can -guard against BLS rogue-key attack. If you allow anyone to randomly choose a -public key, then the attacker can select a particular key which interacts with -other participants' keys so a forged aggregate signature verifies even though -not all honest parties actually signed. +guard against BLS rogue-key attack. If anyone is allowed to randomly choose a +public key, then an attacker can select a particular public key which interacts +with other participants' keys so a forged aggregate signature verifies even +though not all honest parties actually signed. ## Alternatives Considered From 39033d522cd0009e8aa3ea38bf4570f77c159686 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 27 Oct 2025 20:47:21 -0700 Subject: [PATCH 07/44] Proof of knowledge -> Proof of possession --- .../0387-bls-pubkey-management-in-vote-account.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 689173fc8..ea2c573fe 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -80,7 +80,7 @@ vote accounts this command can be removed. ### New instructions to vote programs -In the following instructions, there is a proof_of_knowledge field associated +In the following instructions, there is a proof_of_possession field associated with the new BLS public key. Since we need to verify the caller really holds the BLS public key claimed, the caller needs to prove possession of the BLS keypair to the vote program by signing the BLS public key with the @@ -119,11 +119,11 @@ pub struct VoteInitWithBLS { pub commission: u8, pub bls_pubkey_compressed: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], // signing bls_pubkey with bls keypair - pub proof_of_knowledge: pub [u8; BLS_SIGNATURE_COMPRESSED_SIZE], + pub proof_of_possession: pub [u8; BLS_SIGNATURE_COMPRESSED_SIZE], } ``` -In addition to the original checks, it also checks that proof of knowledge is +In addition to the original checks, it also checks that proof of possession is correctly signed. - AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS) @@ -134,7 +134,7 @@ existing vote account, just check vote authority public key didn’t change) ```rust pub enum VoteAuthorizeWithBLS { - Voter(bls_pubkey_compressed, proof_of_knowledge), + Voter(bls_pubkey_compressed, proof_of_possession), Withdrawer, } ``` @@ -167,7 +167,7 @@ needed to switch to a standby node are the same as today. The safety of BLS votes in Alpenglow is still guarded by the ed25519 vote authority keypair, so users are supposed to safe guard it like before. -We need to have the proof of knowledge in the instruction inputs so we can +We need to have the proof of possession in the instruction inputs so we can guard against BLS rogue-key attack. If anyone is allowed to randomly choose a public key, then an attacker can select a particular public key which interacts with other participants' keys so a forged aggregate signature verifies even From d0dde55374424bb87a298f2b5a63a7b0a84fa42c Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 28 Oct 2025 10:25:43 -0700 Subject: [PATCH 08/44] Address pr comments. --- ...7-bls-pubkey-management-in-vote-account.md | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index ea2c573fe..be0c5a183 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -16,7 +16,7 @@ feature: (fill in with feature key and github tracking issues once accepted) This proposal specifies in detail how a BLS public key can be generated by users via updated existing tools and how they can put the generated BLS public -keys into their vote accounts for voting in Alpenglow per [SIMD 326](https://github.com/solana-foundation/solana-improvement-documents/pull/326) +keys into their vote accounts for voting in Alpenglow. It also describes in detail the data structure changes needed. @@ -34,13 +34,23 @@ However, the BLS public key is entirely different from an ed25519 public key (as BLS operates over a different elliptic curve), so we can’t naively reuse the current ed25519 public keys in vote accounts either. We have to add a BLS public key into each vote account and make that a requirement a little before -Alpenglow launches per [SIMD 357](https://github.com/solana-foundation/solana-improvement-documents/pull/357). +Alpenglow launches. + +## Dependencies + +- Alpenglow is specified in [SIMD 326](https://github.com/solana-foundation/solana-improvement-documents/pull/326) + +- VoteStateV4 is specified in [SIMD 185](https://github.com/solana-foundation/solana-improvement-documents/pull/185) +and it adds an optional BLS public key field + +- Requiring BLS public key for Alpenglow is specified in [SIMD 357](https://github.com/solana-foundation/solana-improvement-documents/pull/357) + +- The BLS verification syscall is specified in [SIMD 388](https://github.com/solana-foundation/solana-improvement-documents/pull/388) ## New Terminology -- **BLS public key**: The public key used in BLS signatures. Its size is 48 -bytes in vote accounts, the field name is bls_pubkey_compressed (we will -uncompress it later into 96 bytes, but that’s internal implementation details). +- **BLS public key**: The public key used in BLS signatures. It will be +stored as a 48 bytes vector in vote account. ## Detailed Design @@ -57,11 +67,10 @@ list three different scenarios below. 1. Creating a new vote account -After VoteStateV4 (SIMD 185) is enabled everywhere, when users use -create-vote-account to create a new vote account, the correct BLS public key -will be automatically added to the new vote account. The BLS public key is -derived from the vote authority keypair (if authorized-voter is not specified, -identity keypair is used). +After VoteStateV4 (SIMD 185) is enabled everywhere, when users create a new +vote account, the correct BLS public key will be automatically added to the +new vote account. The BLS public key is derived from the vote authority keypair +(if authorized voter is not specified, identity keypair is used). 2. Changing vote authority keypair on existing vote account @@ -90,7 +99,9 @@ transaction will fail. 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). +succeed (actual numbers to be measured and published later). We will make +the new instructions added below use different CU consumption amounts, detailed +numbers will be updated in this SIMD after testing the new syscall. We will be adding the following three instructions: From 5de2954876f6ae79c0e5315d911318c24cedd03b Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 30 Oct 2025 09:14:04 -0700 Subject: [PATCH 09/44] Specify that it's a compressed BLS pubkey. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index be0c5a183..81b8c786f 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -49,8 +49,8 @@ and it adds an optional BLS public key field ## New Terminology -- **BLS public key**: The public key used in BLS signatures. It will be -stored as a 48 bytes vector in vote account. +- **BLS public key**: The compressed public key used in BLS signatures. It will +be stored as a 48 bytes vector in vote account. ## Detailed Design From a8e44f94212516ae791818591bc87cedf53d67eb Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 30 Oct 2025 13:29:19 -0700 Subject: [PATCH 10/44] Clarify the new vote program additions and add BLS syscall/program to Alternatives Considered. --- ...7-bls-pubkey-management-in-vote-account.md | 134 ++++++++++-------- 1 file changed, 72 insertions(+), 62 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 81b8c786f..a1e66c87a 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -45,8 +45,6 @@ and it adds an optional BLS public key field - Requiring BLS public key for Alpenglow is specified in [SIMD 357](https://github.com/solana-foundation/solana-improvement-documents/pull/357) -- The BLS verification syscall is specified in [SIMD 388](https://github.com/solana-foundation/solana-improvement-documents/pull/388) - ## New Terminology - **BLS public key**: The compressed public key used in BLS signatures. It will @@ -74,10 +72,10 @@ new vote account. The BLS public key is derived from the vote authority keypair 2. Changing vote authority keypair on existing vote account -After VoteStateV4 (SIMD 185) is enabled everywhere, when users use -vote-authorize-voter-checked to update vote authority keypair, the correct BLS -public key will be automatically updated in the vote account. The BLS public -key rotation happens at the same time when a new vote authority switch happens. +After VoteStateV4 (SIMD 185) is enabled everywhere, when users update the vote +authority keypair, the correct BLS public key will be automatically updated in +the vote account. The BLS public key rotation happens at the same time when a +new vote authority switch happens. 3. Updating missing BLS public key on existing vote account @@ -87,83 +85,77 @@ will use the given vote authority keypair to generate and update the BLS public key in the vote account. When everyone has a proper BLS public key in their vote accounts this command can be removed. -### New instructions to vote programs +### Changes to vote program -In the following instructions, there is a proof_of_possession field associated -with the new BLS public key. Since we need to verify the caller really holds -the BLS public key claimed, the caller needs to prove possession of the BLS -keypair to the vote program by signing the BLS public key with the -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. +Whenever a new BLS public key is being updated in the vote account, we need +to perform BLS verification on its validity, see "Security Considerations" +for details. We plan to implement this by calling BLS library from the vote +program, see "Alternatives Considered" for details. 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). We will make -the new instructions added below use different CU consumption amounts, detailed -numbers will be updated in this SIMD after testing the new syscall. +succeed (actual numbers to be measured and added to this PR). + +All of the changes below depend on the launch of VoteStateV4. + +#### Disallow change of vote authority by old instructions -We will be adding the following three instructions: +After the feature gate associated with this SIMD is activated, the previous +instructions will be disallowed to change vote authority, they will result +in transaction error. These include: ```rust -pub enum VoteInstruction { - InitializeAccountWithBLS(VoteInitWithBLS), - AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS), - AuthorizeCheckedWithSeedAndBLS(VoteAuthorizeCheckedWithSeedAndBLS) -} +InitializeAccount(VoteInit), // Will be totally forbidden, use InitializeAccountV2 +AuthorizeChecked(VoteAuthorize), // When VoteAuthorize is VoteAuthorize::Voter +AuthorizeCheckedWithSeed(VoteAuthorizeWithSeedArgs), // When authorization_type is VoteAuthorize::Voter ``` -- InitializeAccountWithBLS(VoteInitWithBLS) - -The main difference between this and InitializeAccount is that VoteInitWithBLS -will contain a new field in addition to the ones in VoteInit: +#### Add InitializeAccountV2 ```rust +InitializeAccountV2(VoteInitV2), +``` -/// Size of a BLS signature in a compressed point representation +```rust +pub const BLS_PUBLIC_KEY_COMPRESSED_SIZE: usize = 48; pub const BLS_SIGNATURE_COMPRESSED_SIZE: usize = 96; -pub struct VoteInitWithBLS { - pub node_pubkey: Pubkey, - pub authorized_voter: Pubkey, - pub authorized_withdrawer: Pubkey, - pub commission: u8, - pub bls_pubkey_compressed: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], - // signing bls_pubkey with bls keypair - pub proof_of_possession: pub [u8; BLS_SIGNATURE_COMPRESSED_SIZE], +pub struct VoteInitV2 { + pub note_pubkey: Pubkey, + pub authorized_voter: Pubkey, + pub authorized_voter_bls_pubkey: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], + pub authorized_voter_bls_proof_of_possession: [u8; BLS_SIGNATURE_COMPRESSED_SIZE], + pub authorized_withdrawer: Pubkey, + pub inflation_rewards_commission_bps: u16, + pub inflation_rewards_collector: Pubkey, + pub block_revenue_commission_bps: u16, + pub block_revenue_collector: Pubkey, } ``` -In addition to the original checks, it also checks that proof of possession is -correctly signed. - -- AuthorizeCheckedWithBLS(VoteAuthorizeWithBLS) +Upon receiving the transaction, the vote program will perform a BLS +verification on submitted BLS public key and associated proof of +possession. The transaction will fail if the verification failed. +Otherwise the new vote account is created with given parameters. -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) +#### Add new variant of VoteAuthorize ```rust -pub enum VoteAuthorizeWithBLS { - Voter(bls_pubkey_compressed, proof_of_possession), +pub enum VoteAuthorize { + Voter, Withdrawer, + VoterWithBLS( + [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], // BLS public key + [u8; BLS_SIGNATURE_COMPRESSED_SIZE], // BLS Proof of Posession + ), } ``` -- AuthorizeCheckedWithSeedAndBLS(VoteAuthorizeCheckedWithSeedAndBLS) - -Changing the vote authority public key and BLS public key for existing vote -account 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) - -```rust -pub struct VoteAuthorizeCheckedWithSeedAndBLS { - pub authorization_type: VoteAuthorizeWithBLS, - pub current_authority_derived_key_owner: Pubkey, - pub current_authority_derived_key_seed: String, - pub new_authority: Pubkey, -} -``` +We only allow the new variant in AuthorizeCheck instruction. Upon receiving the +AuthorizeCheck transaction, if the parameter is of the new variant, the vote +program will perform a BLS verification on submitted BLS public key and +associated proof of possession. The transaction will fail if the verification +failed. Otherwise the vote authority change will be recorded in vote account. ## Impact @@ -186,6 +178,24 @@ though not all honest parties actually signed. ## Alternatives Considered -We could randomly generate a new BLS keypair, it does mean users need to -separately maintain another different format of keypair. So we are deriving -the BLS keypair from the existing ed25519 keypair. \ No newline at end of file +### Moving BLS verification to a syscall and/or a different program + +The benefit of this approach is conceptually cleaner because vote program +does not need to know about any BLS operation, also the BLS syscall and/or +program can be generally used outside the vote program as well. + +However, before Alpenglow launches, we still want to keep the vote program +native because it needs to process a lot of vote transactions. Performing +a syscall from a native program adds quite some complexity. Also because it +is a new syscall, we might need to frequently adjust the interface based on +our findings. + +Therefore, the current plan is to perform these steps: + +1. Directly call the BLS library from the native vote program for the necessary +BLS verification operations. + +2. Launch Alpenglow. + +3. After Alpenglow launches, add BLS syscall and/or program and move vote +program to BPF. \ No newline at end of file From b71247b130d7723ef41a163ab173206f067f3f7e Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 30 Oct 2025 13:33:59 -0700 Subject: [PATCH 11/44] Specifying the new variant will fail in all other instructions. --- .../0387-bls-pubkey-management-in-vote-account.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index a1e66c87a..08f069418 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -151,11 +151,12 @@ pub enum VoteAuthorize { } ``` -We only allow the new variant in AuthorizeCheck instruction. Upon receiving the -AuthorizeCheck transaction, if the parameter is of the new variant, the vote -program will perform a BLS verification on submitted BLS public key and -associated proof of possession. The transaction will fail if the verification -failed. Otherwise the vote authority change will be recorded in vote account. +We only allow the new variant in AuthorizeCheck instruction. Calling the new +variant in any other instruction will fail. Upon receiving the AuthorizeCheck +transaction, if the parameter is of the new variant, the vote program will +perform a BLS verification on submitted BLS public key and associated proof of +possession. The transaction will fail if the verification failed. Otherwise the +vote authority change will be recorded in vote account. ## Impact From 3197a17aa40998fc262dac2a3428f6660941fff1 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 30 Oct 2025 13:36:10 -0700 Subject: [PATCH 12/44] Make linter happy. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 08f069418..1e9b78968 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -105,9 +105,12 @@ instructions will be disallowed to change vote authority, they will result in transaction error. These include: ```rust -InitializeAccount(VoteInit), // Will be totally forbidden, use InitializeAccountV2 -AuthorizeChecked(VoteAuthorize), // When VoteAuthorize is VoteAuthorize::Voter -AuthorizeCheckedWithSeed(VoteAuthorizeWithSeedArgs), // When authorization_type is VoteAuthorize::Voter +// 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), ``` #### Add InitializeAccountV2 From 629daad483fecea3dc1c79e71eb22270cb8ffc3b Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Mon, 3 Nov 2025 10:29:29 -0800 Subject: [PATCH 13/44] Some small fixes. --- ...7-bls-pubkey-management-in-vote-account.md | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 1e9b78968..8f4feeee2 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -47,8 +47,8 @@ and it adds an optional BLS public key field ## New Terminology -- **BLS public key**: The compressed public key used in BLS signatures. It will -be stored as a 48 bytes vector in vote account. +- **BLS public key**: The public key used in BLS signatures. It will be +compressed and stored as a 48 bytes vector in vote account. ## Detailed Design @@ -61,26 +61,27 @@ associated BLS keypair on demand. ### User Operations Support Since a user’s BLS keypair always changes with the vote authority keypair, we -list three different scenarios below. +list three different scenarios below. The following are all dependent on the +feature associated with this SIMD being rolled out, the operations will not +change before the feature is active. 1. Creating a new vote account -After VoteStateV4 (SIMD 185) is enabled everywhere, when users create a new -vote account, the correct BLS public key will be automatically added to the -new vote account. The BLS public key is derived from the vote authority keypair -(if authorized voter is not specified, identity keypair is used). +When users create a new vote account, the correct BLS public key will be +automatically added to the new vote account. The BLS public key is derived +from the vote authority keypair (if authorized voter is not specified, identity +keypair is used). 2. Changing vote authority keypair on existing vote account -After VoteStateV4 (SIMD 185) is enabled everywhere, when users update the vote -authority keypair, the correct BLS public key will be automatically updated in -the vote account. The BLS public key rotation happens at the same time when a -new vote authority switch happens. +When users update the vote authority keypair, the correct BLS public key will +be automatically updated in the vote account. The BLS public key rotation +happens at the same time when a new vote authority switch happens. 3. Updating missing BLS public key on existing vote account This is a temporary work-around before all existing staked vote accounts have -proper BLS public keys specified. We will add update-bls-pubkey command so it +proper BLS public keys specified. We will add `update-bls-pubkey` command so it will use the given vote authority keypair to generate and update the BLS public key in the vote account. When everyone has a proper BLS public key in their vote accounts this command can be removed. @@ -90,19 +91,17 @@ vote accounts this command can be removed. Whenever a new BLS public key is being updated in the vote account, we need to perform BLS verification on its validity, see "Security Considerations" for details. We plan to implement this by calling BLS library from the vote -program, see "Alternatives Considered" for details. +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 succeed (actual numbers to be measured and added to this PR). -All of the changes below depend on the launch of VoteStateV4. - #### Disallow change of vote authority by old instructions After the feature gate associated with this SIMD is activated, the previous instructions will be disallowed to change vote authority, they will result -in transaction error. These include: +in transaction errors. These include: ```rust // Will be totally forbidden, use InitializeAccountV2 @@ -137,9 +136,9 @@ pub struct VoteInitV2 { ``` Upon receiving the transaction, the vote program will perform a BLS -verification on submitted BLS public key and associated proof of -possession. The transaction will fail if the verification failed. -Otherwise the new vote account is created with given parameters. +verification on submitted BLS public key and associated proof of possession. +The transaction will fail if the verification failed. Otherwise the new vote +account is created with given parameters. #### Add new variant of VoteAuthorize @@ -184,7 +183,7 @@ though not all honest parties actually signed. ### Moving BLS verification to a syscall and/or a different program -The benefit of this approach is conceptually cleaner because vote program +The benefit is that it is conceptually cleaner because vote program does not need to know about any BLS operation, also the BLS syscall and/or program can be generally used outside the vote program as well. From 561edb28b51044480b9f14f1b087f18854248da2 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 4 Nov 2025 13:25:03 -0800 Subject: [PATCH 14/44] Update enum new variant definition. --- .../0387-bls-pubkey-management-in-vote-account.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 8f4feeee2..4d777fd7c 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -143,13 +143,15 @@ account is created with given parameters. #### Add new variant of VoteAuthorize ```rust +pub struct VoterWithBLSArgs { + bls_pub_key: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], + bls_proof_of_possession: [u8; BLS_SIGNATURE_COMPRESSED_SIZE], +} + pub enum VoteAuthorize { Voter, Withdrawer, - VoterWithBLS( - [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], // BLS public key - [u8; BLS_SIGNATURE_COMPRESSED_SIZE], // BLS Proof of Posession - ), + VoterWithBLS(VoterWithBLSArgs), } ``` From 34a576b8e67a56cab792e3bf71bbc175e4275f1e Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 4 Nov 2025 21:09:11 -0800 Subject: [PATCH 15/44] Address pr comments. --- ...7-bls-pubkey-management-in-vote-account.md | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 4d777fd7c..c12e3659c 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -93,23 +93,31 @@ to perform BLS verification on its validity, see "Security Considerations" for details. We plan to implement this by calling BLS library from the vote 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 -succeed (actual numbers to be measured and added to this PR). +Since BLS verification is expensive (around 1.15ms), these operations changing +BLS public key will need to have consume 34,500 CU right before BLS signature +verification happens. #### Disallow change of vote authority by old instructions After the feature gate associated with this SIMD is activated, the previous -instructions will be disallowed to change vote authority, they will result -in transaction errors. These include: +instructions will be disallowed to change vote authority after off-chain tools +are upgraded, they will result in transaction errors. These include: ```rust -// Will be totally forbidden, use InitializeAccountV2 +// Will be forbidden after off-chain tools are upgraded, use InitializeAccountV2 InitializeAccount(VoteInit), -// Forbidden when VoteAuthorize is VoteAuthorize::Voter +// Forbidden when VoteAuthorize is VoteAuthorize::Voter and the account has BLS +// public key +Authorize(Pubkey, VoteAuthorize), +// Forbidden when authorization_type is VoteAuthorize::Voter and the account has +// BLS public key +AuthorizeWithSeed(VoteAuthorizeWithSeedArgs), +// Forbidden when VoteAuthorize is VoteAuthorize::Voter and the account has BLS +// public key AuthorizeChecked(VoteAuthorize), -// Forbidden when authorization_type is VoteAuthorize::Voter -AuthorizeCheckedWithSeed(VoteAuthorizeWithSeedArgs), +// Forbidden when authorization_type is VoteAuthorize::Voter and the account has +// BLS public key +AuthorizeCheckedWithSeed(VoteAuthorizeCheckedWithSeedArgs), ``` #### Add InitializeAccountV2 From 109feeed6b2c301fce84470ccaf4c988043fd05e Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 5 Nov 2025 16:52:45 -0800 Subject: [PATCH 16/44] Add proposal to remove vote program from using builtin CU limit. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index c12e3659c..db393d464 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -97,6 +97,13 @@ Since BLS verification is expensive (around 1.15ms), these operations changing BLS public key will need to have consume 34,500 CU right before BLS signature verification happens. +Currently the vote program is still using the builtin CU, and each instruction +consumes 3,000 CU. We propose to completely remove the vote program from using +the built in CU. Because simple vote transactions do not use the code path +where the CU limit matters, and there are very few other transactions executed +in the vote program. We can make those transactions consume correct CU based +on the amount of CPU they would consume. + #### Disallow change of vote authority by old instructions After the feature gate associated with this SIMD is activated, the previous From 4129dd0f6e719a590224747009c43741447bebee Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:28:34 -0800 Subject: [PATCH 17/44] Update proposals/0387-bls-pubkey-management-in-vote-account.md Co-authored-by: Joe C --- proposals/0387-bls-pubkey-management-in-vote-account.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index db393d464..6fe83bf0f 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -48,7 +48,7 @@ and it adds an optional BLS public key field ## New Terminology - **BLS public key**: The public key used in BLS signatures. It will be -compressed and stored as a 48 bytes vector in vote account. +compressed and stored as a 48-byte array in vote account. ## Detailed Design From 2166bb6ad5b23a9e0700752be367ef87441af35d Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:29:33 -0800 Subject: [PATCH 18/44] Update proposals/0387-bls-pubkey-management-in-vote-account.md Co-authored-by: Joe C --- .../0387-bls-pubkey-management-in-vote-account.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 6fe83bf0f..bf09f22ae 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -93,9 +93,15 @@ to perform BLS verification on its validity, see "Security Considerations" for details. We plan to implement this by calling BLS library from the vote program, see "Alternatives Considered" for comparison with other solutions. -Since BLS verification is expensive (around 1.15ms), these operations changing -BLS public key will need to have consume 34,500 CU right before BLS signature -verification happens. +Since BLS verification is expensive (around 1.15ms), each verification will cost +34,500 CUs. Any Vote program instruction that performs a BLS verification will +therefore add 34,500 CUs per verification on top of its baseline cost. As a result, +Vote program instructions - which currently all cost 2,100 CUs - will have +differentiated CU costs depending on whether they include BLS verification. The +updated CU values are detailed in later sections. + +Note the 34,500 CUs for BLS verification will be consumed immediately before +the verification is performed. Currently the vote program is still using the builtin CU, and each instruction consumes 3,000 CU. We propose to completely remove the vote program from using From c6c617c33d3accd5d509835b310a1217af21286e Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:30:33 -0800 Subject: [PATCH 19/44] Update proposals/0387-bls-pubkey-management-in-vote-account.md Co-authored-by: Joe C --- .../0387-bls-pubkey-management-in-vote-account.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index bf09f22ae..0623ff4bb 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -103,12 +103,11 @@ updated CU values are detailed in later sections. Note the 34,500 CUs for BLS verification will be consumed immediately before the verification is performed. -Currently the vote program is still using the builtin CU, and each instruction -consumes 3,000 CU. We propose to completely remove the vote program from using -the built in CU. Because simple vote transactions do not use the code path -where the CU limit matters, and there are very few other transactions executed -in the vote program. We can make those transactions consume correct CU based -on the amount of CPU they would consume. +Currently the vote program is allocated a budget of 3,000 CUs in the validator's +builtin program cost modeling mechanism. Simple vote transactions (containing a +`Vote` instruction) already bypass this mechanism, and other Vote program +instructions that may use BLS verification are fairly infrequent. As a result, the Vote +program will be removed from builtin program cost modeling. #### Disallow change of vote authority by old instructions From d61ea12935f4be5cc8ba10c218f0e109c12d8d92 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:44:35 -0800 Subject: [PATCH 20/44] Make linter happy. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 0623ff4bb..d9f6f730a 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -106,8 +106,8 @@ the verification is performed. Currently the vote program is allocated a budget of 3,000 CUs in the validator's builtin program cost modeling mechanism. Simple vote transactions (containing a `Vote` instruction) already bypass this mechanism, and other Vote program -instructions that may use BLS verification are fairly infrequent. As a result, the Vote -program will be removed from builtin program cost modeling. +instructions that may use BLS verification are fairly infrequent. As a result, +the Vote program will be removed from builtin program cost modeling. #### Disallow change of vote authority by old instructions From d6ffd1de3763eaa574393c02b20d55bf9d14b8a9 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:31:06 -0800 Subject: [PATCH 21/44] Shorten some paragraphs. --- ...7-bls-pubkey-management-in-vote-account.md | 54 ++++--------------- 1 file changed, 9 insertions(+), 45 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index d9f6f730a..28d1e3587 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -58,33 +58,9 @@ used in Alpenglow votes based on their ed25519 vote keypair. In other words, with an existing ed25519 vote keypair, the users can safely regenerate the associated BLS keypair on demand. -### User Operations Support - -Since a user’s BLS keypair always changes with the vote authority keypair, we -list three different scenarios below. The following are all dependent on the -feature associated with this SIMD being rolled out, the operations will not -change before the feature is active. - -1. Creating a new vote account - -When users create a new vote account, the correct BLS public key will be -automatically added to the new vote account. The BLS public key is derived -from the vote authority keypair (if authorized voter is not specified, identity -keypair is used). - -2. Changing vote authority keypair on existing vote account - -When users update the vote authority keypair, the correct BLS public key will -be automatically updated in the vote account. The BLS public key rotation -happens at the same time when a new vote authority switch happens. - -3. Updating missing BLS public key on existing vote account - -This is a temporary work-around before all existing staked vote accounts have -proper BLS public keys specified. We will add `update-bls-pubkey` command so it -will use the given vote authority keypair to generate and update the BLS public -key in the vote account. When everyone has a proper BLS public key in their -vote accounts this command can be removed. +When users create vote accounts, they must register their BLS public key by +storing it in the newly created vote account. When they modify their vote +authority, they must re-register the new corresponding BLS key. ### Changes to vote program @@ -205,22 +181,10 @@ though not all honest parties actually signed. ### Moving BLS verification to a syscall and/or a different program -The benefit is that it is conceptually cleaner because vote program -does not need to know about any BLS operation, also the BLS syscall and/or -program can be generally used outside the vote program as well. - -However, before Alpenglow launches, we still want to keep the vote program -native because it needs to process a lot of vote transactions. Performing -a syscall from a native program adds quite some complexity. Also because it -is a new syscall, we might need to frequently adjust the interface based on -our findings. - -Therefore, the current plan is to perform these steps: - -1. Directly call the BLS library from the native vote program for the necessary -BLS verification operations. - -2. Launch Alpenglow. +Another option is we can put BLS verification into a separate program or +into a syscall. -3. After Alpenglow launches, add BLS syscall and/or program and move vote -program to BPF. \ No newline at end of file +We choose not to do this now because currently vote program needs to handle +a lot of vote transactions so it's a native program. We may explore this +option later if the vote program is migrated to an on-chain BPF program after +Alpenglow launches. \ No newline at end of file From fa25fbb04a43936d4b11d882adfa5b820a3a0f05 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:06:32 -0800 Subject: [PATCH 22/44] Address comments. --- ...7-bls-pubkey-management-in-vote-account.md | 38 ++++++++----------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 28d1e3587..ce0f31d1c 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -91,22 +91,18 @@ After the feature gate associated with this SIMD is activated, the previous instructions will be disallowed to change vote authority after off-chain tools are upgraded, they will result in transaction errors. These include: -```rust -// Will be forbidden after off-chain tools are upgraded, use InitializeAccountV2 -InitializeAccount(VoteInit), -// Forbidden when VoteAuthorize is VoteAuthorize::Voter and the account has BLS -// public key -Authorize(Pubkey, VoteAuthorize), -// Forbidden when authorization_type is VoteAuthorize::Voter and the account has -// BLS public key -AuthorizeWithSeed(VoteAuthorizeWithSeedArgs), -// Forbidden when VoteAuthorize is VoteAuthorize::Voter and the account has BLS -// public key -AuthorizeChecked(VoteAuthorize), -// Forbidden when authorization_type is VoteAuthorize::Voter and the account has -// BLS public key -AuthorizeCheckedWithSeed(VoteAuthorizeCheckedWithSeedArgs), -``` +- Authorize(Pubkey, VoteAuthorize): when VoteAuthorize is VoteAuthorize::Voter +and the account has BLS public key it will fail + +- AuthorizeWithSeed(VoteAuthorizeWithSeedArgs): when authorization_type is +VoteAuthorize::Voter and the account has BLS public key it will fail + +- AuthorizeChecked(VoteAuthorize): when VoteAuthorize is VoteAuthorize::Voter +and the account has BLS public key it will fail + +- AuthorizeCheckedWithSeed(VoteAuthorizeCheckedWithSeedArgs): when +authorization_type is VoteAuthorize::Voter and the account has BLS public key +it will fail #### Add InitializeAccountV2 @@ -151,12 +147,10 @@ pub enum VoteAuthorize { } ``` -We only allow the new variant in AuthorizeCheck instruction. Calling the new -variant in any other instruction will fail. Upon receiving the AuthorizeCheck -transaction, if the parameter is of the new variant, the vote program will -perform a BLS verification on submitted BLS public key and associated proof of -possession. The transaction will fail if the verification failed. Otherwise the -vote authority change will be recorded in vote account. +Upon receiving the transaction, if the parameter is of the new variant, the +vote program will perform a BLS verification on submitted BLS public key and +associated proof of possession. The transaction will fail if the verification +failed. Otherwise the vote authority change will be recorded in vote account. ## Impact From 6c46ae40bbfc15a8753edf9acaf8f371cea67568 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:49:20 -0800 Subject: [PATCH 23/44] Small change. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index ce0f31d1c..cfcdc2ac1 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -175,8 +175,8 @@ though not all honest parties actually signed. ### Moving BLS verification to a syscall and/or a different program -Another option is we can put BLS verification into a separate program or -into a syscall. +We can put BLS verification into a separate program or into a syscall, this is +conceptually cleaner. We choose not to do this now because currently vote program needs to handle a lot of vote transactions so it's a native program. We may explore this From e7f671962d9d0ac6ee765a92d8752b2498b7f237 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:05:07 -0800 Subject: [PATCH 24/44] Address Sam's comments, fix typo and add PoP definition. --- ...7-bls-pubkey-management-in-vote-account.md | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index cfcdc2ac1..b78ec0c1d 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -104,6 +104,24 @@ and the account has BLS public key it will fail authorization_type is VoteAuthorize::Voter and the account has BLS public key it will fail +#### Proof of Possession Calculation + +While a standard Proof of Possession (PoP) is simply a signature over the +public key itself (σ=Signsk​(pk)), this can leave room for "binding theft" +where a valid PoP is intercepted and registered to an attacker's vote account. +To prevent this and cross-chain replay, the PoP must sign a domain-separated +message binding the key to its specific context. + +The signature verification must use the following message structure: +``` +message=label ∣∣ vote_account_address ∣∣ chain_id ∣∣ bls_pubkey_bytes +```rust + +Where: +`label` is a constant string (e.g., "SOL_BLS_POP_V1"). +`vote_account_address` is the authorized_voter Ed25519 public key. +`chain_id` is the genesis hash or chain identifier. + #### Add InitializeAccountV2 ```rust @@ -115,7 +133,7 @@ pub const BLS_PUBLIC_KEY_COMPRESSED_SIZE: usize = 48; pub const BLS_SIGNATURE_COMPRESSED_SIZE: usize = 96; pub struct VoteInitV2 { - pub note_pubkey: Pubkey, + pub node_pubkey: Pubkey, pub authorized_voter: Pubkey, pub authorized_voter_bls_pubkey: [u8; BLS_PUBLIC_KEY_COMPRESSED_SIZE], pub authorized_voter_bls_proof_of_possession: [u8; BLS_SIGNATURE_COMPRESSED_SIZE], From 89d114ed67997f158922f8a2e8db91640777a0fb Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:06:11 -0800 Subject: [PATCH 25/44] Fix typo again --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index b78ec0c1d..6fdfcb685 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -113,9 +113,9 @@ To prevent this and cross-chain replay, the PoP must sign a domain-separated message binding the key to its specific context. The signature verification must use the following message structure: -``` -message=label ∣∣ vote_account_address ∣∣ chain_id ∣∣ bls_pubkey_bytes ```rust +message=label ∣∣ vote_account_address ∣∣ chain_id ∣∣ bls_pubkey_bytes +``` Where: `label` is a constant string (e.g., "SOL_BLS_POP_V1"). From b5330ae2797bfd94c0b4efce78c60d52d9df989c Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 08:12:50 -0800 Subject: [PATCH 26/44] Make linter happy. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 6fdfcb685..7c7ffcd11 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -107,12 +107,13 @@ it will fail #### Proof of Possession Calculation While a standard Proof of Possession (PoP) is simply a signature over the -public key itself (σ=Signsk​(pk)), this can leave room for "binding theft" +public key itself (`σ=Signsk​(pk)`), this can leave room for "binding theft" where a valid PoP is intercepted and registered to an attacker's vote account. To prevent this and cross-chain replay, the PoP must sign a domain-separated message binding the key to its specific context. The signature verification must use the following message structure: + ```rust message=label ∣∣ vote_account_address ∣∣ chain_id ∣∣ bls_pubkey_bytes ``` From aee4d34a78dcafe844f837d4f1a4bfe0293be7ba Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 09:35:03 -0800 Subject: [PATCH 27/44] Clarify proof of possession calculation. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 7c7ffcd11..c8d123970 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -115,13 +115,13 @@ message binding the key to its specific context. The signature verification must use the following message structure: ```rust -message=label ∣∣ vote_account_address ∣∣ chain_id ∣∣ bls_pubkey_bytes +message=label ∣∣ chain_id ∣∣ authorized_voter_pubkey ∣∣ bls_pubkey_bytes ``` Where: -`label` is a constant string (e.g., "SOL_BLS_POP_V1"). -`vote_account_address` is the authorized_voter Ed25519 public key. -`chain_id` is the genesis hash or chain identifier. +`label` is a constant string, we will make it "Alpenglow" here. +`chain_id` is the genesis hash of the chain. +`authorized_voter_pubkey` is the authorized_voter Ed25519 public key. #### Add InitializeAccountV2 From c423fa86ca77b60782c22f41f77367c7d30e3837 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 09:38:41 -0800 Subject: [PATCH 28/44] Add newlines between items. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index c8d123970..3853b9aaf 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -119,9 +119,12 @@ message=label ∣∣ chain_id ∣∣ authorized_voter_pubkey ∣∣ bls_pubkey_b ``` Where: -`label` is a constant string, we will make it "Alpenglow" here. -`chain_id` is the genesis hash of the chain. -`authorized_voter_pubkey` is the authorized_voter Ed25519 public key. + +- `label` is a constant string, we will make it "Alpenglow" here. + +- `chain_id` is the genesis hash of the chain. + +- `authorized_voter_pubkey` is the authorized_voter Ed25519 public key. #### Add InitializeAccountV2 From 03cff6580453edab5fa1d9bcb0a54943ffffa9f7 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:45:19 -0800 Subject: [PATCH 29/44] Describe the replay attack in PoP generation. --- .../0387-bls-pubkey-management-in-vote-account.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 3853b9aaf..8f49101f9 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -193,6 +193,16 @@ public key, then an attacker can select a particular public key which interacts with other participants' keys so a forged aggregate signature verifies even though not all honest parties actually signed. +We also need to put ed25519 public key in Proof of Possession calculation +because a replay attack exists: + +- User A wants to update vote authority, calculates PoP signature + +- 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 + ## Alternatives Considered ### Moving BLS verification to a syscall and/or a different program From eb96fd60b3fb524a76605ad4963b140b69595543 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:47:05 -0800 Subject: [PATCH 30/44] Explain the other fields as well. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 8f49101f9..ea888a43d 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -126,6 +126,8 @@ Where: - `authorized_voter_pubkey` is the authorized_voter Ed25519 public key. +See "Security Considerations" for why the fields are needed. + #### Add InitializeAccountV2 ```rust @@ -203,6 +205,9 @@ transaction grabbing the BLS public key before user A - Now user A cannot use the BLS public key generated for his own vote account +We also add a label so in the future we can update the version, and add a +`chain_id` so attackers can't do cross-chain replay attack. + ## Alternatives Considered ### Moving BLS verification to a syscall and/or a different program From 8b00dae6cb98988556a2c8320f2c13d37f4d81f1 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 10:52:04 -0800 Subject: [PATCH 31/44] Clarify the fields in security considerations. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index ea888a43d..bf93d9ca2 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -195,7 +195,7 @@ public key, then an attacker can select a particular public key which interacts with other participants' keys so a forged aggregate signature verifies even though not all honest parties actually signed. -We also need to put ed25519 public key in Proof of Possession calculation +We need to put `authorized_voter_pubkey` in Proof of Possession calculation because a replay attack exists: - User A wants to update vote authority, calculates PoP signature @@ -205,7 +205,7 @@ transaction grabbing the BLS public key before user A - Now user A cannot use the BLS public key generated for his own vote account -We also add a label so in the future we can update the version, and add a +We also add a `label` so in the future we can update the version, and add a `chain_id` so attackers can't do cross-chain replay attack. ## Alternatives Considered From 01e88650015c57abda5384196cab0a3dde7c4217 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Wed, 19 Nov 2025 11:19:11 -0800 Subject: [PATCH 32/44] Clarify label is upper case. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index bf93d9ca2..a874c599c 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -120,7 +120,8 @@ message=label ∣∣ chain_id ∣∣ authorized_voter_pubkey ∣∣ bls_pubkey_b Where: -- `label` is a constant string, we will make it "Alpenglow" here. +- `label` is a constant string, we will make it "ALPENGLOW" here (all upper +case). - `chain_id` is the genesis hash of the chain. From a6a8ef007284097ea34abef10891afd3ce960ac9 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:17:32 -0800 Subject: [PATCH 33/44] Address pr comments. --- .../0387-bls-pubkey-management-in-vote-account.md | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index a874c599c..5c39aec5e 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -32,9 +32,9 @@ sign Alpenglow votes. However, the BLS public key is entirely different from an ed25519 public key (as BLS operates over a different elliptic curve), so we can’t naively reuse -the current ed25519 public keys in vote accounts either. We have to add a BLS -public key into each vote account and make that a requirement a little before -Alpenglow launches. +the current ed25519 public keys in vote accounts either. Each validator must +add a BLS public into their vote account before the network enables Alpenglow +in order to vote. ## Dependencies @@ -45,17 +45,12 @@ and it adds an optional BLS public key field - Requiring BLS public key for Alpenglow is specified in [SIMD 357](https://github.com/solana-foundation/solana-improvement-documents/pull/357) -## New Terminology - -- **BLS public key**: The public key used in BLS signatures. It will be -compressed and stored as a 48-byte array in vote account. - ## Detailed Design BLS keypairs can be generated randomly like ed25519 keypairs. But to save the users some trouble on keypair management, we chose to derive their BLS keypair used in Alpenglow votes based on their ed25519 vote keypair. In other words, -with an existing ed25519 vote keypair, the users can safely regenerate the +with an existing ed25519 vote keypair, the operators can safely regenerate the associated BLS keypair on demand. When users create vote accounts, they must register their BLS public key by @@ -179,7 +174,7 @@ failed. Otherwise the vote authority change will be recorded in vote account. ## Impact -When starting a validator, the users are supposed to provide all ed25519 +When starting a validator, the operators are supposed to provide all ed25519 keypairs like before. The BLS keypair will automatically be derived from the vote authority keypair (if that’s missing, then the identity keypair is used like now). The operations needed to switch the keypair and the operations From 02cc97c95e2792f29554e492c6f9475ce6912588 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:19:49 -0800 Subject: [PATCH 34/44] Make linter happy. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 5c39aec5e..b55ca6456 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -36,6 +36,10 @@ the current ed25519 public keys in vote accounts either. Each validator must add a BLS public into their vote account before the network enables Alpenglow in order to vote. +## New Terminology + +N/A + ## Dependencies - Alpenglow is specified in [SIMD 326](https://github.com/solana-foundation/solana-improvement-documents/pull/326) From c3813cbd2da90bc4a0d0132f5d8d28ac71c154ac Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:25:44 -0800 Subject: [PATCH 35/44] Explain PoP calculation and verification. --- .../0387-bls-pubkey-management-in-vote-account.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index b55ca6456..e73c98ffa 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -103,7 +103,7 @@ and the account has BLS public key it will fail authorization_type is VoteAuthorize::Voter and the account has BLS public key it will fail -#### Proof of Possession Calculation +#### Proof of Possession calculation and verification While a standard Proof of Possession (PoP) is simply a signature over the public key itself (`σ=Signsk​(pk)`), this can leave room for "binding theft" @@ -111,7 +111,7 @@ where a valid PoP is intercepted and registered to an attacker's vote account. To prevent this and cross-chain replay, the PoP must sign a domain-separated message binding the key to its specific context. -The signature verification must use the following message structure: +The PoP calculation and verification must use the following message structure: ```rust message=label ∣∣ chain_id ∣∣ authorized_voter_pubkey ∣∣ bls_pubkey_bytes @@ -126,8 +126,18 @@ case). - `authorized_voter_pubkey` is the authorized_voter Ed25519 public key. +- `bls_pubkey_bytes` is the compressed new BLS public key (48 bytes). + See "Security Considerations" for why the fields are needed. +During PoP calculation, the user uses the BLS private key to sign this message +to generate the signature, compress it, and save in +`authorized_voter_bls_proof_of_possession`. + +During PoP verification, the validator will construct the same message, then +check that the expected signature matches the given one under given BLS public +key. + #### Add InitializeAccountV2 ```rust From 9382ffa1934f7181c3d7936f52c17f852f416597 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:29:04 -0800 Subject: [PATCH 36/44] Clarify a bit. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index e73c98ffa..5888ca9da 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -135,8 +135,8 @@ to generate the signature, compress it, and save in `authorized_voter_bls_proof_of_possession`. During PoP verification, the validator will construct the same message, then -check that the expected signature matches the given one under given BLS public -key. +check that the `authorized_voter_bls_proof_of_possession` is the correct +signature. #### Add InitializeAccountV2 From e81fa9ef8ca4271c829f6b21d3499ac3da7e0107 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 09:30:13 -0800 Subject: [PATCH 37/44] Clarify more. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 5888ca9da..73dfcffba 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -117,7 +117,7 @@ The PoP calculation and verification must use the following message structure: message=label ∣∣ chain_id ∣∣ authorized_voter_pubkey ∣∣ bls_pubkey_bytes ``` -Where: +Where: (|| above is concatenation) - `label` is a constant string, we will make it "ALPENGLOW" here (all upper case). From 5296d19ea0c8017c57c9d28be25d9f1f2c7d9961 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:21:44 -0800 Subject: [PATCH 38/44] Address pr comments. --- ...7-bls-pubkey-management-in-vote-account.md | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 73dfcffba..295480880 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -52,10 +52,13 @@ and it adds an optional BLS public key field ## Detailed Design BLS keypairs can be generated randomly like ed25519 keypairs. But to save the -users some trouble on keypair management, we chose to derive their BLS keypair -used in Alpenglow votes based on their ed25519 vote keypair. In other words, -with an existing ed25519 vote keypair, the operators can safely regenerate the -associated BLS keypair on demand. +users some trouble on keypair management, we chose to initially derive their +BLS keypair used in Alpenglow votes based on their ed25519 vote keypair. In +other words, with an existing ed25519 vote keypair, the operators can safely +regenerate the associated BLS keypair on demand. Also during validator +operations, the users still only need to supply the vote keypair as before. +After Alpenglow launches we may get rid of ed25519 vote keypair and allow users +to randomly generate BLS keypairs. When users create vote accounts, they must register their BLS public key by storing it in the newly created vote account. When they modify their vote @@ -188,6 +191,19 @@ failed. Otherwise the vote authority change will be recorded in vote account. ## Impact +### Before feature gate in this SIMD is activated + +There is no change, users cannot update their BLS public key in vote account. + +### After the feature gate in this SIMD is activated but before Alpenglow launch + +Users can update their BLS public key in the vote account. + +### After Alpenglow launch + +Per SIMD 357, only vote accounts with updated BLS public key can participate +in the voting process. + When starting a validator, the operators are supposed to provide all ed25519 keypairs like before. The BLS keypair will automatically be derived from the vote authority keypair (if that’s missing, then the identity keypair is used From cba1c98de7bf2e8d1b2a421d58f27be17b770359 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:34:00 -0800 Subject: [PATCH 39/44] Clarify the cli will do everything for the user. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 295480880..b8b9ba7cd 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -133,9 +133,9 @@ case). See "Security Considerations" for why the fields are needed. -During PoP calculation, the user uses the BLS private key to sign this message -to generate the signature, compress it, and save in -`authorized_voter_bls_proof_of_possession`. +During PoP calculation, the cli will generate the BLS keypair, then use the BLS +private key to sign this message to generate the signature, compress it, and +save it in `authorized_voter_bls_proof_of_possession`. During PoP verification, the validator will construct the same message, then check that the `authorized_voter_bls_proof_of_possession` is the correct From 3ec74073048f0e33844ba9f551d4da3228f4cafa Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:35:18 -0800 Subject: [PATCH 40/44] Fix english. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index b8b9ba7cd..4f6fc731f 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -137,7 +137,7 @@ During PoP calculation, the cli will generate the BLS keypair, then use the BLS private key to sign this message to generate the signature, compress it, and save it in `authorized_voter_bls_proof_of_possession`. -During PoP verification, the validator will construct the same message, then +During PoP verification, the validators will construct the same message, then check that the `authorized_voter_bls_proof_of_possession` is the correct signature. From b88c205fa0be63b0f9d59f03d89b32a09df0aba8 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 13:54:47 -0800 Subject: [PATCH 41/44] Clarify a bit. --- .../0387-bls-pubkey-management-in-vote-account.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 4f6fc731f..4e574ac9e 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -52,13 +52,13 @@ and it adds an optional BLS public key field ## Detailed Design BLS keypairs can be generated randomly like ed25519 keypairs. But to save the -users some trouble on keypair management, we chose to initially derive their -BLS keypair used in Alpenglow votes based on their ed25519 vote keypair. In -other words, with an existing ed25519 vote keypair, the operators can safely -regenerate the associated BLS keypair on demand. Also during validator -operations, the users still only need to supply the vote keypair as before. -After Alpenglow launches we may get rid of ed25519 vote keypair and allow users -to randomly generate BLS keypairs. +users some trouble on keypair management, the current plan is to initially +derive their BLS keypair used in Alpenglow votes based on their ed25519 vote +keypair. In other words, with an existing ed25519 vote keypair, the operators +can safely regenerate the associated BLS keypair on demand. Also during +validator operations, the users still only need to supply the vote keypair as +before. After Alpenglow launches we may get rid of ed25519 vote keypair and +allow users to randomly generate BLS keypairs. When users create vote accounts, they must register their BLS public key by storing it in the newly created vote account. When they modify their vote From 3a55e377c939c4a441c8a7631d09ef7e98954cf7 Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Thu, 20 Nov 2025 14:46:08 -0800 Subject: [PATCH 42/44] Address pr comments. --- proposals/0387-bls-pubkey-management-in-vote-account.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 4e574ac9e..c84cf5ee7 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -57,8 +57,12 @@ derive their BLS keypair used in Alpenglow votes based on their ed25519 vote keypair. In other words, with an existing ed25519 vote keypair, the operators can safely regenerate the associated BLS keypair on demand. Also during validator operations, the users still only need to supply the vote keypair as -before. After Alpenglow launches we may get rid of ed25519 vote keypair and -allow users to randomly generate BLS keypairs. +before. + +The association of BLS keypair with vote authority ed25519 keypair is the +default client behavior to simplify Alpenglow launch. After Alpenglow launches +we may get rid of ed25519 vote keypair and allow users to randomly generate BLS +keypairs. When users create vote accounts, they must register their BLS public key by storing it in the newly created vote account. When they modify their vote From 20b565796aea92910e3080e16cafa767f335f5eb Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Fri, 21 Nov 2025 08:04:41 -0800 Subject: [PATCH 43/44] Update proposals/0387-bls-pubkey-management-in-vote-account.md Co-authored-by: Quentin Kniep --- proposals/0387-bls-pubkey-management-in-vote-account.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index c84cf5ee7..468c27dbe 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -33,7 +33,7 @@ sign Alpenglow votes. However, the BLS public key is entirely different from an ed25519 public key (as BLS operates over a different elliptic curve), so we can’t naively reuse the current ed25519 public keys in vote accounts either. Each validator must -add a BLS public into their vote account before the network enables Alpenglow +add a BLS public key into their vote account before the network enables Alpenglow in order to vote. ## New Terminology From e1f1a07c29450acff1cb7a072a0063db7af4db9a Mon Sep 17 00:00:00 2001 From: Wen <113942165+wen-coding@users.noreply.github.com> Date: Fri, 21 Nov 2025 08:04:55 -0800 Subject: [PATCH 44/44] Update proposals/0387-bls-pubkey-management-in-vote-account.md Co-authored-by: Quentin Kniep --- proposals/0387-bls-pubkey-management-in-vote-account.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0387-bls-pubkey-management-in-vote-account.md b/proposals/0387-bls-pubkey-management-in-vote-account.md index 468c27dbe..4c44cb99f 100644 --- a/proposals/0387-bls-pubkey-management-in-vote-account.md +++ b/proposals/0387-bls-pubkey-management-in-vote-account.md @@ -137,7 +137,7 @@ case). See "Security Considerations" for why the fields are needed. -During PoP calculation, the cli will generate the BLS keypair, then use the BLS +During PoP calculation, the CLI will generate the BLS keypair, then use the BLS private key to sign this message to generate the signature, compress it, and save it in `authorized_voter_bls_proof_of_possession`.