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 }