Repository navigation
feat(crypto): add the mainnet and PocketIC master keys to ic-secp256r1 - #11895
Merged
Merged
Conversation
`ic-secp256k1` and `ic-ed25519` ship the mainnet and PocketIC master public keys of their algorithms, which `ic-pub-key` uses for offline key derivation. The mainnet ECDSA keys `key_1` and `test_key_1` now also exist over secp256r1, and PocketIC holds secp256r1 keys too, but `ic-secp256r1` has none of them. * `PublicKey::mainnet_key` returns the master public keys of `ecdsa:Secp256r1:key_1` and `ecdsa:Secp256r1:test_key_1`, read from the CUPs of subnets uzr34 and fuqsr. * `PublicKey::pocketic_key` returns the ones PocketIC uses for `key_1`, `test_key_1` and `dfx_test_key`, and a test derives them the way PocketIC does. * The version moves to 0.3.0, to be released before `ic-pub-key` can depend on these keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The mainnet key constants still need independent confirmation against their authoritative source CUPs before release.
No open issues 🎉
What changed in this PR
Adds mainnet and PocketIC P-256 master public keys to ic-secp256r1, preparing a release needed for offline key derivation in ic-pub-key.
Changes:
- Adds key identifiers and constructors for two mainnet and three PocketIC keys.
- Adds mainnet serialization checks and PocketIC derivation tests.
- Prepares version 0.3.0 with dependency and changelog updates.
| File | Description |
|---|---|
| packages/ic-secp256r1/tests/tests.rs | Tests embedded keys and PocketIC derivation. |
| packages/ic-secp256r1/src/lib.rs | Adds key identifiers, constructors, and constants. |
| packages/ic-secp256r1/CHANGELOG.md | Documents the 0.3.0 release. |
| packages/ic-secp256r1/Cargo.toml | Bumps version and adds the runtime dependency. |
| packages/ic-secp256r1/BUILD.bazel | Aligns Bazel version and dependencies. |
| Cargo.lock | Records version 0.3.0. |
Review effort: Balanced
pierugo-dfinity
approved these changes
Oct 20, 2026
pierugo-dfinity
left a comment
Contributor
There was a problem hiding this comment.
Verified that the provided mainnet keys match the ones in the live subnets' CUPs.
* Add `PublicKey::derive_mainnet_key` and `PublicKey::derive_pocketic_key`, and re-export `ic_principal::Principal` as `CanisterId` for them, as `ic-secp256k1` and `ic-ed25519` do. Their tests expect what the replica's `derive_threshold_public_key` returns for the same master keys, canisters and paths. * Test the SLIP-10 retry for nist256p1 (index 33941), the only branch of the derivation the tests didn't reach. It runs when iL >= n, about once in 2^32 steps on P-256. * Rename `mainnet_keys_are_the_ones_in_the_cups` to `mainnet_keys_round_trip`, which is what it checks. * Name the two new enums in the changelog, drop the duplicate `hex-literal` dev-dependency, and list `ic-secp256r1` among the crates with hardcoded master keys in the `cup_explorer` README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eichhorl
added a commit
that referenced
this pull request
Oct 20, 2026
…-key-secp256r1 ic-pub-key needs the ic-secp256r1 0.3.0 of #11895: take its version of ic-secp256r1 and raise the requirement to 0.3.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
eichhorl
added a commit
that referenced
this pull request
Oct 23, 2026
Resolve two conflicts with #11909: - CHANGELOG.md: keep #11909's line for ic-management-canister-types 0.5.0 -> 0.11.0 once, next to this PR's entries. - Cargo.lock: master's, with cargo re-applying this PR's change to the ic-pub-key entry. The ic-secp256r1 changes this branch carried from #11895 are identical to master's squash commit, so they drop out of the diff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AleDema
pushed a commit
to AleDema/ic
that referenced
this pull request
Oct 24, 2026
…finity#11894) ### Why The mainnet ECDSA keys `key_1` and `test_key_1` now also exist over secp256r1 (P-256), the curve dfinity#11573 added, and PocketIC holds secp256r1 keys too (dfinity#11741). `ic-pub-key` derives canister public keys offline from hardcoded master keys, but for ECDSA only over secp256k1: any other curve returns `AlgorithmNotSupported`. `ic-secp256r1` 0.3.0 (dfinity#11895) has the secp256r1 master keys, and the workspace's `ic-management-canister-types` 0.11.0 (dfinity#11909) has `EcdsaCurve::Secp256r1`. Both are published. ### What * A new `secp256r1` feature, on by default, derives keys for `key_1`, `test_key_1`, `pocketic_key_1`, `pocketic_test_key_1` and `dfx_test_key`, following the secp256k1 code paths. It requires `ic-secp256r1` 0.3.0. * `TryFrom<&EcdsaKeyId>` checks each curve in its own feature-gated block, like `TryFrom<&SchnorrKeyId>`, instead of depending on the order of its checks. * `serialize` and `chain_code` share one implementation on `DerivedPublicKeyInner`, instead of one each in `CanisterMasterKey` and `DerivedPublicKey`. * The crate docs and README describe the features, including `default-features = false`, and `derive_ecdsa_key` names the feature each curve needs. * The changelog adds the secp256r1 support and the changes since the published 0.3.0 that weren't recorded yet: `ic-vetkeys` 0.6.0 → 0.7.0 and the `ic-cdk-management-canister` dependency of the `vetkeys` feature. dfinity#11909 already recorded `ic-management-canister-types` 0.5.0 → 0.11.0, which makes the next release a breaking one. ### Tests * Known-answer tests for all five secp256r1 keys, using the same canisters and path shape as the secp256k1 tests. * All ECDSA tests now also check the chain code, and that unknown key names are rejected. * All expected public keys and chain codes are what the replica's `derive_threshold_public_key`, the function that answers `ecdsa_public_key`, returns for these master keys. A one-off check, not committed, confirmed this for all 11 ECDSA vectors: * `ic-pub-key` matches the replica on both public key and chain code. * The replica reproduces the existing secp256k1 vectors. * The offline derivation also matches mainnet itself: for a canister on mainnet, `ecdsa_public_key` returned exactly the public keys `ic-pub-key` derives offline, for `key_1` and `test_key_1` on both curves, each with an empty and a 7-element path. Mainnet doesn't expose chain codes, so those rest on the replica check. * The test helpers follow the Schnorr ones and are feature-gated. With a single feature, the tests build without warnings, and so does the library, except with only `vetkeys`: the two warnings master already has in `CanisterMasterKey::derive_key` remain. This PR removes a third, in `TryFrom<&SchnorrKeyId>`. * Locally, in the dev container, all of these pass: `cargo check` (default and each single feature), `rust-lint.sh`, `bazel build //... --nobuild`, `//bazel:buildifier.check`, and the 3 affected tests. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
dfinityianblenke
added a commit
that referenced
this pull request
Oct 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
ic-secp256k1andic-ed25519ship the mainnet and PocketIC master public keys of their algorithms, andic-pub-keyuses them to derive keys offline. The mainnet ECDSA keyskey_1andtest_key_1now also exist over secp256r1 (P-256), and PocketIC holds secp256r1 keys too (#11741). Butic-secp256r1has none of them.This PR adds the keys and bumps the version, so the crate can be released.
ic-pub-keycan only use the keys once that release is out (#11894). That's the same order as #7148 before #7194 for the secp256k1 and Ed25519 PocketIC keys.What
PublicKey::mainnet_key(MasterPublicKeyId)returnskey_1andtest_key_1.PublicKey::pocketic_key(PocketIcMasterPublicKeyId)returns the keys PocketIC uses forkey_1,test_key_1anddfx_test_key.PublicKey::derive_mainnet_keyandPublicKey::derive_pocketic_keyderive a canister's public key from those master keys. They are offline equivalents ofecdsa_public_key. For their&CanisterIdargument, the crate re-exportsic_principal::PrincipalasCanisterId, asic-secp256k1andic-ed25519do.hex-literalbecomes a regular dependency, to embed the keys, andic_principala new one.cup_explorerREADME now listsic-secp256r1among the crates with hardcoded master keys.Where the keys come from:
key_1) and fuqsr (test_key_1). In that same output, the secp256k1, BIP340, Ed25519 and VetKD master keys match the valuesic-secp256k1,ic-ed25519andic-vetkeysalready ship.PrivateKey::generate_insecure_key_for_testing(42)and the key name.Tests
mainnet_keys_round_trip: the mainnet keys round-trip.derive_mainnet_keyandderive_pocketic_keyhave known-answer tests for all five keys. The expected keys are what the replica'sderive_threshold_public_key(the function that answersecdsa_public_key) returns for the same master key, canister and path.cargo check,cargo fmt,rust-lint.sh,bazel build //... --nobuild,//bazel:buildifier.check, and the 37 tests from the depth-2 rdeps query (this package,ic-pub-key,rs/crypto, the P-256 basic-sig crate,standalone-sig-verifier,rs/validator).🤖 Generated with Claude Code