# 2025-11-03 Update
## What's New?
### Task: Show signing and encapsulation algorithm in format of `PublicKeys` and `PrivateKeys`.
The Envelope formatting of the `PrivateKeys` and `PublicKeys` type now explicitly identifies both the type and identities of their internal signing and encapsulation keys:
```
PRVKEYS=`envelope generate prvkeys`
PUBKEYS=`envelope generate pubkeys $PRVKEYS`
envelope subject type ur $PRVKEYS | envelope format
envelope subject type ur $PUBKEYS | envelope format
│ PrivateKeys(bddd8f8c, SigningPrivateKey(f5acda33, SchnorrPrivateKey(aa3b66fa)), EncapsulationPrivateKey(f9367fef, X25519PrivateKey(f9367fef)))
│ PublicKeys(37603ad1, SigningPublicKey(f781986d, SchnorrPublicKey(ef73428a)), EncapsulationPublicKey(a5124fb7, X25519PublicKey(a5124fb7)))
```
Note that the hex identifiers here are abbreviated from the `Reference` to the keys, and do not reveal anything about the keys themselves.
### Task: Provide explicit ways to specify the signing and encapsulation algorithms in keys
The `envelope generate prvkeys` command no longer generates a `ur:crypto-prvkey-base` by default. As shown in the previous example, it now generates a `ur:crypto-prvkeys`, which includes both the signing and encapsulation (`encryption` in the `envelope` tool UI) keys for particular algorithms (Schnorr and X25519 by default) and gives us a place for users to specify the algorithms they actually want to use. In this example, we explicitly create a `PrivateKeys` using ED25519 as our signing algorithm:
```
PRVKEYS=`envelope generate prvkeys --signing ed25519`
PUBKEYS=`envelope generate pubkeys $PRVKEYS`
envelope subject type ur $PRVKEYS | envelope format
envelope subject type ur $PUBKEYS | envelope format
│ PrivateKeys(81ad4584, SigningPrivateKey(76ac347d, Ed25519PrivateKey(5d20b4a0)), EncapsulationPrivateKey(c5e91887, X25519PrivateKey(c5e91887)))
│ PublicKeys(88d90933, SigningPublicKey(c5385c8f, Ed25519PublicKey(a1fae6ca)), EncapsulationPublicKey(a20a01e7, X25519PublicKey(a20a01e7)))
```
However, this two-step process: generating private keys and then deriving public keys from the private keys, does not work for all algorithm types. In particular the post-quantum *ml-dsa* and *ml-kem* algorithms don't afford deriving public keys from private keys; they ony afford generating both private and public keys together as a pair. This is why `envelope generate prvkeys` does not offer the *ml-dsa* or *ml-kem* algorithms as values for its `--signing` and `--encryption` options. These algorithms also do not afford generation of private keys deterministically; they control their own source of randomness and don't give us a way to control it ourselves.
The solution is the new `envelope generate keypairs` command, which can accept any of the algorithms we support:
For `--signing`: `schnorr` (default), `ecdsa`, `ed25519`, `ssh-ed25519`, `ssh-dsa`, `ssh-ecdsa-p256`, `ssh-ecdsa-p384`, `mldsa44`, `mldsa65`, `mldsa87`
For `--encryption`: `x25519` (default), `mlkem512`, `mlkem768`, `mlkem1024`
The `envelope generate keypairs` command outputs both a `ur:crypto-prvkeys` and its corresponding `ur:crypto-pubkeys` together on one line, separated by a single space.
Many times you will assign them both to a single shell variable:
```
KEYPAIRS=`envelope generate keypairs --signing mldsa44 --encryption mlkem512`
$echo KEYPAIRS
│ ur:crypto-prvkeys/... ur:crypto-pubkeys/...
```
But if you wish it's easy to separate them when you generate them using the shell's `read` command:
```
envelope generate keypairs --signing mldsa44 --encryption mlkem512 | read PRVKEYS PUBKEYS
echo $PRVKEYS
echo $PUBKEYS
│ ur:crypto-prvkeys/...
│ ur:crypto-pubkeys/...
```
Or if you already have them in one variable, use `read` to separate them:
```
echo $KEYPAIRS | read PRVKEYS PUBKEYS
echo $PRVKEYS
echo $PUBKEYS
│ ur:crypto-prvkeys/...
│ ur:crypto-pubkeys/...
```
Having them together in a single variable means you can now pass them as a single argument to the `xid new` and `xid key add` subcommands. So to create a `XIDDocument` that uses only post-quantum keys:
```
KEYPAIRS=`envelope generate keypairs --signing mldsa44 --encryption mlkem512`
XID_DOC=`envelope xid new $KEYPAIRS`
envelope format $XID_DOC
│ XID(1eec24c3) [
│ 'key': PublicKeys(da26ba91, SigningPublicKey(1eec24c3, MLDSA44PublicKey(fee6ddae)), EncapsulationPublicKey(a326c176, MLKEM512PublicKey(a326c176))) [
│ {
│ 'privateKey': PrivateKeys(39505c7b, SigningPrivateKey(21146f78, MLDSA44PrivateKey(e40e9019)), EncapsulationPrivateKey(6c8376f5, MLKEM512PrivateKey(6c8376f5)))
│ } [
│ 'salt': Salt
│ ]
│ 'allow': 'All'
│ ]
│ ]
```
Note that passing the private and public keys as separate arguments is *not* the same as passing them as we did above, as a single argument:
```
envelope xid new $PRVKEYS $PUBKEYS
│ error: unexpected argument 'ur:crypto-pubkeys/...' found
```
For this to work you'd need to combine them into a single argument:
```
envelope xid new "$PRVKEYS $PUBKEYS"
│ ur:xid/...
```
You can still pass just a `PublicKeys`, in which case the XID document won't contain any private keys, or a `PrivateKeys`, assuming the algorithms in them allow public derivation, or even a `ur:crypto-prvkey-base`.
Due to this new system, there was no longer any need for the `generate signer` or `generate verifier` commands, so they have been removed. A `PrivateKeys` can be used for both signing and decrypting messages, and a `PublicKeys` can be used to both encrypt to the recipient and verify signatures from them.
### Task: Clarify the relationship between `ur:seed`, `ur:crypto-prvkey-base`, `ur:crypto-prvkeys`, and `ur:crypto-pubkeys`.
The problem here was too many steps and too much time needed to introduce and explain the actually important concept: how we're handling private and public keys. So the main thing I did was to de-emphasize `Seed` and `PrivateKeyBase` in both the `envelope` tool UI as well as the documentation and examples, while keeping them as valid inputs for backwards compatibility.
If you want to explain how seeds can be used to derive keys, etc., at least you are no longer *required* to do it as a prerequisite to showing the important higher-level principles at work.
### Task: Default to `xid new` generating its own private keys
I chose to continue to require that the user specify keys, but since the default is now to include private keys in the XID, it's a simple matter to provide the key pair for any set of algorithms. For example:
```
envelope generate keypairs --signing ed25519 | envelope xid new | envelope format
│ XID(e813b144) [
│ 'key': PublicKeys(82fb1c2b, SigningPublicKey(e813b144, Ed25519PublicKey(bdcc74bc)), EncapsulationPublicKey(561ddc5e, X25519PublicKey(561ddc5e))) [
│ {
│ 'privateKey': PrivateKeys(5b2c0b12, SigningPrivateKey(7088b0a3, Ed25519PrivateKey(54514efe)), EncapsulationPrivateKey(4ccf33ae, X25519PrivateKey(4ccf33ae)))
│ } [
│ 'salt': Salt
│ ]
│ 'allow': 'All'
│ ]
│ ]
```
### Task: Allow `xid new` to include a genesis mark and generator
The `xid new` command, in addition to the `--private` option, now includes a `--generator` option. The supported values for this option are `omit` (the default), `include`, and `encrypt`.
Including the provenance mark generator also implies including the genesis mark for the new XIDDocument chain:
```
envelope generate keypairs | envelope xid new --generator include | envelope format
│ XID(cc831666) [
│ 'key': PublicKeys(8983a826, SigningPublicKey(cc831666, SchnorrPublicKey(5ac88bce)), EncapsulationPublicKey(d2467287, X25519PublicKey(d2467287))) [
│ {
│ 'privateKey': PrivateKeys(4aa19a3f, SigningPrivateKey(9af5a45b, SchnorrPrivateKey(d2a25c3d)), EncapsulationPrivateKey(fceb9bc8, X25519PrivateKey(fceb9bc8)))
│ } [
│ 'salt': Salt
│ ]
│ 'allow': 'All'
│ ]
│ 'provenance': ProvenanceMark(632330b4) [
│ {
│ 'provenanceGenerator': Bytes(32) [
│ 'isA': "provenance-generator"
│ "next-seq": 1
│ "res": 3
│ "rng-state": Bytes(32)
│ "seed": Bytes(32)
│ ]
│ } [
│ 'salt': Salt
│ ]
│ ]
│ ]
```
Similar to how the private keys are stored as a salted assertion on the public keys then provenance mark generator is stored as a salted assertion on the provenance mark itself.
If *either* of the `--private` or `--generator` options specify encrypt, then a password will be required, either on the command line using `--encrypt-password`, or by default it will be requested interactively.
```
envelope generate keypairs | envelope xid new --private encrypt --generator encrypt --encrypt-password "test" | envelope format
│ XID(08e22ae2) [
│ 'key': PublicKeys(0fd62607, SigningPublicKey(08e22ae2, SchnorrPublicKey(10bb0f41)), EncapsulationPublicKey(f8e8fce3, X25519PublicKey(f8e8fce3))) [
│ {
│ 'privateKey': ENCRYPTED [
│ 'hasSecret': EncryptedKey(Argon2id)
│ ]
│ } [
│ 'salt': Salt
│ ]
│ 'allow': 'All'
│ ]
│ 'provenance': ProvenanceMark(65058585) [
│ {
│ 'provenanceGenerator': ENCRYPTED [
│ 'hasSecret': EncryptedKey(Argon2id)
│ ]
│ } [
│ 'salt': Salt
│ ]
│ ]
│ ]
```
## What Remains?
- Make envelope XID document self-signed by default
- Provide way to advance XID document provenance mark using embedded or externally-provided generator
- Enhance `provenance` tool to validate series of envelopes or provenance marks
## Featured Releases: November 3, 2025
### bc-envelope-cli 0.26.1 - November 3, 2025
- Removed all references and examples to `ur:crypto-prvkey-base`, keeping legacy support but deprecating its use.
- All examples and documentation updated to use `ur:crypto-prvkeys` and `ur:crypto-pubkeys`.
- Add new `generate keypairs` command for generating random keypairs with post-quantum algorithm support (ML-DSA, ML-KEM).
- Replace `generate signer` and `generate verifier` commands with unified `generate keypairs` command.
- Add `--signing` and `--encryption` options to `generate prvkeys` for scheme selection (Schnorr, ECDSA, Ed25519, SSH variants).
- Enhance `generate prvkeys` to accept `ur:crypto-prvkey-base`, `ur:seed`, or `ur:envelope` inputs.
- Enhance `generate pubkeys` to convert `ur:crypto-prvkeys` or `ur:signing-private-key` to public keys.
- Add `--generator` option to `xid new` command for controlling provenance mark generator inclusion (include, omit, elide, encrypt).
- Add support for `PrivateKeys` and combined `PrivateKeys`+`PublicKeys` in XID document key handling.
- Improve input parsing to support multiple key formats across commands.
- Add encryption support for provenance mark generator.
- Update extensive documentation with new command examples and workflows.
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-envelope-cli/0.26.0)
- [GitHub](https://github.com/BlockchainCommons/bc-envelope-cli-rust)
### bc-xid 0.15.1 - November 3, 2025
- Add comprehensive `ProvenanceMarkGenerator` support with optional encryption in XID documents.
- Add new `Provenance` type with `GeneratorData` enum for handling encrypted/decrypted generator states.
- Add `MarkGeneratorOptions` for controlling generator inclusion (omit, include, elide, encrypt).
- Consolidate `XIDDocument` constructors into unified `new()` with `InceptionKeyOptions` and `GenesisMarkOptions`.
- Add support for genesis mark creation with passphrase or seed during document construction.
- Add `generator_envelope()` method for extracting generators with optional password decryption.
- Add `has_generator()` and `has_encrypted_generator()` methods to `Provenance`.
- Reorganize all tests into `tests/` directory for better project structure.
- Improve constructor API ergonomics with enum-based option types.
- Add support for including ProvenanceMarkGenerator in Envelope XIDDocument.
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-xid/0.15.0)
- [GitHub](https://github.com/BlockchainCommons/bc-xid-rust)
### provenance-mark 0.15.0 - November 3, 2025
- Add comprehensive Envelope support for `ProvenanceMarkGenerator` with bidirectional conversion.
- Add Envelope conversions for `ProvenanceMark`, `ProvenanceSeed`, and `RngState`.
- Add `from_slice()` constructors to `ProvenanceSeed` and `RngState` for validation.
- Add `new_with_passphrase()` method to `ProvenanceSeed`.
- Refactor `ProvenanceMarkGenerator::new()` to return `Result` with proper validation.
- Add error variants: `InvalidSeedLength`, `InvalidChainIdLength`, `DuplicateKey`, `MissingKey`, `InvalidKey`, `ExtraKeys`.
- Add CBOR conversions for `ProvenanceSeed` and `RngState`.
- Consolidate envelope implementation from separate module into type implementations.
- Derive `PartialEq` and `Eq` for `ProvenanceMarkGenerator`, `ProvenanceSeed`, and `RngState`.
- Fix test to work correctly with global tag registration.
- Align to dependencies.
- [Crates.io](https://crates.io/crates/provenance-mark/0.15.0)
- [GitHub](https://github.com/BlockchainCommons/provenance-mark-rust)
### bc-envelope 0.36.0 - November 3, 2025
- Add new feature gates: `ed25519`, `secp256k1`, `ssh-agent`, and `pqcrypto`.
- Make cryptographic schemes optional via feature flags in `bc-crypto` and `bc-components` dependencies.
- Add `pqcrypto` and `ssh-agent` to default features (breaking change for minimal builds).
- Reorganize feature dependencies: `signature` feature now requires explicit crypto scheme selection.
- Add comprehensive feature testing matrix covering all crypto scheme combinations.
- Document O(1) cloning behavior using reference counting in `Envelope` type.
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-envelope/0.36.0)
- [GitHub](https://github.com/BlockchainCommons/bc-envelope-rust)
### known-values 0.10.0 - November 3, 2025
- Add 68 - provenanceGenerator.
- Align to dependencies.
- [Crates.io](https://crates.io/crates/known-values/0.10.0)
- [GitHub](https://github.com/BlockchainCommons/known-values-rust)
## Other Releases: November 3, 2025
### dcbor-cli 0.13.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/dcbor-cli/0.13.0)
- [GitHub](https://github.com/BlockchainCommons/bc-dcbor-cli)
### bc-envelope-pattern 0.7.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-envelope-pattern/0.7.0)
- [GitHub](https://github.com/BlockchainCommons/bc-envelope-pattern-rust)
### dcbor-pattern 0.6.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/dcbor-pattern/0.6.0)
- [GitHub](https://github.com/BlockchainCommons/bc-dcbor-pattern-rust)
### dcbor-parse 0.6.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/dcbor-parse/0.6.0)
- [GitHub](https://github.com/BlockchainCommons/bc-dcbor-parse-rust)
### bc-crypto 0.12.0 - November 3, 2025
- Add feature gates for secp256k1 and ed25519.
- [Crates.io](https://crates.io/crates/bc-crypto/0.12.0)
- [GitHub](https://github.com/BlockchainCommons/bc-crypto-rust)
### bc-components 0.27.0 - November 3, 2025
- Align to dependencies.
- Feature gate cryptographic schemes.
- Improve Display formatting for keys.
- [Crates.io](https://crates.io/crates/bc-components/0.27.0)
- [GitHub](https://github.com/BlockchainCommons/bc-components-rust)
### sskr 0.10.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/sskr/0.10.0)
- [GitHub](https://github.com/BlockchainCommons/bc-sskr-rust)
### bc-ur 0.15.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-ur/0.15.0)
- [GitHub](https://github.com/BlockchainCommons/bc-ur-rust)
### bc-tags 0.8.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-tags/0.8.0)
- [GitHub](https://github.com/BlockchainCommons/bc-tags-rust)
### dcbor 0.23.2 - November 3, 2025
- Clarify documentation.
- [Crates.io](https://crates.io/crates/dcbor/0.23.2)
- [GitHub](https://github.com/BlockchainCommons/bc-dcbor-rust)
### bc-shamir 0.11.0 - November 3, 2025
- Align to dependencies.
- [Crates.io](https://crates.io/crates/bc-shamir/0.11.0)
- [GitHub](https://github.com/BlockchainCommons/bc-shamir-rust)