Threshold Schnorr - Facilitating BRC-20 trading, Solana integration, certificate signing, and more

Tl:dr: We would like to integrate a new threshold-Schnorr protocol in ICP. This would allow:

  • Canisters to obtain their own Schnorr public keys/addresses
  • Canisters to request ICP to compute Schnorr signatures on arbitrary messages
  • Support both for BIP-340 and Ed25519


Schnorr-like digital signatures are popular in blockchains as they are simple in design, efficient, and allow for easier aggregate signatures, multi-signatures and threshold signatures. Enabling the support for threshold variants of Schnorr-like schemes on the IC can unlock canisters to host a broader range of crypto assets and opens up the possibility of direct integration with multiple chains. The most popular variants of Schnorr signatures in the crypto space are:

  • BIP340: this is the Schnorr variant used in Bitcoin, and also used in ordinals like BRC-20.
  • Ed25519: used in other chains like Solana, Cardano, Ripple, Polkadot, and others. This is also one of the most popular signature schemes outside of the blockchain space.

Working on this feature, we aim to capture the core implementation of threshold Schnorr-BIP340 and Ed25519 variants, as well as their integration on the Internet Computer. As a result of this, canisters would have public keys for the new signatures schemes, enabling them to derive addresses on other chains, and authorize transactions on those chains.


Work has started

People Involved

@ais, @andrea, @domwoe, @eichhorl, @franzstefan, @JackLloyd


  • One pager on forum (now)
  • t-ECDSA latency improvements (expected: early April)
  • t-ECDSA throughput improvement (expected: mid April)
  • First community conversation (expected: mid-late April)
  • Beta Implementation (people can already play with Dominic’s Schnorr canister)
  • Bounty Program
  • Second community conversation with test key demos (expected: June)
  • NNS Proposal
  • Integration
  • Launch (expected: Summer)


Introducing t-Schnorr furthers ICP’s goal of decentralizing the web and decentralizing crypto. The first major block of work in this direction saw the t-ECDSA implementation integrated to ICP. This coupled with the native bitcoin integration, and the ethereum RPC canister allowed ICP canisters to read and write to Bitcoin and Ethereum. Integrating threshold Schnorr will allow further integrations (eg. with Solana and Cardano) and other cryptographic capabilities. The design principles used for t-ECDSA will largely be reused for t-Schnorr with two modifications:

  • Instead of taking a curve as input, the Schnorr variant is passed in as a parameter. Having variants requires that we also do a key derivation for the corresponding scheme.
  • Instead of creating a signature on the hash of the message (as in ECDSA), the signature is created on the message itself.

Furthermore, there are some improvements being made to t-ECDSA that will also be leveraged by the new schnorr implementation. These improvements are around throughput and latency and will be rolled out in the coming weeks.

High level objective

There are two main parts to getting t-Schnorr on ICP. First we need to implement the threshold cryptography, and then we need to do the system integration.

​​Part 1: Implement the threshold protocols:

  • Distributed Key Generation
    • The IDKG protocol implemented for t-ECDSA will largely be reused for t-Schnorr
  • Key Derivation
    • Will need to do a new KD for Ed25519, but can reuse the BIP32 KD implemented for t-ECDSA
  • Signature generation
    • New implementation

Part 2: Do the system integration:

  • Threshold keys are generated and backed up in subnets
  • Canisters can request signatures and public keys

Proposed API

The proposed API will likely look as follows:

type schnorr_algorithm = variant { bip340secp256k1; ed25519};

schnorr_public_key : (record {
    canister_id : opt canister_id;
    derivation_path : vec blob;
    key_id : record { algorithm: schnorr_algorithm; name: text };
}) -> (record { public_key : blob; chain_code : blob; });

sign_with_schnorr : (record {
    message : blob;
    derivation_path : vec blob;
    key_id : record { algorithm: schnorr_algorithm; name: text };
}) -> (record { signature : blob });

Potential Applications

Threshold Schnorr would unlock several potential multichain features/initiatives:

  • Support Bitcoin taproot tx on the IC:
    • Bitcoin inscriptions
    • Bitcoin fungible tokens like BRC-20
  • Holding of new set of crypto assets in Canisters: BRC-20, SOL, ADA, XRP, …
    • Massively relevant for the chain abstraction narrative and to enhance multichain wallets
  • Creation of more “twin” ck-tokens on the IC: ckBRC20, ckSOL,…
  • Direct integrations with other chains

Threshold Schnorr also has better efficiency than tECDSA:

  • Higher signature throughput.
  • Future iterations could leverage Schnorr-specific techniques to boost efficiency

Threshold Schorr is also widely used more broadly on the Internet:

  • Canisters could sign x.509 certificates and act like a decentralized Certificate Authority
  • GPG signing for software distribution would canisters to form the basis of decentralized repositories


Next Steps

We’d love to hear from you if you would like to use this or have built examples already, if you think there are interesting projects we should talk to, if there’s anything in particular you’d like us to cover in the community conversation, or any other questions or comments.

Super looking forward to this!


SLIP-0010 is a key derivation standard for Ed25519:

Many projects are using it, such as SUI:

, and our NS-Protocol:

According to the definition of BIP32, the derivation_path is actually an vec nat32.

Got it.

SLIP-0010 is already used in the IC in some places. For example, II may be using it to derive recovery keys. It is also used internally for P-256 key derivation.

However, when it comes to Ed25519, SLIP-0010 only specifies hardened key derivation. This means that you must know the secret key even to derive new public keys. In the threshold setting this is an issue as no single party ever knows the full secret key. It is technically possible to use generic MPC protocols to securely compute the evaluation of an hash on shares of a common input. However this is computationally really expensive, and it does not bring any advantage in practice. For example, it is not possible to publicly verify that an hardened key is derived from another, so a user cannot even tell if key derivation was used or whether the new key was generated at random.


How about limitations? For example ingress message size and data chunking?

1 Like

The x.509 signing is very interesting to me, for years it’s been a dream to have ICP be used as a decentralized certificate authority and to possibly build a decentralized DNS (maybe orthogonal project?).


Since Schnorr signatures require providing the entire message rather than just a hash of it, the size of messages that can be signed is bounded by the cross net canister call message limit of 2 MB. The exact limit on the message size will be somewhat less than this, since the xnet call must contain everything else about the signature request (such as the derivation path, key ID, caller information, etc).