package crypto import ( "encoding/hex" "strings" "testing" ) func TestPeerIDIsHex(t *testing.T) { id := newTestIdentity(t) peerID := string(id.PeerID()) if len(peerID) != 64 { t.Fatalf("PeerID length = %d, want 64", len(peerID)) } if strings.ToLower(peerID) != peerID { t.Fatal("PeerID is not lowercase") } if _, err := hex.DecodeString(peerID); err != nil { t.Fatalf("PeerID is not valid hex: %v", err) } } func TestSignVerifyHex(t *testing.T) { id := newTestIdentity(t) msg := []byte("test message") sig := id.Sign(msg) if err := Verify(string(id.PeerID()), msg, sig); err != nil { t.Fatalf("Verify failed: %v", err) } } func TestSignalingBoxRoundTrip(t *testing.T) { alice := newTestIdentity(t) bob := newTestIdentity(t) plaintext := []byte(`{"kind":"offer","sdp":"v=0..."}`) sealed := SignalingBox(plaintext, bob.CurvePublicKey(), alice.CurvePrivateKey()) got, err := SignalingOpen(sealed, alice.CurvePublicKey(), bob.CurvePrivateKey()) if err != nil { t.Fatalf("SignalingOpen failed: %v", err) } if string(got) != string(plaintext) { t.Fatalf("got %q, want %q", got, plaintext) } } func TestSignalingBoxTamperedFails(t *testing.T) { alice := newTestIdentity(t) bob := newTestIdentity(t) sealed := SignalingBox([]byte("hello"), bob.CurvePublicKey(), alice.CurvePrivateKey()) // wrong sender public key carol := newTestIdentity(t) if _, err := SignalingOpen(sealed, carol.CurvePublicKey(), bob.CurvePrivateKey()); err == nil { t.Fatal("expected error with wrong sender key, got nil") } } func TestExportImportRoundtrip(t *testing.T) { id := newTestIdentity(t) passphrase := "correct horse battery staple" blob, err := ExportIdentity(id, passphrase) if err != nil { t.Fatalf("ExportIdentity: %v", err) } // Exported blob must contain the public peer ID in plaintext. if !strings.Contains(string(blob), string(id.PeerID())) { t.Fatal("exported blob does not contain peer ID") } imported, err := ImportIdentity(blob, passphrase) if err != nil { t.Fatalf("ImportIdentity: %v", err) } if imported.PeerID() != id.PeerID() { t.Fatalf("peer ID mismatch: got %s, want %s", imported.PeerID(), id.PeerID()) } if imported.Alias != id.Alias { t.Fatalf("alias mismatch: got %q, want %q", imported.Alias, id.Alias) } } func TestImportWrongPassphraseFails(t *testing.T) { id := newTestIdentity(t) blob, err := ExportIdentity(id, "correct") if err != nil { t.Fatalf("ExportIdentity: %v", err) } if _, err := ImportIdentity(blob, "wrong"); err == nil { t.Fatal("expected error with wrong passphrase, got nil") } } // newTestIdentity creates a fresh in-memory identity for testing. func newTestIdentity(t *testing.T) *Identity { t.Helper() id, err := LoadOrCreate(t.TempDir(), "test") if err != nil { t.Fatalf("LoadOrCreate: %v", err) } return id }