diff --git a/spec/ic.did b/spec/ic.did index 705eb6441..59bf89225 100644 --- a/spec/ic.did +++ b/spec/ic.did @@ -24,6 +24,19 @@ type http_response = record { body: blob; }; +type http_request_error = variant { + no_consensus; + timeout; + bad_tls; + invalid_url; + transform_error; + dns_error; + unreachable; + conn_timeout; +}; + +type ecdsa_curve = variant { secp256k1; }; + service ic : { create_canister : (record { settings : opt canister_settings @@ -63,6 +76,18 @@ service ic : { }; }) -> (http_response); + // Threshold ECDSA signature + ecdsa_public_key : (record { + canister_id : opt canister_id; + derivation_path : vec blob; + key_id : record { curve: ecdsa_curve; name: text }; + }) -> (record { public_key : blob; chain_code : blob; }); + sign_with_ecdsa : (record { + message_hash : blob; + derivation_path : vec blob; + key_id : record { curve: ecdsa_curve; name: text }; + }) -> (record { signature : blob }); + // provisional interfaces for the pre-ledger world provisional_create_canister_with_cycles : (record { amount: opt nat; diff --git a/spec/index.adoc b/spec/index.adoc index a278c148a..b99c6a9e9 100644 --- a/spec/index.adoc +++ b/spec/index.adoc @@ -1657,6 +1657,32 @@ There is no restriction on who can invoke this method. This method takes no input and returns 32 pseudo-random bytes to the caller. The return value is unknown to any part of the IC at time of the submission of this call. A new return value is generated for each call to this method. +[#ic-ecdsa_public_key] +=== IC method `ecdsa_public_key` + +This method returns a https://www.secg.org/sec1-v2.pdf[SEC1] 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. +The `key_id` is a struct specifying both a curve and a name. +The availability of a particular `key_id` depends on implementation. + +For curve `secp256k1`, the public key is derived using a generalization of BIP32 (see https://ia.cr/2021/1330[ia.cr/2021/1330, Appendix D]). To derive (non-hardened) https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki[BIP-0032]-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 2^31^. + +The return result is an extended public key consisting of an ECDSA `public_key`, encoded in https://www.secg.org/sec2-v2.pdf[SEC1] compressed form, and a `chain_code`, which can be used to deterministically derive child keys of the `public_key`. + +This call requires that the ECDSA feature is enabled, and the `canister_id` meets the requirement of a canister id. +Otherwise it will be rejected. + +[#ic-sign_with_ecdsa] +=== IC method `sign_with_ecdsa` + +This method returns a new https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf[ECDSA] 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 https://www.secg.org/sec2-v2.pdf[SEC1] 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. + [#ic-http_request] === IC method `http_request`