diff --git a/docs/references/ic-interface-spec/canister-interface.md b/docs/references/ic-interface-spec/canister-interface.md index 4617b98a..e9bc70b6 100644 --- a/docs/references/ic-interface-spec/canister-interface.md +++ b/docs/references/ic-interface-spec/canister-interface.md @@ -927,7 +927,7 @@ These system calls return costs in Cycles, represented by 128 bits, which will b - `ic0.cost_vetkd_derive_key(src : I, size : I, vetkd_curve: i32, dst : I) -> i32`; `I ∈ {i32, i64}` These system calls accept a key name via a textual representation for the specific signing scheme / key of a given size stored in the heap memory starting at offset `src`. They also accept an `i32` with the following interpretations: - - `ecdsa_curve: 0 → secp256k1` + - `ecdsa_curve: 0 → secp256k1, 1 → secp256r1` - `algorithm: 0 → bip340secp256k1, 1 → ed25519` - `vetkd_curve: 0 → bls12_381` diff --git a/docs/references/ic-interface-spec/changelog.md b/docs/references/ic-interface-spec/changelog.md index 4225275e..9d156281 100644 --- a/docs/references/ic-interface-spec/changelog.md +++ b/docs/references/ic-interface-spec/changelog.md @@ -32,6 +32,11 @@ sidebar: by external users and from composite query methods (it remains callable by canisters via inter-canister calls and remains rejected for ingress messages). Retrieving canister information is not subject to any access control, so any principal, including the anonymous one, can call it. +* New variant `secp256r1` of `ecdsa_curve`, selecting threshold ECDSA on the NIST P-256 curve in + `ecdsa_public_key` and `sign_with_ecdsa`. Key derivation follows SLIP-10 and signatures are encoded as + for `secp256k1`, the concatenation of the 32-byte big-endian encodings of r and s. The `ecdsa_curve` + argument of `ic0.cost_sign_with_ecdsa` accepts `1` for the new curve. As for any curve, the + availability of a particular `key_id` depends on the implementation. ### 0.66.0 (2026-08-17) {$0_66_0} * Two new paths in the certified state tree, `/canister//canister_creation_timestamp` diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index 38308e56..b646bf0f 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -475,7 +475,11 @@ This method can only be called by canisters, i.e., it cannot be called by extern This method returns a [SEC1](https://www.secg.org/sec1-v2.pdf) encoded ECDSA public key for the given canister using the given derivation path. If the `canister_id` is unspecified, it will default to the canister id of the caller. The `derivation_path` is a vector of variable length byte strings. Each byte string may be of arbitrary length, including empty. The total number of byte strings in the `derivation_path` must be at most 255. The `key_id` is a struct specifying both a curve and a name. The availability of a particular `key_id` depends on the implementation. -For curve `secp256k1`, the public key is derived using a generalization of BIP32 (see [ia.cr/2021/1330, Appendix D](https://ia.cr/2021/1330)). To derive (non-hardened) [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)-compatible public keys, each byte string (`blob`) in the `derivation_path` must be a 4-byte big-endian encoding of an unsigned integer less than 231. If the `derivation_path` contains a byte string that is not a 4-byte big-endian encoding of an unsigned integer less than 231, then a derived public key will be returned, but that key derivation process will not be compatible with the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) standard. +The derivation depends on the key ID's `curve`: + +- For curve `secp256k1`, the public key is derived using a generalization of BIP32 (see [ia.cr/2021/1330, Appendix D](https://ia.cr/2021/1330)). To derive (non-hardened) [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)-compatible public keys, each byte string (`blob`) in the `derivation_path` must be a 4-byte big-endian encoding of an unsigned integer less than 231. If the `derivation_path` contains a byte string that is not a 4-byte big-endian encoding of an unsigned integer less than 231, then a derived public key will be returned, but that key derivation process will not be compatible with the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) standard. + +- For curve `secp256r1`, the public key is derived using the same generalization instantiated over NIST P-256, which is [SLIP-10](https://github.com/satoshilabs/slips/blob/master/slip-0010.md). To derive (non-hardened) [SLIP-10](https://github.com/satoshilabs/slips/blob/master/slip-0010.md)-compatible public keys, the same encoding requirement applies to every byte string (`blob`) in the `derivation_path`. The return value is an extended public key consisting of an ECDSA `public_key`, encoded in [SEC1](https://www.secg.org/sec1-v2.pdf) compressed form, and a `chain_code`, which can be used to deterministically derive child keys of the `public_key`. @@ -493,7 +497,7 @@ If the signing request returns a reject response whose reject code is `SYS_UNKNO ::: -The signatures are encoded as the concatenation of the [SEC1](https://www.secg.org/sec1-v2.pdf) encodings of the two values r and s. For curve `secp256k1`, this corresponds to 32-byte big-endian encoding. +The signatures are encoded as the concatenation of the [SEC1](https://www.secg.org/sec1-v2.pdf) encodings of the two values r and s. For curves `secp256k1` and `secp256r1`, this corresponds to 32-byte big-endian encoding. This call requires that an ECDSA key with ID `key_id` was generated by the IC, the signing functionality for that key was enabled, and `message_hash` is 32 bytes long. Otherwise, the call is is rejected. diff --git a/public/references/ic.did b/public/references/ic.did index fc939abf..0bdf10f0 100644 --- a/public/references/ic.did +++ b/public/references/ic.did @@ -126,6 +126,7 @@ type http_request_result = record { type ecdsa_curve = variant { secp256k1; + secp256r1; }; type vetkd_curve = variant {