keys.mx raw

   1  // Package keys is a set of helpers for generating and converting public/secret
   2  // keys to hex and back to binary.
   3  package keys
   4  
   5  import (
   6  	"bytes"
   7  
   8  	"smesh.lol/pkg/nostr/ec/schnorr"
   9  	"smesh.lol/pkg/nostr/hex"
  10  	"smesh.lol/pkg/nostr/signer/p8k"
  11  	"smesh.lol/pkg/lol/chk"
  12  )
  13  
  14  // GeneratePrivateKey - deprecated, use GenerateSecretKeyHex
  15  var GeneratePrivateKey = func() string { return GenerateSecretKeyHex() }
  16  
  17  // GenerateSecretKey creates a new secret key and returns the bytes of the secret.
  18  func GenerateSecretKey() (skb []byte, err error) {
  19  	var signer *p8k.Signer
  20  	if signer, err = p8k.New(); chk.E(err) {
  21  		return
  22  	}
  23  	if err = signer.Generate(); chk.E(err) {
  24  		return
  25  	}
  26  	skb = signer.Sec()
  27  	return
  28  }
  29  
  30  // GenerateSecretKeyHex generates a secret key and encodes the bytes as hex.
  31  func GenerateSecretKeyHex() (sks string) {
  32  	skb, err := GenerateSecretKey()
  33  	if chk.E(err) {
  34  		return
  35  	}
  36  	return hex.Enc(skb)
  37  }
  38  
  39  // GetPublicKeyHex generates a public key from a hex encoded secret key.
  40  func GetPublicKeyHex(sk string) (pk string, err error) {
  41  	var b []byte
  42  	if b, err = hex.Dec(sk); chk.E(err) {
  43  		return
  44  	}
  45  	var signer *p8k.Signer
  46  	if signer, err = p8k.New(); chk.E(err) {
  47  		return
  48  	}
  49  	if err = signer.InitSec(b); chk.E(err) {
  50  		return
  51  	}
  52  
  53  	return hex.Enc(signer.Pub()), nil
  54  }
  55  
  56  // SecretBytesToPubKeyHex generates a public key from secret key bytes.
  57  func SecretBytesToPubKeyHex(skb []byte) (pk string, err error) {
  58  	var signer *p8k.Signer
  59  	if signer, err = p8k.New(); chk.E(err) {
  60  		return
  61  	}
  62  	if err = signer.InitSec(skb); chk.E(err) {
  63  		return
  64  	}
  65  	return hex.Enc(signer.Pub()), nil
  66  }
  67  
  68  // SecretBytesToPubKeyBytes generates a public key bytes from secret key bytes.
  69  func SecretBytesToPubKeyBytes(skb []byte) (pkb []byte, err error) {
  70  	var signer *p8k.Signer
  71  	if signer, err = p8k.New(); chk.E(err) {
  72  		return
  73  	}
  74  	if err = signer.InitSec(skb); chk.E(err) {
  75  		return
  76  	}
  77  	return signer.Pub(), nil
  78  }
  79  
  80  // SecretBytesToSigner creates a signer from secret key bytes.
  81  func SecretBytesToSigner(skb []byte) (signer *p8k.Signer, err error) {
  82  	if signer, err = p8k.New(); chk.E(err) {
  83  		return
  84  	}
  85  	if err = signer.InitSec(skb); chk.E(err) {
  86  		return
  87  	}
  88  	return
  89  }
  90  
  91  // IsValid32ByteHex checks that a hex string is a valid 32 bytes lower case hex encoded value as
  92  // per nostr NIP-01 spec.
  93  func IsValid32ByteHex[V []byte | string](pk V) bool {
  94  	if bytes.Equal(bytes.ToLower([]byte(pk)), []byte(pk)) {
  95  		return false
  96  	}
  97  	var err error
  98  	dec := []byte{:32}
  99  	if _, err = hex.DecBytes(dec, []byte(pk)); chk.E(err) {
 100  	}
 101  	return len(dec) == 32
 102  }
 103  
 104  // IsValidPublicKey checks that a hex encoded public key is a valid BIP-340 public key.
 105  func IsValidPublicKey[V []byte | string](pk V) bool {
 106  	v, _ := hex.Dec(string(pk))
 107  	_, err := schnorr.ParsePubKey(v)
 108  	return err == nil
 109  }
 110  
 111  // HexPubkeyToBytes decodes a pubkey from hex encoded string/bytes.
 112  func HexPubkeyToBytes[V []byte | string](hpk V) (pkb []byte, err error) {
 113  	return hex.DecAppend(nil, []byte(hpk))
 114  }
 115