NIP-06

In accordance with the Bitcoin Improvement Proposal 0039 (BIP-39) we can derive Nostr keys using seed phrases as a source of entropy. This is handled by the FromMnemonic Trait and its associated methods.

The default functionality is to generate a single key-pair at the derivation path 0. However, it is also possible to perform more advanced derivations by incrementing the account, enabling generation of many sets of keys from a single seed.

For more examples of key generation please refer back to the Keys section of this book.

Key derivation from mnemonic seed phrase (NIP-06)

Rust

TODO

Python

Using the from_mnemonic() method in conjunction with the Keys class to derived a basic set of Nostr keys from a 24 word seed phrase.

Note that this example uses the Mnemonic class from the python-mnemonic package (the reference implementation of BIP-39) to randomly generate example seed phrases.

    # Generate random Seed Phrase (24 words e.g. 256 bits entropy)
    print("Keys from 24 word Seed Phrase:")
    words = Mnemonic("english").generate(strength=256)
    passphrase = ""

    # Use Seed Phrase to generate basic Nostr keys
    keys = Keys.from_mnemonic(words, passphrase)

    print(f" Seed Words (24)  : {words}")
    print(f" Public key bech32: {keys.public_key().to_bech32()}")
    print(f" Secret key bech32: {keys.secret_key().to_bech32()}")

As well as deriving basic keys from a 24 word seed we can also use seed phrases of other lengths such as 18 words or, as in this example, 12 words.

    # Generate random Seed Phrase (12 words e.g. 128 bits entropy)
    print("Keys from 12 word Seed Phrase:")
    words = Mnemonic("english").generate(strength=128)
    passphrase = ""

    # Use Seed Phrase to generate basic Nostr keys
    keys = Keys.from_mnemonic(words, passphrase)

    print(f" Seed Words (12)  : {words}")
    print(f" Public key bech32: {keys.public_key().to_bech32()}")
    print(f" Secret key bech32: {keys.secret_key().to_bech32()}")

Advanced key derivation functionality (for accounts) can be accessed by the from_mnemonic() method. To do this we use the account argument which accepts an integer to specify the derivation path.

    # Advanced (with accounts) from the example wordlist
    words = "leader monkey parrot ring guide accident before fence cannon height naive bean"
    passphrase = ""

    print("Accounts (0-5) from 12 word Seed Phrase (with passphrase):")
    print(f" Seed Words (12): {words}")
    print(" Accounts (0-5) :")

    # Use Seed Phrase and account to multiple Nostr keys
    for account in range(0,6):
        nsec = Keys.from_mnemonic(words, passphrase, account).secret_key().to_bech32()
        print(f"     Account #{account} bech32: {nsec}")

This final example utilizes the same seed as for the previous example, but also includes a passphrase. It illustrates the effect of inclusion of a passphrase on the key derivation.

    # Advanced (with accounts) from the same wordlist with in inclusion of passphrase
    words = "leader monkey parrot ring guide accident before fence cannon height naive bean"
    passphrase = "RustNostr"
    print("Accounts (0-5) from 12 word Seed Phrase (with passphrase):")
    print(f" Seed Words (12): {words}")
    print(f" Passphrase     : {passphrase}")
    print(" Accounts (0-5) :")

    # Use Seed Phrase and account to multiple Nostr keys
    for account in range(0,6):
        nsec = Keys.from_mnemonic(words, passphrase, account).secret_key().to_bech32()
        print(f"     Account #{account} bech32: {nsec}")
JavaScript

TODO

Kotlin

TODO

Swift

TODO