Obsidian Systems - Schnorr Crypto Primitives on Nervos CKB

Team and Background

Obsidian Systems was founded in 2014 by Ali Abrar and Ryan Trinkle, who continue to serve as its managing partners today. It consists of approximately 39 software developers, quality assurance engineers, management professionals, and other staff.

Obsidian Systems designs and develops high quality software solutions to pressing business problems. Our experienced team has delivered mission-critical solutions to a variety of high-profile clients, including several Fortune 500 companies, national retail firms, and blockchains such as Tezos, Kadena, Nervos, Avalanche, and Solana. These solutions secure millions of dollars in cryptographic assets (Tezos Baking/Wallet Ledger applications), lower the technical barrier to participation in consensus (Kiln), and facilitate the development of smart contracts (Pact and Chainweaver).

Our solutions are currently used by thousands of employees and tens of thousands of consumers every day.

We have built the Nervos Ledger application and made it accessible to app developers through LedgerJS. We’ve also built the first plugin for CKB-CLI for the Ledger integration. Through this work we’ve become very familiar with Nervos’ architecture, value proposition, and cryptography.

You can find us on Github, Gitlab, Medium, and Twitter.

Project and Justification

Schnorr signatures have finally been merged into Bitcoin Core. The reasoning behind this is well outlined in BIP-340 and there has been ample discussion surrounding its impact on privacy, security, and payment channels.

Like Bitcoin, Nervos uses ECDSA signatures over the secp256k1 curve, though the two use different hashing functions (Bitcoin uses SHA256 while Nervos uses Blake2b). This similarity makes it possible for Nervos to adopt this cryptography. Due to CKB’s flexible and extensible design, new cryptographic primitives can be added without the need for a software upgrade, a powerful capability we’d exercise here as others have done as well.

Schnorr signatures have a few advantages that make them very attractive. First, they are provably secure, whereas standard secp256k1 signatures are not. They are similarly non-malleable, meaning a third party without access to the secret key cannot change an existing valid signature into another signature for that private key and message which is still valid despite its alteration.

These properties are certainly desirable, but linearity is the most attractive feature of Schnorr signatures: multiple public keys can be combined off-chain to produce a single signature representing their sum which appears on-chain no different than a standard secp256k1 signature.

Multisigs using secp256k1 are native to CKB and allow expression of a diverse and robust set of signing requirements. For instance, token issuers who need strict approval from multiple parties can enforce these requirements with code, or apps can ‘authorize’ their user’s actions within their platform by requiring their own signature in addition to the user’s.

The secp256k1 multisig currently available is powerful and can underpin many use cases, but it reveals information about the signers. Anyone can determine the number of signatures required, which keys are valid signers, and which keys signed in a given instance.

Schnorr signatures can keep all of this information private through off-chain key aggregation without sacrificing any of the benefits of CKB’s native multisig. Instead of keys being aggregated on-chain and thus visible to others, a Schnorr signature appears as a single signature with no indication of how many or what signatures contributed. This aggregated signature also occupies less space on-chain and is indistinguishable from a standard secp256k1 signature.

Introducing these capabilities with Schnorr makes the Nervos ecosystem even more attractive to anyone interested in strong cryptography, keeping sensitive information about asset management private, and many other possibilities.

Technical Specification and Implementation

There are three parts to this proposal:

  1. Place a schnorr-secp256k1 script on CKB
  2. Create a Lumos-compatible Schnorr library
  3. Build a demo app which uses the schnorr-secp256k1 on-chain script and the off-chain Schnorr library with Lumos

All development done as part of this proposal will be open source.

Schnorr-secp256k1 Script on CKB

We’ll use elements of the schnorr-secp256k1 signature library being added to Bitcoin by placing it in the type-script of a cell on CKB which can then be referenced by other cells in their lock script, allowing them to use this crypto primitive.

This script will be written in C and will build upon the work that’s been done with other scripts thus far, such as that found in ckb-system-scripts.

To assist ourselves in the script development process, we will create a framework that pulls in tools such as ckb-system-scripts and Capsule so we can:

  1. Measure VM cycles consumed by a our schnorr-secp256k1 signature
  2. Deploy the schnorr-secp256k1 lock script to a given chain (ie. Lina, Aggron, dev chain, etc)
  3. Create keypairs and corresponding addresses using the schnorr-secp256k1 crypto primitive and spend from them
  4. Produce automated scripts for the three items listed above

Lumos-Compatible Schnorr Library

The Schnorr lock script is most valuable if application developers can easily use it. Lumos, the Javascript/Typescript Dapp framework for Nervos CKB, already allows Dapp developers to use various crypto primitives, making it a logical integration target.

We’ll write a Schnorr library intended to be used with Lumos. The Schnorr Library will support four functions:

  1. Create new schnorr-secp256k1 standard address - This creates a standard schnorr-secp256k1 address that can then be used as a signer in a schnorr multisig address.

  2. Sign with schnorr-secp256k1 standard address - Signs a transfer with a standard schnorr-secp256k1 address

  3. Create schnorr-secp256k1 multisig address - Creates a schnorr-secp256k1 multisig address with standard schnorr-secp256k1 addresses. Users will have the same options when creating this address as they do with the existing multisigs in CKB-CLI:

    • List the addresses to be used as signers (—sighash-address analog)
    • Require N of those addresses for a valid signature (—require-first-n analog)
    • Setting the threshold of signature required for a valid signature (—threshold analog)
    • Setting a timelock based on the epochs since genesis (—since-absolute-epoch analog)
  4. Aggregate standard schnorr-secp256k1 signatures - This function forms the multisig schorr-secp256k1 signature.

The signing algorithm in our library will sign pre-serialized data so another existing tool, like Lumos or CKB-CLI, can be used to handle the parts of the transaction not supported in this library.

Message signing will not be supported at this time, as only recoverable pre-hashed messages are supported in Lumos and recoverable signatures are not supported by schnorr-secp256k1. We will build our integration against v0.12.0.

Demo Application

To help other developers use Schnorr signatures on CKB, we’ll create a basic web application that uses the Schnorr lock script, Lumos, and the Lumos-compatible Schnorr Library. We’ll also write a guide that walks a developer through how they can implement this themselves.

Demo app features are:

  1. Create standard schnorr-secp256k1 address(es)
  2. Create a multisig schnorr-secp256k1 address
  3. Create a transfer from the Multisig schnorr address
  4. Sign the transfer with standard schnorr-secp256k1 address(es)
  5. Aggregate standard schnorr-secp256k1 signatures to form the multisig schnorr secp256k1 signature.
  6. Submit the signed transfer to a node and display the operation hash

While we won’t host the demo app, interested parties can run it locally and configure the node (ie. network) to which they would like to connect.

Timeline and Project Duration

The entire duration of this project is 3 months.

Checkpoint 1 - 1 Month

  • Support for standard secp256k1 signatures in our lock script dev framework
  • schnorr-secp256k1 lock script development complete

Checkpoint 2 - 1 Month

  • Support for schnorr-secp256k1 signatures in our lock script dev framework
  • Lumos-Compatible Schnorr Library Complete

Checkpoint 3 - 1 Month

  • schnorr-secp25k61 Demo app complete
  • Schnorr example added to Lumos’ Common Scripts