This specification provides an optional method for Nostr Clients, NIP-07 providers and Wallet providers to generate deterministic private keys from chain-agnostic CAIP-122 Signatures (`Sign-In-With-X` specification). The keypairs generated using this specification are Nostr-specific and do not expose the original signing keypair. The new private keys are derived using SHA-256 HMAC Key Derivation Function (HKDF) with NIP-02 or NIP-05 names, CAIP-02 Blockchain ID & CAIP-10 Account ID Specification identifiers, and deterministic signatures from connected wallets as inputs.
## Introduction
NIP-XX at its core is an account abstraction specification in which a cryptographic signature calculated by one signing algorithm and its native keypair (e.g. [Bitcoin-native Schnorr algorithm](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki)) can be used to derive a deterministic cryptographic keypair for another signing algorithm (e.g. [Ethereum-native ECDSA algorithm](https://eips.ethereum.org/EIPS/eip-191)) using an appropriate singular (non-invertible) key derivation function. This specification particularly describes the case where the former and latter algorithms are Schnorr and ECDSA respectively, and the one-way adaptor from ECDSA to Schnorr keypair is HMAC-based Key Derivation Function ([HKDF](https://datatracker.ietf.org/doc/html/rfc586)).
NIP-XX specification originated from the desire to allow Nostr to function with widely popular Ethereum wallets such as Metamask and leverage the strong network effects of Ethereum ecosystem. The problem however lay in the fact that Nostr Protocol uses Bitcoin-native Schnorr algorithm for signing messages/data while Ethereum (and its wallets such as Metamask etc) uses ECDSA algorithm. The difference in two signing algorithms and respective signing keypairs is the exact technical incompatibility that this specification originally succeeded in resolving by enabling [Sign-In With Ethereum](https://login.xyz) (SIWE) on Nostr. The underlying schema however is fully capable of functioning as a chain-agnostic workflow and this improved draft reflects that property by using [CAIP](https://github.com/ChainAgnostic/CAIPs) (Chain-Agnostic Improvement Proposals) implementations.
Chain-agnostic [CAIP-02: Blockchain ID Specification](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md) and [CAIP-10: Account ID Specification](https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-10.md) schemes are used to generate blockchain and address identifiers,
-`info` is CAIP-10 and NIP-02/NIP-05 identifier string formatted as:
```js
let info = `${caip10}:${username}`;
```
### e) Message
Deterministic message to be signed by the wallet provider,
```js
let message = `Login to Nostr as ${username}\n\nImportant: Please verify the integrity and authenticity of your Nostr client before signing this message.\n${info}`
[RFC-6979](https://datatracker.ietf.org/doc/html/rfc6979) compatible (ECDSA) deterministic signature calculated by the wallet provider using native keypair,
```js
let signature = wallet.signMessage(message);
```
### g) Salt
-`salt` is SHA-256 hash of the `info`, optional password and last **32 bytes** of signature string formatted as:
```js
let salt = await sha256(`${info}:${password?password:""}:${signature.slice(68)}`);
```
where, `signature.slice(68)` are the last 32 bytes of the deterministic ECDSA-derived Ethereum signature.
### h) Key Derivation Function (KDF)
HMAC-Based KDF `hkdf(sha256, inputKey, salt, info, dkLen = 42)` is used to derive the **42 bytes** long **hashkey** with inputs,
[FIPS 186-4 B.4.1](https://csrc.nist.gov/publications/detail/fips/186/4/final) requires hashkey length to be `>= n + 8`, where `n = 32` is the **bytelength** of the final `secp256k1` private key, such that `42 >= 32 + 8`.
-`hashToPrivateKey()` function is FIPS 186-4 B.4.1 implementation to convert HKDF-derived hashkey to valid `secp256k1` keypair. This function is implemented in JavaScript library `@noble/secp256k1` as `hashToPrivateKey()`.
let message = `Login to Nostr as ${username}\n\nImportant: Please verify the integrity and authenticity of your Nostr client before signing this message.\n${caip10}`