cipher.go raw

   1  package cipher
   2  
   3  import (
   4  	"fmt"
   5  
   6  	"github.com/getAlby/go-nostr/nip04"
   7  	"github.com/getAlby/go-nostr/nip44"
   8  	"github.com/getAlby/hub/constants"
   9  )
  10  
  11  const (
  12  	SUPPORTED_VERSIONS    = "0.0 1.0"
  13  	SUPPORTED_ENCRYPTIONS = "nip44_v2 nip04"
  14  )
  15  
  16  type Nip47Cipher struct {
  17  	encryption      string
  18  	pubkey          string
  19  	privkey         string
  20  	sharedSecret    []byte
  21  	conversationKey [32]byte
  22  }
  23  
  24  func NewNip47Cipher(encryption, pubkey, privkey string) (*Nip47Cipher, error) {
  25  	_, err := isEncryptionSupported(encryption)
  26  	if err != nil {
  27  		return nil, err
  28  	}
  29  
  30  	var ss []byte
  31  	var ck [32]byte
  32  	if encryption == constants.ENCRYPTION_TYPE_NIP04 {
  33  		ss, err = nip04.ComputeSharedSecret(pubkey, privkey)
  34  		if err != nil {
  35  			return nil, err
  36  		}
  37  	} else {
  38  		ck, err = nip44.GenerateConversationKey(pubkey, privkey)
  39  		if err != nil {
  40  			return nil, err
  41  		}
  42  	}
  43  
  44  	return &Nip47Cipher{
  45  		encryption:      encryption,
  46  		pubkey:          pubkey,
  47  		privkey:         privkey,
  48  		sharedSecret:    ss,
  49  		conversationKey: ck,
  50  	}, nil
  51  }
  52  
  53  func (c *Nip47Cipher) Encrypt(message string) (msg string, err error) {
  54  	if c.encryption == constants.ENCRYPTION_TYPE_NIP04 {
  55  		msg, err = nip04.Encrypt(message, c.sharedSecret)
  56  		if err != nil {
  57  			return "", err
  58  		}
  59  	} else {
  60  		msg, err = nip44.Encrypt(message, c.conversationKey)
  61  		if err != nil {
  62  			return "", err
  63  		}
  64  	}
  65  	return msg, nil
  66  }
  67  
  68  func (c *Nip47Cipher) Decrypt(content string) (payload string, err error) {
  69  	if c.encryption == constants.ENCRYPTION_TYPE_NIP04 {
  70  		payload, err = nip04.Decrypt(content, c.sharedSecret)
  71  		if err != nil {
  72  			return "", err
  73  		}
  74  	} else {
  75  		payload, err = nip44.Decrypt(content, c.conversationKey)
  76  		if err != nil {
  77  			return "", err
  78  		}
  79  	}
  80  	return payload, nil
  81  }
  82  
  83  func isEncryptionSupported(encryption string) (bool, error) {
  84  	if encryption == constants.ENCRYPTION_TYPE_NIP44_V2 || encryption == constants.ENCRYPTION_TYPE_NIP04 {
  85  		return true, nil
  86  	}
  87  
  88  	return false, fmt.Errorf("invalid encryption: %s", encryption)
  89  }
  90