Files
2026-04-04 19:36:14 +02:00

69 lines
1.4 KiB
Go

package crypto
import (
"crypto/rand"
"encoding/hex"
"golang.org/x/crypto/chacha20"
"golang.org/x/crypto/nacl/box"
)
func GenerateKey() ([]byte, []byte, error) {
public, private, err := box.GenerateKey(rand.Reader)
if err != nil {
return nil, nil, err
}
return public[:], private[:], err
}
func CalcSharedKey(devicePublicB64, clientPrivateB64 string) ([]byte, error) {
var sharedKey, publicKey, privateKey [32]byte
if _, err := hex.Decode(publicKey[:], []byte(devicePublicB64)); err != nil {
return nil, err
}
if _, err := hex.Decode(privateKey[:], []byte(clientPrivateB64)); err != nil {
return nil, err
}
box.Precompute(&sharedKey, &publicKey, &privateKey)
return sharedKey[:], nil
}
func Encode(src, key32 []byte) ([]byte, error) {
dst := make([]byte, len(src)+8)
if _, err := rand.Read(dst[:8]); err != nil {
return nil, err
}
nonce12 := make([]byte, 12)
copy(nonce12[4:], dst[:8])
c, err := chacha20.NewUnauthenticatedCipher(key32, nonce12)
if err != nil {
return nil, err
}
c.XORKeyStream(dst[8:], src)
return dst, nil
}
func Decode(src, key32 []byte) ([]byte, error) {
return DecodeNonce(src[8:], src[:8], key32)
}
func DecodeNonce(src, nonce8, key32 []byte) ([]byte, error) {
nonce12 := make([]byte, 12)
copy(nonce12[4:], nonce8)
c, err := chacha20.NewUnauthenticatedCipher(key32, nonce12)
if err != nil {
return nil, err
}
dst := make([]byte, len(src))
c.XORKeyStream(dst, src)
return dst, nil
}