Owner: @Giacomo Pasini

Reviewers: 🟢@Thomas Lavaur 🟢@Mehmet 🟢@Daniel Sanchez Quiros 🟢@Álvaro Castro-Castilla

Introduction

The main motivation behind this spec is avoiding being locked into a wallet software. By specifying the algorithms used to derive keys, we allow user to easily migrate from one implementation to the other.

Overview

This document mostly follows pre-existing standards in Bitcoin and adapts it to Nomos needs when necessary. This is also the choice of other Bitcoin-inspired projects like Cardano or Zcash. For this reason, this document will not go over the entire spec itself, and just highlight differences with existing standards.

Mnemonic codes for key generation

Mnemonic codes are far easier to interact with as humans than raw binary or hex strings and are the standard for wallets. In this regard we can reuse ‣ entirely, as it’s just operations on strings and bytes.

HD wallet

Hierarchical Deterministic (HD) wallets are nowadays the standard. Using a single source of entropy (usually obtained through the process above) it’s possible to generate many different addresses and share all or part of it.

The industry standard is BIP32. However, we can’t use it as it is, as we use different keys and cryptographic components. In addition, some of the BIP32 features are only possible thanks to homomorphic properties of ECC, which we don’t have in Nomos since we use hash-based sk/pk.

image.png

BIP-32 specifies two kind of child keys:

Unfortunately, ‘normal’ children are possibly thanks to specific properties of the keys used in Bitcoin that we don’t have in Nomos (namely, homomorphism).

To maintain compatibility, we will still use the same structure but non-hardened children will not be available.

<aside> 💡

Extended Keys (from BIP32)

In what follows, we will define a function that derives a number of child keys from a parent key. In order to prevent these from depending solely on the key itself, we extend both private and public keys first with an extra 256 bits of entropy. This extension, called the chain code, is identical for corresponding private and public keys, and consists of 32 bytes.

We represent an extended private key as (k, c), with k the normal private key, and c the chain code. An extended public key is represented as $(K, c)$, with $K = hash("NOMOS\_KDF\_V1", k)$ and $c$ the chain code.

Each extended key has $2^{31}$ hardened children keys. Each of these child key has an index. The hardened child keys use indices from $2^{31}$  through $2^{32} -1$.

</aside>

Details

We only highlight the differences with the aforementioned protocols instead of going over all the details again as they’re already covered extensively elsewhere.