keys.mx raw

   1  package bech32encoding
   2  
   3  import (
   4  	"bytes"
   5  
   6  	"crypto/ec/bech32"
   7  	"crypto/secp256k1"
   8  	"git.smesh.lol/nostr/pkg/hex"
   9  	"git.smesh.lol/nostr/pkg/lol/chk"
  10  	"git.smesh.lol/nostr/pkg/lol/log"
  11  )
  12  
  13  const (
  14  	MinKeyStringLen = 56
  15  	HexKeyLen       = 64
  16  	Bech32HRPLen    = 4
  17  )
  18  
  19  var (
  20  	SecHRP []byte
  21  	PubHRP []byte
  22  )
  23  
  24  func init() {
  25  	SecHRP = []byte("nsec")
  26  	PubHRP = []byte("npub")
  27  	NoteHRP = []byte("note")
  28  	NsecHRP = []byte("nsec")
  29  	NpubHRP = []byte("npub")
  30  	NprofileHRP = []byte("nprofile")
  31  	NeventHRP = []byte("nevent")
  32  	NentityHRP = []byte("naddr")
  33  }
  34  
  35  func ConvertForBech32(b8 []byte) (b5 []byte, err error) {
  36  	return bech32.ConvertBits(b8, 8, 5, true)
  37  }
  38  
  39  func ConvertFromBech32(b5 []byte) (b8 []byte, err error) {
  40  	return bech32.ConvertBits(b5, 5, 8, true)
  41  }
  42  
  43  func NsecToBytes(encoded []byte) (sk []byte, err error) {
  44  	var b5, hrp []byte
  45  	if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
  46  		return
  47  	}
  48  	if !bytes.Equal(hrp, SecHRP) {
  49  		err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, SecHRP)
  50  		return
  51  	}
  52  	if sk, err = ConvertFromBech32(b5); chk.E(err) {
  53  		return
  54  	}
  55  	sk = sk[:secp256k1.PubKeyBytesLen]
  56  	return
  57  }
  58  
  59  func NpubToBytes(encoded []byte) (pk []byte, err error) {
  60  	var b5, hrp []byte
  61  	if hrp, b5, err = bech32.Decode(encoded); chk.E(err) {
  62  		return
  63  	}
  64  	if !bytes.Equal(hrp, PubHRP) {
  65  		err = log.E.Err([]byte("wrong human readable part, got '%s' want '%s'"), hrp, PubHRP)
  66  		return
  67  	}
  68  	if pk, err = ConvertFromBech32(b5); chk.E(err) {
  69  		return
  70  	}
  71  	pk = pk[:secp256k1.PubKeyBytesLen]
  72  	return
  73  }
  74  
  75  func HexToNpub(publicKeyHex []byte) (s []byte, err error) {
  76  	b := []byte{:secp256k1.PubKeyBytesLen}
  77  	if _, err = hex.DecBytes(b, publicKeyHex); chk.D(err) {
  78  		return
  79  	}
  80  	var bits5 []byte
  81  	if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
  82  		return
  83  	}
  84  	return bech32.Encode(NpubHRP, bits5)
  85  }
  86  
  87  func BinToNpub(b []byte) (s []byte, err error) {
  88  	var bits5 []byte
  89  	if bits5, err = bech32.ConvertBits(b, 8, 5, true); chk.D(err) {
  90  		return
  91  	}
  92  	return bech32.Encode(NpubHRP, bits5)
  93  }
  94  
  95  func BinToNsec(sk []byte) (nsec []byte, err error) {
  96  	var b5 []byte
  97  	if b5, err = ConvertForBech32(sk); chk.E(err) {
  98  		return
  99  	}
 100  	return bech32.Encode(SecHRP, b5)
 101  }
 102  
 103  func HexToNsec(sk []byte) (nsec []byte, err error) {
 104  	if len(sk) != HexKeyLen {
 105  		err = log.E.Err([]byte("secret key is %d bytes, must be %d"), len(sk), HexKeyLen)
 106  		return
 107  	}
 108  	pb := []byte{:secp256k1.PubKeyBytesLen}
 109  	if _, err = hex.DecBytes(pb, sk); chk.D(err) {
 110  		return
 111  	}
 112  	return BinToNsec(pb)
 113  }
 114  
 115  func NsecToHex(nsec []byte) (hexSec []byte, err error) {
 116  	var sk []byte
 117  	if sk, err = NsecToBytes(nsec); chk.E(err) {
 118  		return
 119  	}
 120  	return hex.EncAppend(nil, sk), nil
 121  }
 122