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

     1  package wallit
     2  
     3  import (
     4  	"github.com/mit-dci/lit/btcutil"
     5  	"github.com/mit-dci/lit/crypto/koblitz"
     6  	"github.com/mit-dci/lit/logging"
     7  	"github.com/mit-dci/lit/portxo"
     8  )
     9  
    10  /*
    11  Key derivation for a TxStore has 3 levels: use case, peer index, and keyindex.
    12  Regular wallet addresses are use 0, peer 0, and then a linear index.
    13  The identity key is use 11, peer 0, index 0.
    14  Channel multisig keys are use 2, peer and index per peer and channel.
    15  Channel refund keys are use 3, peer and index per peer / channel.
    16  */
    17  
    18  // =====================================================================
    19  // OK only use these now
    20  
    21  // PathPrivkey returns a private key by descending the given path
    22  // Returns nil if there's an error.
    23  func (w *Wallit) PathPrivkey(kg portxo.KeyGen) *koblitz.PrivateKey {
    24  	// in uspv, we require path depth of 5
    25  	if kg.Depth != 5 {
    26  		return nil
    27  	}
    28  	priv, err := kg.DerivePrivateKey(w.rootPrivKey)
    29  	if err != nil {
    30  		logging.Errorf("PathPrivkey err %s", err.Error())
    31  		return nil
    32  	}
    33  	return priv
    34  }
    35  
    36  // PathPubkey returns a public key by descending the given path.
    37  // Returns nil if there's an error.
    38  func (w *Wallit) PathPubkey(kg portxo.KeyGen) *koblitz.PublicKey {
    39  	priv := w.PathPrivkey(kg)
    40  	if priv == nil {
    41  		return nil
    42  	}
    43  	return w.PathPrivkey(kg).PubKey()
    44  }
    45  
    46  // PathPubHash160 returns a 20 byte pubkey hash for the given path
    47  // It'll always return 20 bytes, or a nil if there's an error.
    48  func (w *Wallit) PathPubHash160(kg portxo.KeyGen) [20]byte {
    49  	var pkh [20]byte
    50  	pub := w.PathPubkey(kg)
    51  	if pub == nil {
    52  		return pkh
    53  	}
    54  	copy(pkh[:], btcutil.Hash160(pub.SerializeCompressed()))
    55  
    56  	return pkh
    57  }
    58  
    59  // ------------- end of 2 main key deriv functions
    60  
    61  // get a private key from the regular wallet
    62  func (w *Wallit) GetWalletPrivkey(idx uint32) *koblitz.PrivateKey {
    63  	var kg portxo.KeyGen
    64  	kg.Depth = 5
    65  	kg.Step[0] = 44 | 1<<31
    66  	kg.Step[1] = w.Param.HDCoinType | 1<<31
    67  	kg.Step[2] = 0 | 1<<31
    68  	kg.Step[3] = 0 | 1<<31
    69  	kg.Step[4] = idx | 1<<31
    70  	return w.PathPrivkey(kg)
    71  }
    72  
    73  // GetWalletKeygen returns the keygen for a standard wallet address
    74  func GetWalletKeygen(idx, cointype uint32) portxo.KeyGen {
    75  	var kg portxo.KeyGen
    76  	kg.Depth = 5
    77  	kg.Step[0] = 44 | 1<<31
    78  	kg.Step[1] = cointype | 1<<31
    79  	kg.Step[2] = 0 | 1<<31
    80  	kg.Step[3] = 0 | 1<<31
    81  	kg.Step[4] = idx | 1<<31
    82  	return kg
    83  }
    84  
    85  // GetUsePrive generates a private key for the given use case & keypath
    86  func (w *Wallit) GetUsePriv(kg portxo.KeyGen, use uint32) *koblitz.PrivateKey {
    87  	kg.Step[2] = use
    88  	return w.PathPrivkey(kg)
    89  }
    90  
    91  // GetUsePub generates a pubkey for the given use case & keypath
    92  func (w *Wallit) GetUsePub(kg portxo.KeyGen, use uint32) [33]byte {
    93  	var b [33]byte
    94  	pub := w.GetUsePriv(kg, use).PubKey()
    95  	if pub != nil {
    96  		copy(b[:], pub.SerializeCompressed())
    97  	}
    98  	return b
    99  }