slip10

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2025 License: MIT Imports: 9 Imported by: 2

README

Ed25519 private key derivation from master private key

Golang SLIP-0010 implementation(ed25519 only) according to the https://github.com/satoshilabs/slips/blob/master/slip-0010.md

Example

    package main

    import (
    	"encoding/hex"
    	"fmt"

    	slip10 "github.com/anyproto/go-slip10"
    )

    func main() {
    	seed, err := hex.DecodeString("000102030405060708090a0b0c0d0e0f")
    	if err != nil {
    		panic(err)
    	}

    	// example vector 1: https://github.com/satoshilabs/slips/blob/master/slip-0010.md#test-vector-1-for-ed25519
    	node, err := slip10.DeriveForPath("m/0'/1'", seed)
    	if err != nil {
    		panic(err)
    	}

    	pub, priv, err := node.Keypair()
    	if err != nil {
    		panic(err)
    	}

    	// prints b1d0bad404bf35da785a64ca1ac54b2617211d2777696fbffaf208f746ae84f2
    	fmt.Printf("%x\n", priv)

    	// prints 1932a5270f335bed617d5b935c80aedb1a35bd9fc1e31acafd5372c30f5c1187
    	// You can notice that example at https://github.com/satoshilabs/slips/blob/master/slip-0010.md#test-vector-1-for-ed25519
    	// adds 0x00 prefix for the public key. Because we are using native crypto/ed25519 for the keypair we won't do this for the Keypair() method
    	fmt.Printf("%x\n", pub)

    	// but you can use node.PublicKeyWithPrefix() to get the public key with prefix
    	pubK, err := node.PublicKeyWithPrefix()
    	if err != nil {
    		panic(err)
    	}

    	// prints 001932a5270f335bed617d5b935c80aedb1a35bd9fc1e31acafd5372c30f5c1187
    	fmt.Printf("%x\n", pubK)
    }

Licensing

The code in this project is licensed under the MIT License

Documentation

Index

Constants

View Source
const (
	// FirstHardenedIndex is the index of the first hardened key (2^31).
	// https://youtu.be/2HrMlVr1QX8?t=390
	FirstHardenedIndex = uint32(0x80000000)
)

Variables

View Source
var (
	ErrInvalidPath        = fmt.Errorf("invalid derivation path")
	ErrNoPublicDerivation = fmt.Errorf("no public derivation for ed25519")
)

Functions

func IsValidPath

func IsValidPath(path string) bool

IsValidPath check whether or not the path has valid segments.

Types

type Node

type Node interface {
	Derive(i uint32) (Node, error)

	Keypair() (ed25519.PublicKey, ed25519.PrivateKey)
	PrivateKey() []byte
	PublicKeyWithPrefix() []byte
	RawSeed() []byte
	MarshalBinary() ([]byte, error)
}

func DeriveForPath

func DeriveForPath(path string, rootSeed []byte) (Node, error)

DeriveForPath derives the node at `path` starting from a ROOT seed.

Use this when you have the rootSeed(e.g. extracted from the mnemonic) and a derivation path, and you want to deterministically re-create the SAME node every time from the root.

Do NOT pass a node's RawSeed() here — that 32-byte value is only the ed25519 key seed for that node and does not include its chain code. Feeding it here creates a NEW unrelated root.

func NewMasterNode

func NewMasterNode(rootSeed []byte) (Node, error)

NewMasterNode constructs the SLIP-0010 *master node* from a ROOT seed.

Use this when you have the original root entropy and want to (re)build a tree deterministically from the top (e.g., together with a path like "m/44'/..."). Security: anyone with rootSeed can derive the entire tree. Treat as highly sensitive.

rootSeed: arbitrary-length seed per SLIP-0010 (typically 16–64 bytes).

func UnmarshalNode added in v1.0.1

func UnmarshalNode(b []byte) (Node, error)

UnmarshalNode restores a node from a 64-byte key||chainCode blob produced by MarshalBinary. Use this when you saved a node checkpoint and want to continue deriving BELOW that node.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL