github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/portxo/keygen.go (about)

     1  package portxo
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  )
     8  
     9  // KeyGen describes how to get to the key from the master / seed.
    10  // it can be used with bip44 or other custom schemes (up to 5 levels deep)
    11  // Depth must be 0 to 5 inclusive.  Child indexes of 0 are OK, so we can't just
    12  // terminate at the first 0.
    13  type KeyGen struct {
    14  	Depth   uint8     `json:"depth"`   // how many levels of the path to use. 0 means privkey as-is
    15  	Step    [5]uint32 `json:"steps"`   // bip 32 / 44 path numbers
    16  	PrivKey [32]byte  `json:"privkey"` // private key
    17  }
    18  
    19  // Bytes returns the 53 byte serialized key derivation path.
    20  // always works
    21  func (k KeyGen) Bytes() []byte {
    22  	var buf bytes.Buffer
    23  	binary.Write(&buf, binary.BigEndian, k.Depth)
    24  	binary.Write(&buf, binary.BigEndian, k.Step[0])
    25  	binary.Write(&buf, binary.BigEndian, k.Step[1])
    26  	binary.Write(&buf, binary.BigEndian, k.Step[2])
    27  	binary.Write(&buf, binary.BigEndian, k.Step[3])
    28  	binary.Write(&buf, binary.BigEndian, k.Step[4])
    29  	buf.Write(k.PrivKey[:])
    30  	return buf.Bytes()
    31  }
    32  
    33  // KeyGenFromBytes turns a 53 byte array into a key derivation path.  Always works
    34  // (note a depth > 5 path is invalid, but this just deserializes & doesn't check)
    35  func KeyGenFromBytes(b [53]byte) (k KeyGen) {
    36  	buf := bytes.NewBuffer(b[:])
    37  	binary.Read(buf, binary.BigEndian, &k.Depth)
    38  	binary.Read(buf, binary.BigEndian, &k.Step[0])
    39  	binary.Read(buf, binary.BigEndian, &k.Step[1])
    40  	binary.Read(buf, binary.BigEndian, &k.Step[2])
    41  	binary.Read(buf, binary.BigEndian, &k.Step[3])
    42  	binary.Read(buf, binary.BigEndian, &k.Step[4])
    43  	copy(k.PrivKey[:], buf.Next(32))
    44  	return
    45  }
    46  
    47  // String turns a keygen into a string
    48  func (k KeyGen) String() string {
    49  	var s string
    50  	//	s = fmt.Sprintf("\tkey derivation path: m")
    51  	for i := uint8(0); i < k.Depth; i++ {
    52  		if k.Step[i]&0x80000000 != 0 { // high bit means hardened
    53  			s += fmt.Sprintf("/%d'", k.Step[i]&0x7fffffff)
    54  		} else {
    55  			s += fmt.Sprintf("/%d", k.Step[i])
    56  		}
    57  	}
    58  	return s
    59  }