package model import ( "crypto/rand" "fmt" "golang.org/x/crypto/nacl/secretbox" "io" ) type Group struct { GroupID string GroupKey [32]byte GroupServer string Timeline []Message } func NewGroup(server string) *Group { group := new(Group) group.GroupServer = server var groupID [16]byte if _, err := io.ReadFull(rand.Reader, groupID[:]); err != nil { panic(err) } group.GroupID = fmt.Sprintf("%x", groupID) var groupKey [32]byte if _, err := io.ReadFull(rand.Reader, groupKey[:]); err != nil { panic(err) } copy(group.GroupKey[:], groupKey[:]) return group } func (g *Group) AddMember() { // TODO: Rotate Key } func (g *Group) RemoveMember() { // TODO: Rotate Key } func (g *Group) EncryptMessage(message string) []byte { var nonce [24]byte if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil { panic(err) } encrypted := secretbox.Seal(nonce[:], []byte(message), &nonce, &g.GroupKey) return encrypted } func (g *Group) DecryptMessage(ciphertext []byte) (bool, string) { var decryptNonce [24]byte copy(decryptNonce[:], ciphertext[:24]) decrypted, ok := secretbox.Open(nil, ciphertext[24:], &decryptNonce, &g.GroupKey) if ok { return true, string(decrypted) } return false, "" }