What the user achieves
Multiple users jointly control a single private account (regular or PDA) on the LEZ. From one 32-byte Group Master Secret (GMS), every member independently derives the same account keys (NSK/VSK/NPK/VPK), so any member can see and spend the shared private account without an interactive key exchange at spend time. New members are admitted by sealing the GMS to their public key and having them unseal it.
Why it matters
It lifts private accounts from one key holder only to group-owned, which can be the foundation multisig program for k-of-n control over private state. Without it there is no way for several parties to share custody of a private balance or a private PDA.
Key components
- GroupKeyHolder (
lee/key_protocol/src/key_management/group_key_holder.rs): holds the GMS and deterministically derives identical per-account keys for every member; this is the cryptographic core the wallet and circuit both rely on.
- Privacy-preserving circuit (
program_methods/guest/src/bin/privacy_preserving_circuit/): enforces authorization for private PDAs (visibility mask 3) and the tx-wide pda_family_binding check; consumes the keys/account-ids the GroupKeyHolder produces.
- Account id derivation (
lee/state_machine/core/src/program.rs): AccountId::for_private_pda(program_id, seed, npk) binds a PDA address to the group's NPK so a PDA family belongs to one group.
- Wallet group CLI (
lez/wallet/src/cli/group.rs, lez/wallet/src/cli/account.rs): user-facing commands to create groups, distribute the GMS (seal/unseal), and create shared accounts derived from a group.
- Sealing key (
SealingPublicKey/SealingSecretKey, ML-KEM-768 based): a wallet's dedicated key pair for receiving a sealed GMS, kept separate from account viewing keys.
Repository
https://github.com/logos-blockchain/logos-execution-zone
Runtime target
testnet v0.2
Prerequisites
- OS: Linux or macOS. On macOS the Risc0 guest build needs full Xcode with the Metal toolchain, not just command-line tools.
- Hardware: unit/integration tests run with
RISC0_DEV_MODE=1 (skips real proving) on a normal dev machine. Real proof generation needs substantial hardware.
- Tools: Rust toolchain,
cargo, recipes in the justfile.
- Release/commit: no released tag yet contains the complete feature.
v0.2.0-rc4 includes the circuit layer (#446) and key layer (#449) but not the wallet CLI (#460), which merged afterward. Build from main (feature complete as of the #460 merge, b4455122).
- Keys/accounts: a funded public account is needed to fund a shared account from the public side; each joining member needs a sealing key pair (
wallet group new-sealing-key).
Commands and expected outputs
Commands as a user types them (clap subcommands from `lez/wallet/src/cli/`):
# Recipient (Bob), once per wallet: generate a sealing key pair, share the printed public key
wallet group new-sealing-key
# Owner (Alice): create a group with a fresh random GMS
wallet group new test-group
# Alice: create a shared regular private account derived from the group
wallet account new private-gms test-group --label shared-acc
# Alice: seal the group's GMS for Bob using Bob's sealing public key; prints sealed GMS as hex
wallet group invite test-group --key <bob-sealing-pubkey-hex>
# Bob: unseal and store the GMS under his own local name
wallet group join my-copy --sealed <sealed-gms-hex-from-alice>
# Bob: derive his instance of the same shared account (identical keys to Alice's)
wallet account new private-gms my-copy
Shared PDA variant (group-owned PDA family):
wallet account new private-gms test-group --pda \
--seed <32-byte-hex> --program-id <program-id-hex> --identifier 0
`--identifier` diversifies one PDA from another within the same `(program_id, seed)` family; defaults to random if omitted.
Expected outputs:
- `new-sealing-key`: prints the sealing public key to share.
- `group new`: group registered locally; visible in `wallet group list` (alias `ls`).
- `account new private-gms ...`: shared account registered, tied to the group label.
- `group invite`: prints the sealed GMS as hex (1148 bytes: ML-KEM ct 1088 || nonce 12 || ciphertext+tag 48).
- `group join`: stores the GMS; both holders now derive identical keys.
Tests that prove it works:
- Key agreement (Alice and Bob derive the same NPK from a sealed/unsealed GMS): `integration_tests/tests/shared_accounts.rs::group_invite_join_key_agreement`.
- Funding a shared account from a public account and seeing the balance: `integration_tests/tests/shared_accounts.rs::fund_shared_account_from_public`.
- Group-owned PDA family receives and spends across diversified identifiers: `integration_tests/tests/private_pda.rs::private_pda_family_members_receive_and_spend`.
Success command
RISC0_DEV_MODE=1 cargo test --release -p integration_tests group_invite_join_key_agreement
Expected result
the test passes, asserting `alice_npk == bob_npk` ("same GMS produces same keys"). For the end-to-end balance path, run `fund_shared_account_from_public` and expect the shared account balance to read `100`.
Configuration details
Failure modes and limits
Out of scope for this release:
- k-of-n threshold spend control at the key layer. The key layer is 1-of-n: any GMS holder can derive every key and spend. Threshold gating is expected to live at the program layer, not here.
- View-only membership. Viewing and spending cannot be separated for a group; any GMS holder gets both.
- No released tag yet bundles the wallet CLI layer (#460).
GitHub handle
@moudyellaz
Discord handle
moudyellaz
Existing docs or specs
PRs: #446 (circuit), #449 (key), #460 (wallet CLI); follow-ups #464 (PDA address diversification, PrivatePdaForeign), #486 (external PDA seed input to circuit).
Hardware requirements
No response
Estimated time to complete
No response
Security notes
No response
What the user achieves
Multiple users jointly control a single private account (regular or PDA) on the LEZ. From one 32-byte Group Master Secret (GMS), every member independently derives the same account keys (NSK/VSK/NPK/VPK), so any member can see and spend the shared private account without an interactive key exchange at spend time. New members are admitted by sealing the GMS to their public key and having them unseal it.
Why it matters
It lifts private accounts from one key holder only to group-owned, which can be the foundation multisig program for k-of-n control over private state. Without it there is no way for several parties to share custody of a private balance or a private PDA.
Key components
lee/key_protocol/src/key_management/group_key_holder.rs): holds the GMS and deterministically derives identical per-account keys for every member; this is the cryptographic core the wallet and circuit both rely on.program_methods/guest/src/bin/privacy_preserving_circuit/): enforces authorization for private PDAs (visibility mask 3) and the tx-widepda_family_bindingcheck; consumes the keys/account-ids the GroupKeyHolder produces.lee/state_machine/core/src/program.rs):AccountId::for_private_pda(program_id, seed, npk)binds a PDA address to the group's NPK so a PDA family belongs to one group.lez/wallet/src/cli/group.rs,lez/wallet/src/cli/account.rs): user-facing commands to create groups, distribute the GMS (seal/unseal), and create shared accounts derived from a group.SealingPublicKey/SealingSecretKey, ML-KEM-768 based): a wallet's dedicated key pair for receiving a sealed GMS, kept separate from account viewing keys.Repository
https://github.com/logos-blockchain/logos-execution-zone
Runtime target
testnet v0.2
Prerequisites
RISC0_DEV_MODE=1(skips real proving) on a normal dev machine. Real proof generation needs substantial hardware.cargo, recipes in thejustfile.v0.2.0-rc4includes the circuit layer (#446) and key layer (#449) but not the wallet CLI (#460), which merged afterward. Build frommain(feature complete as of the #460 merge,b4455122).wallet group new-sealing-key).Commands and expected outputs
Success command
RISC0_DEV_MODE=1 cargo test --release -p integration_tests group_invite_join_key_agreement
Expected result
Configuration details
Failure modes and limits
Out of scope for this release:
GitHub handle
@moudyellaz
Discord handle
moudyellaz
Existing docs or specs
PRs: #446 (circuit), #449 (key), #460 (wallet CLI); follow-ups #464 (PDA address diversification,
PrivatePdaForeign), #486 (external PDA seed input to circuit).Hardware requirements
No response
Estimated time to complete
No response
Security notes
No response