package beaconcrypt
import (
"bytes"
"testing"
)
func registerBeacon(t *testing.T, server *Server, beacon *Beacon) []byte {
t.Helper()
message := bytes.Repeat([]byte{0xff}, 32)
phase1, err := beacon.GenerateRegistration()
if err != nil {
t.Fatal(err)
}
regOut, err := server.RegisterBeacon(phase1, message)
if err != nil {
t.Fatal(err)
}
if regOut.KeyID == 0 {
t.Fatal("expected non-zero beacon key id")
}
phase2, err := beacon.ProcessInitialMessage(regOut.Serialized)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(phase2, message) {
t.Fatalf("initial message mismatch: got %x want %x", phase2, message)
}
return phase2
}
func newServer(t *testing.T) *Server {
t.Helper()
server, err := NewServer(0)
if err != nil {
t.Fatal(err)
}
t.Cleanup(server.Close)
return server
}
func newBeacon(t *testing.T, serverPK []byte) *Beacon {
t.Helper()
beacon, err := NewBeacon(0, serverPK)
if err != nil {
t.Fatal(err)
}
t.Cleanup(beacon.Close)
return beacon
}
func TestRegister(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
beacon := newBeacon(t, serverPK)
if registerBeacon(t, server, beacon) == nil {
t.Fatal("expected registration to return initial message")
}
}
func TestEncryptToMultiple(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
b1 := newBeacon(t, serverPK)
b2 := newBeacon(t, serverPK)
message := bytes.Repeat([]byte{0x01}, 32)
b1Initial := registerBeacon(t, server, b1)
b2Initial := registerBeacon(t, server, b2)
if !bytes.Equal(b2Initial, b1Initial) {
t.Fatalf("initial messages differ: got %x want %x", b2Initial, b1Initial)
}
b1M1, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
b2M1, err := server.EncryptToBeacon(2, message)
if err != nil {
t.Fatal(err)
}
if bytes.Equal(b1M1, b2M1) {
t.Fatal("expected different ciphertexts for different beacons")
}
}
func TestEncryptMultiple(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
b1 := newBeacon(t, serverPK)
message := bytes.Repeat([]byte{0x01}, 32)
registerBeacon(t, server, b1)
b1M1, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
b1M2, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
if bytes.Equal(b1M1, b1M2) {
t.Fatal("expected repeated encryption to produce different ciphertexts")
}
}
func TestDecryptMultiple(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
beacon := newBeacon(t, serverPK)
message := bytes.Repeat([]byte{0x01}, 32)
registerBeacon(t, server, beacon)
m1, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
m2, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
if bytes.Equal(m1, m2) {
t.Fatal("expected different ciphertexts")
}
plain1, err := beacon.DecryptServerMessage(m1)
if err != nil {
t.Fatal(err)
}
plain2, err := beacon.DecryptServerMessage(m2)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
t.Fatalf("decrypted messages mismatch: got %x and %x want %x", plain1, plain2, message)
}
}
func TestDecryptMultipleSigned(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
beacon := newBeacon(t, serverPK)
message := bytes.Repeat([]byte{0x01}, 32)
registerBeacon(t, server, beacon)
m1, err := server.EncryptToBeaconSigned(1, message)
if err != nil {
t.Fatal(err)
}
m2, err := server.EncryptToBeaconSigned(1, message)
if err != nil {
t.Fatal(err)
}
if bytes.Equal(m1, m2) {
t.Fatal("expected different signed ciphertexts")
}
plain1, err := beacon.DecryptServerMessageSigned(m1)
if err != nil {
t.Fatal(err)
}
plain2, err := beacon.DecryptServerMessageSigned(m2)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
t.Fatalf("decrypted signed messages mismatch: got %x and %x want %x", plain1, plain2, message)
}
}
func TestDecryptCatchUp(t *testing.T) {
server := newServer(t)
serverPK, err := server.IdentityPK()
if err != nil {
t.Fatal(err)
}
beacon := newBeacon(t, serverPK)
message := bytes.Repeat([]byte{0x01}, 32)
registerBeacon(t, server, beacon)
m1, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
m2, err := server.EncryptToBeacon(1, message)
if err != nil {
t.Fatal(err)
}
if bytes.Equal(m1, m2) {
t.Fatal("expected different ciphertexts")
}
plain2, err := beacon.DecryptServerMessage(m2)
if err != nil {
t.Fatal(err)
}
plain1, err := beacon.DecryptServerMessage(m1)
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(plain1, message) || !bytes.Equal(plain2, message) {
t.Fatalf("catch-up decrypt mismatch: got %x and %x want %x", plain1, plain2, message)
}
}