forked from cwtch.im/cwtch
61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
|
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, ""
|
||
|
}
|