Files
lafsession/identity.go
2026-09-24 11:33:28 +02:00

77 lines
1.6 KiB
Go

package lafsession
import (
"crypto/ed25519"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
)
type Identity struct {
Private ed25519.PrivateKey
Public ed25519.PublicKey
}
func GenerateIdentity() (*Identity, error) {
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
return nil, err
}
return &Identity{Private: priv, Public: pub}, nil
}
func IdentityFromSeed(seed []byte) (*Identity, error) {
if len(seed) != ed25519.SeedSize {
return nil, fmt.Errorf("lafsession: seed must be %d bytes", ed25519.SeedSize)
}
priv := ed25519.NewKeyFromSeed(seed)
return &Identity{Private: priv, Public: priv.Public().(ed25519.PublicKey)}, nil
}
func (id *Identity) PublicBytes() []byte {
return append([]byte(nil), id.Public...)
}
func (id *Identity) Fingerprint() string {
sum := sha256.Sum256(id.Public)
return hex.EncodeToString(sum[:])
}
func (id *Identity) ShortFingerprint() string {
sum := sha256.Sum256(id.Public)
h := hex.EncodeToString(sum[:20])
out := make([]byte, 0, 24+5)
for i := 0; i < len(h); i += 4 {
if i > 0 {
out = append(out, ' ')
}
end := i + 4
if end > len(h) {
end = len(h)
}
out = append(out, h[i:end]...)
}
return string(out)
}
func (id *Identity) Sign(msg []byte) []byte {
return ed25519.Sign(id.Private, msg)
}
func (id *Identity) Verify(msg, sig []byte) bool {
return ed25519.Verify(id.Public, msg, sig)
}
func VerifyPeer(peerPub, msg, sig []byte) bool {
if len(peerPub) != ed25519.PublicKeySize {
return false
}
return ed25519.Verify(peerPub, msg, sig)
}
func FingerprintOf(pub []byte) string {
sum := sha256.Sum256(pub)
return hex.EncodeToString(sum[:])
}