From 2288e5f9c53d5bdee0d0c835fedbed7b3469ce8e Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Tue, 26 Mar 2024 00:28:10 +0100 Subject: [PATCH 1/8] Management canister API for tSchnorr signatures --- spec/_attachments/ic.did | 30 ++++++++++++++++++++++++++++++ spec/index.md | 30 ++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/spec/_attachments/ic.did b/spec/_attachments/ic.did index a34f3318..57ee223f 100644 --- a/spec/_attachments/ic.did +++ b/spec/_attachments/ic.did @@ -67,6 +67,11 @@ type ecdsa_curve = variant { secp256k1; }; +type schnorr_algorithm = variant { + bip340secp256k1; + ed25519; +}; + type satoshi = nat64; type bitcoin_network = variant { @@ -284,6 +289,27 @@ type sign_with_ecdsa_result = record { signature : blob; }; +type schnorr_public_key_args = record { + canister_id : opt canister_id; + derivation_path : vec blob; + key_id : record { algorithm : schnorr_algorithm; name : text }; +}; + +type schnorr_public_key_result = record { + public_key : blob; + chain_code : blob; +}; + +type sign_with_schnorr_args = record { + message : blob; + derivation_path : vec blob; + key_id : record { algorithm : schnorr_algorithm; name : text }; +}; + +type sign_with_schnorr_result = record { + signature : blob; +}; + type node_metrics_history_args = record { subnet_id : principal; start_at_timestamp_nanos : nat64; @@ -344,6 +370,10 @@ service ic : { ecdsa_public_key : (ecdsa_public_key_args) -> (ecdsa_public_key_result); sign_with_ecdsa : (sign_with_ecdsa_args) -> (sign_with_ecdsa_result); + // Threshold Schnorr signature + schnorr_public_key : (schnorr_public_key_args) -> (schnorr_public_key_result); + sign_with_schnorr : (sign_with_schnorr_args) -> (sign_with_schnorr_result); + // bitcoin interface bitcoin_get_balance : (bitcoin_get_balance_args) -> (bitcoin_get_balance_result); bitcoin_get_balance_query : (bitcoin_get_balance_query_args) -> (bitcoin_get_balance_query_result) query; diff --git a/spec/index.md b/spec/index.md index 61a750b0..3f51c66a 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2145,11 +2145,11 @@ This method takes no input and returns 32 pseudo-random bytes to the caller. The ### IC method `ecdsa_public_key` {#ic-ecdsa_public_key} -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 implementation. +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 return result 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`. +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`. ### IC method `sign_with_ecdsa` {#ic-sign_with_ecdsa} @@ -2159,6 +2159,32 @@ The signatures are encoded as the concatenation of the [SEC1](https://www.secg.o This call requires that the ECDSA feature is enabled, the caller is a canister, and `message_hash` is 32 bytes long. Otherwise it will be rejected. +### IC method `schnorr_public_key` {#ic-schnorr_public_key} + +This method returns a (derived) Schnorr 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 an algorithm and a name. The availability of a particular `key_id` depends on the implementation. + +The return value is an extended Schnorr public key consisting of a Schnorr `public_key` and a `chain_code`. The chain code can be used to deterministically derive child keys of the `public_key`. Both the derivation and the encoding of the public key depends on the key ID's `algorithm`: + +- For algorithm `bip340secp256k1`, the public key is derived using the generalization of BIP32 defined in [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 public key is encoded in [SEC1](https://www.secg.org/sec1-v2.pdf) compressed form. To use BIP32 public keys to verify BIP340 Schnorr signatures, the first byte of the (33-byte) SEC1-encoded public key must be removed (see [BIP-340, Public Key Conversion](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#public-key-conversion)). + +- For algorithm `ed25519`, the public key is derived using the scheme specified in the Threshold Schnorr signatures reference of the Internet Computer Developer Docs. + + The public key is encoded in standard 32-byte compressed form (see [RFC8032, 5.1.2 Encoding](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2)). + +### IC method `sign_with_schnorr` {#ic-sign_with_schnorr} + +This method returns a Schnorr signature of the given `message` that can be verified against a (derived) public key obtained by calling `schnorr_public_key` using the caller's `canister_id` and the given `derivation_path` and `key_id`. + +The encoding of the signature depends on the key ID's `algorithm`: + +- For algorithm `bip340secp256k1`, the signature is encoded in 64 bytes according to [BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + +- For algorithm `ed25519`, the signature is encoded in 64 bytes according to [RFC8032, 5.1.6 Sign](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.6). + +This call requires that the Schnorr feature is enabled and the caller is a canister. Otherwise it will be rejected. + ### IC method `http_request` {#ic-http_request} This method makes an HTTP request to a given URL and returns the HTTP response, possibly after a transformation. From c473954bceec5b6469e03b3f28c77a0e26fb5426 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Tue, 26 Mar 2024 01:37:15 +0100 Subject: [PATCH 2/8] Update link to KD spec --- spec/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index 3f51c66a..78c257a1 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2169,7 +2169,7 @@ The return value is an extended Schnorr public key consisting of a Schnorr `publ The public key is encoded in [SEC1](https://www.secg.org/sec1-v2.pdf) compressed form. To use BIP32 public keys to verify BIP340 Schnorr signatures, the first byte of the (33-byte) SEC1-encoded public key must be removed (see [BIP-340, Public Key Conversion](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#public-key-conversion)). -- For algorithm `ed25519`, the public key is derived using the scheme specified in the Threshold Schnorr signatures reference of the Internet Computer Developer Docs. +- For algorithm `ed25519`, the public key is derived using the [Ed25519 hierarchical key derivation scheme specified in the Internet Computer Developer Docs](https://2xf6o-laaaa-aaaam-abrla-cai.icp0.io/docs/current/references/t-schnorr-how-it-works#ed25519-hierarchical-key-derivation). The public key is encoded in standard 32-byte compressed form (see [RFC8032, 5.1.2 Encoding](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2)). From b6877025a1154fcf8306b310716ef2241f832591 Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Wed, 27 Mar 2024 18:59:50 +0100 Subject: [PATCH 3/8] Improve spec regarding call requirements, also for ECDSA --- spec/index.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/spec/index.md b/spec/index.md index 78c257a1..ff353f37 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2151,13 +2151,15 @@ For curve `secp256k1`, the public key is derived using a generalization of BIP32 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`. +This call requires that an ECDSA key with ID `key_id` was generated by the IC. Otherwise, the call is rejected. + ### IC method `sign_with_ecdsa` {#ic-sign_with_ecdsa} This method returns a new [ECDSA](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) signature of the given `message_hash` that can be separately verified against a derived ECDSA public key. This public key can be obtained by calling `ecdsa_public_key` with the caller's `canister_id`, and the same `derivation_path` and `key_id` used here. 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. -This call requires that the ECDSA feature is enabled, the caller is a canister, and `message_hash` is 32 bytes long. Otherwise it will be rejected. +This call requires that an ECDSA key with ID `key_id` was generated by the IC, the signing functionality for that key was enabled, the caller is a canister, and `message_hash` is 32 bytes long. Otherwise, the call is is rejected. ### IC method `schnorr_public_key` {#ic-schnorr_public_key} @@ -2173,6 +2175,8 @@ The return value is an extended Schnorr public key consisting of a Schnorr `publ The public key is encoded in standard 32-byte compressed form (see [RFC8032, 5.1.2 Encoding](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2)). +This call requires that a Schnorr key with ID `key_id` was generated by the IC. Otherwise, the call is rejected. + ### IC method `sign_with_schnorr` {#ic-sign_with_schnorr} This method returns a Schnorr signature of the given `message` that can be verified against a (derived) public key obtained by calling `schnorr_public_key` using the caller's `canister_id` and the given `derivation_path` and `key_id`. @@ -2183,7 +2187,7 @@ The encoding of the signature depends on the key ID's `algorithm`: - For algorithm `ed25519`, the signature is encoded in 64 bytes according to [RFC8032, 5.1.6 Sign](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.6). -This call requires that the Schnorr feature is enabled and the caller is a canister. Otherwise it will be rejected. +This call requires that a Schnorr key with ID `key_id` was generated by the IC, the signing functionality for that key was enabled, and the caller is a canister. Otherwise, the call is is rejected. ### IC method `http_request` {#ic-http_request} From d351361d976f6cae531a6f8b0d88abadb738e12a Mon Sep 17 00:00:00 2001 From: Franz-Stefan Preiss Date: Fri, 19 Apr 2024 15:51:04 +0200 Subject: [PATCH 4/8] Specify Ed25519 key derivation within IC spec --- spec/index.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/spec/index.md b/spec/index.md index ff353f37..3d42e33b 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2171,12 +2171,82 @@ The return value is an extended Schnorr public key consisting of a Schnorr `publ The public key is encoded in [SEC1](https://www.secg.org/sec1-v2.pdf) compressed form. To use BIP32 public keys to verify BIP340 Schnorr signatures, the first byte of the (33-byte) SEC1-encoded public key must be removed (see [BIP-340, Public Key Conversion](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#public-key-conversion)). -- For algorithm `ed25519`, the public key is derived using the [Ed25519 hierarchical key derivation scheme specified in the Internet Computer Developer Docs](https://2xf6o-laaaa-aaaam-abrla-cai.icp0.io/docs/current/references/t-schnorr-how-it-works#ed25519-hierarchical-key-derivation). +- For algorithm `ed25519`, the public key is derived using the scheme specified in [Ed25519 hierarchical key derivation](#ed25519-key-derivation). The public key is encoded in standard 32-byte compressed form (see [RFC8032, 5.1.2 Encoding](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2)). This call requires that a Schnorr key with ID `key_id` was generated by the IC. Otherwise, the call is rejected. +#### Ed25519 hierarchical key derivation {#ed25519-key-derivation} + +This section describes a child key derivation (CKD) function for computing child public keys from Ed25519 parent public keys. +The section is inspired by [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) and uses similar wording and structure. + +##### Motivation + +To support the Ed25519 variant of threshold Schnorr signatures on the Internet Computer, a key derivation scheme compatible with Ed25519 signatures is required. +For a respective signing service on the Internet Computer to be efficient, the signing subnet maintains only a single master key pair and _derives_ signing child keys for each canister. +Although there exist various hierarchical key derivation schemes (e.g., [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki), [SLIP10](https://github.com/satoshilabs/slips/blob/master/slip-0010.md), [BIP32-Ed25519](https://input-output-hk.github.io/adrestia/static/Ed25519_BIP.pdf), [Schnorrkel](https://github.com/w3f/schnorrkel)), all of the analyzed schemes are either incompatible in a threshold setting (e.g., use hardened key derivation only), comply with clamping which adds unnecessary complexity, or otherwise rely on non-standard primitives. +For these reasons, a new derivation scheme is specified here. +This scheme does not make use of _clamping_ (see [RFC8032, Section 5.1.5, Item 2](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5)), because it is unnecessary in the given setting, and satisfies the following requirements: + +- Off-chain availability: New public keys can be computed off-chain from a master public key without requiring interaction with the IC. +- Hierarchical derivation: Derived keys are organized in a tree such that from any public key it is possible to derive new child keys. The first level is used to derive unique canister-specific keys from the master key. +- Simplicity: The scheme is simple to implement using existing libraries. + +##### Conventions + +We will assume the elliptic curve (EC) operations using the field and curve parameters as defined by Ed25519 (see [RFC8032, Section 5.1](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1)). Variables below are either: + +- Integers modulo the order of the curve's prime order subgroup (referred to as L). +- Points on the curve. +- Byte sequences. + +Addition (+) of two points is defined as application of the EC group operation. +Concatenation (||) is the operation of appending one byte sequence onto another. + +We assume the following functions: + +- point(p): returns the point resulting from EC point multiplication (repeated application of the EC group operation) of the Ed25519 base point with the integer p. +- serP(P): serializes the point to a byte sequence using standard 32-byte compressed form (see [RFC8032, 5.1.2 Encoding](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.2)). +- utf8(s): returns the UTF-8 encoding of string s. +- parse512(p): interprets a 64-byte sequence as a 512-bit number, most significant byte first. +- HKDF(salt,IKM,info,N) -> OKM: HMAC-based key derivation function (see [RFC5869](https://datatracker.ietf.org/doc/html/rfc5869)) using HMAC-SHA512 (see [RFC4231](https://datatracker.ietf.org/doc/html/rfc4231)) calculating N-bytes long output key material (OKM) from (byte sequences) salt, input key material (IKM), and application specific information *info*. + +##### Extended keys + +Public keys are extended with an extra 32 bytes of entropy, which extension is called chain code. +An extended public key is represented as (K, c), with K = point(k) and c being the chain code, for some private key k. +Each extended key can have an arbitrary number of child keys. +The scheme does not support hardened derivation of child keys. + +##### Child key derivation (CKD) function + +Given a parent extended public key and an index i, it is possible to compute the corresponding child extended public key. +The function CKDpub computes a child extended public key from a parent extended public key and an index i, where i is a byte sequence of arbitrary length (including empty). + +CKDpub((Kpar, cpar), i) → (Ki, ci): +- let IKM = serP(Kpar) || i. +- let OKM = HKDF(cpar, IKM, utf8("Ed25519"), 96). +- Split OKM into a 64-byte and a 32-byte sequence, tweak and ci. +- let Ki = Kpar + point(parse512(tweak) mod L). +- return (Ki, ci). + +##### Key tree + +A key tree can be built by repeatedly applying CKDpub, starting with one root, called the master extended public key M. +Computing CKDpub(M, i) for different values of i results in a number of level-0 derived keys. +As each of these is again an extended key, CKDpub can be applied to those as well. +The sequence of indices used when repeatedly applying CKDpub is called the _derivation path_. + +The function KTpub computes a child extended public key from a parent extended public key and a derivation path d. + +KTpub((Kpar, cpar), d) → (Kd, cd): +- let (Kd, cd) = (Kpar, cpar) +- for all indices i in d: + (Kd, cd) = CKDpub((Kd, cd), i) +- return (Kd, cd). + ### IC method `sign_with_schnorr` {#ic-sign_with_schnorr} This method returns a Schnorr signature of the given `message` that can be verified against a (derived) public key obtained by calling `schnorr_public_key` using the caller's `canister_id` and the given `derivation_path` and `key_id`. From 35e98f5c638102eac49955bb7fc09c1cb1952460 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 23 Jul 2024 13:16:09 +0200 Subject: [PATCH 5/8] restrictions --- spec/index.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/index.md b/spec/index.md index 5895a140..1ae30182 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2269,10 +2269,14 @@ This method returns a new [ECDSA](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FI 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. -This call requires that an ECDSA key with ID `key_id` was generated by the IC, the signing functionality for that key was enabled, the caller is a canister, and `message_hash` is 32 bytes long. Otherwise, the call is is rejected. +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. + +Cycles to pay for the call must be explicitly transferred with the call, i.e., they are not automatically deducted from the caller's balance implicitly (e.g., as for inter-canister calls). ### IC method `schnorr_public_key` {#ic-schnorr_public_key} +This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. + This method returns a (derived) Schnorr 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 an algorithm and a name. The availability of a particular `key_id` depends on the implementation. The return value is an extended Schnorr public key consisting of a Schnorr `public_key` and a `chain_code`. The chain code can be used to deterministically derive child keys of the `public_key`. Both the derivation and the encoding of the public key depends on the key ID's `algorithm`: @@ -2359,6 +2363,8 @@ KTpub((Kpar, cpar), d) → (Kd, cd): ### IC method `sign_with_schnorr` {#ic-sign_with_schnorr} +This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. + This method returns a Schnorr signature of the given `message` that can be verified against a (derived) public key obtained by calling `schnorr_public_key` using the caller's `canister_id` and the given `derivation_path` and `key_id`. The encoding of the signature depends on the key ID's `algorithm`: @@ -2367,7 +2373,7 @@ The encoding of the signature depends on the key ID's `algorithm`: - For algorithm `ed25519`, the signature is encoded in 64 bytes according to [RFC8032, 5.1.6 Sign](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.6). -This call requires that a Schnorr key with ID `key_id` was generated by the IC, the signing functionality for that key was enabled, and the caller is a canister. Otherwise, the call is is rejected. +This call requires that a Schnorr key with ID `key_id` was generated by the IC and the signing functionality for that key was enabled. Otherwise, the call is is rejected. Cycles to pay for the call must be explicitly transferred with the call, i.e., they are not automatically deducted from the caller's balance implicitly (e.g., as for inter-canister calls). From 6e0072939a0150547dba5b64e13c768001f903a9 Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 23 Jul 2024 13:17:20 +0200 Subject: [PATCH 6/8] changelog --- spec/_attachments/interface-spec-changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/_attachments/interface-spec-changelog.md b/spec/_attachments/interface-spec-changelog.md index 2cd3fb9a..0d19ba2a 100644 --- a/spec/_attachments/interface-spec-changelog.md +++ b/spec/_attachments/interface-spec-changelog.md @@ -1,6 +1,7 @@ ## Changelog {#changelog} ### ∞ (unreleased) +* Management canister API for threshold Schnorr signatures. ### 0.25.0 (2024-06-14) {#0_25_0} * Query call statistics. From 75a006660daaf8126922ecfd23ae143e58f19cbf Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 23 Jul 2024 13:25:40 +0200 Subject: [PATCH 7/8] experimental --- spec/_attachments/interface-spec-changelog.md | 2 +- spec/index.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/_attachments/interface-spec-changelog.md b/spec/_attachments/interface-spec-changelog.md index 0d19ba2a..a2649853 100644 --- a/spec/_attachments/interface-spec-changelog.md +++ b/spec/_attachments/interface-spec-changelog.md @@ -1,7 +1,7 @@ ## Changelog {#changelog} ### ∞ (unreleased) -* Management canister API for threshold Schnorr signatures. +* EXPERIMENTAL: Management canister API for threshold Schnorr signatures. ### 0.25.0 (2024-06-14) {#0_25_0} * Query call statistics. diff --git a/spec/index.md b/spec/index.md index 1ae30182..c9984d28 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2263,6 +2263,12 @@ This call requires that an ECDSA key with ID `key_id` was generated by the IC. O ### IC method `sign_with_ecdsa` {#ic-sign_with_ecdsa} +:::note + +Threshold Schnorr API is EXPERIMENTAL and there might be breaking changes of the behavior in the future. Use at your own risk! + +::: + This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. This method returns a new [ECDSA](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) signature of the given `message_hash` that can be separately verified against a derived ECDSA public key. This public key can be obtained by calling `ecdsa_public_key` with the caller's `canister_id`, and the same `derivation_path` and `key_id` used here. @@ -2363,6 +2369,12 @@ KTpub((Kpar, cpar), d) → (Kd, cd): ### IC method `sign_with_schnorr` {#ic-sign_with_schnorr} +:::note + +Threshold Schnorr API is EXPERIMENTAL and there might be breaking changes of the behavior in the future. Use at your own risk! + +::: + This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. This method returns a Schnorr signature of the given `message` that can be verified against a (derived) public key obtained by calling `schnorr_public_key` using the caller's `canister_id` and the given `derivation_path` and `key_id`. From 3ecade2f9be3137b2d0596c3675f96bf8ed0354e Mon Sep 17 00:00:00 2001 From: Martin Raszyk Date: Tue, 23 Jul 2024 16:03:18 +0200 Subject: [PATCH 8/8] fix experimental note --- spec/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/index.md b/spec/index.md index c9984d28..21655d68 100644 --- a/spec/index.md +++ b/spec/index.md @@ -2263,12 +2263,6 @@ This call requires that an ECDSA key with ID `key_id` was generated by the IC. O ### IC method `sign_with_ecdsa` {#ic-sign_with_ecdsa} -:::note - -Threshold Schnorr API is EXPERIMENTAL and there might be breaking changes of the behavior in the future. Use at your own risk! - -::: - This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. This method returns a new [ECDSA](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) signature of the given `message_hash` that can be separately verified against a derived ECDSA public key. This public key can be obtained by calling `ecdsa_public_key` with the caller's `canister_id`, and the same `derivation_path` and `key_id` used here. @@ -2281,6 +2275,12 @@ Cycles to pay for the call must be explicitly transferred with the call, i.e., t ### IC method `schnorr_public_key` {#ic-schnorr_public_key} +:::note + +Threshold Schnorr API is EXPERIMENTAL and there might be breaking changes of the behavior in the future. Use at your own risk! + +::: + This method can only be called by canisters, i.e., it cannot be called by external users via ingress messages. This method returns a (derived) Schnorr 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 an algorithm and a name. The availability of a particular `key_id` depends on the implementation.