package ring import ( "testing" ) // TestGPVSignVerify verifies basic sign/verify round-trip. func TestGPVSignVerify(t *testing.T) { gp := SmallGPVParams() pk, sk := GPVKeyGen(gp) msg := []byte("hello lattice world") sig := GPVSign(sk, msg) if !GPVVerify(pk, msg, sig) { t.Fatal("valid signature rejected") } } // TestGPVWrongMessage verifies signature doesn't verify for wrong message. func TestGPVWrongMessage(t *testing.T) { gp := SmallGPVParams() pk, sk := GPVKeyGen(gp) msg := []byte("correct message") sig := GPVSign(sk, msg) if GPVVerify(pk, []byte("wrong message"), sig) { t.Fatal("signature verified for wrong message") } } // TestGPVWrongKey verifies signature doesn't verify with wrong key. func TestGPVWrongKey(t *testing.T) { gp := SmallGPVParams() _, sk1 := GPVKeyGen(gp) pk2, _ := GPVKeyGen(gp) msg := []byte("test message") sig := GPVSign(sk1, msg) if GPVVerify(pk2, msg, sig) { t.Fatal("signature verified with wrong public key") } } // TestGPVMultipleMessages verifies multiple sign/verify cycles. func TestGPVMultipleMessages(t *testing.T) { gp := SmallGPVParams() pk, sk := GPVKeyGen(gp) messages := []string{ "", "a", "hello", "the quick brown fox jumps over the lazy dog", "lattice-based cryptography is the future", } for _, msg := range messages { sig := GPVSign(sk, []byte(msg)) if !GPVVerify(pk, []byte(msg), sig) { t.Fatalf("verification failed for message %q", msg) } } } // TestGPVSignatureShortness verifies that signatures are actually short. func TestGPVSignatureShortness(t *testing.T) { gp := SmallGPVParams() _, sk := GPVKeyGen(gp) msg := []byte("test shortness") sig := GPVSign(sk, msg) zNorm := Norm(sig.E1) cNorm := Norm(sig.E2) t.Logf("||z||_∞ = %d, ||c||_∞ = %d, bound = %d", zNorm, cNorm, uint32(gp.Sigma*1.5)) // z should be within the bound. if zNorm > uint32(gp.Sigma*1.5) { t.Errorf("z norm %d exceeds bound %d", zNorm, uint32(gp.Sigma*1.5)) } // c should have small coefficients (±1 or 0). if cNorm > 1 { t.Errorf("c norm %d should be ≤ 1", cNorm) } } // TestGPVDifferentSignatures verifies that signing the same message // produces different signatures (due to randomness). func TestGPVDifferentSignatures(t *testing.T) { gp := SmallGPVParams() pk, sk := GPVKeyGen(gp) msg := []byte("determinism check") sig1 := GPVSign(sk, msg) sig2 := GPVSign(sk, msg) // Both should verify. if !GPVVerify(pk, msg, sig1) || !GPVVerify(pk, msg, sig2) { t.Fatal("valid signatures rejected") } // But should be different (probabilistic signatures). if Equal(sig1.E1, sig2.E1) && Equal(sig1.E2, sig2.E2) { t.Fatal("two signatures are identical — randomness failure") } } // TestGPVFalcon512Params verifies GPV works with Falcon-512 parameters. func TestGPVFalcon512Params(t *testing.T) { gp := DefaultGPVParams() pk, sk := GPVKeyGen(gp) msg := []byte("Falcon-512 parameter test") sig := GPVSign(sk, msg) if !GPVVerify(pk, msg, sig) { t.Fatal("Falcon-512 signature rejected") } zNorm := Norm(sig.E1) t.Logf("Falcon-512: ||z||_∞ = %d, σ = %.1f, bound = %d", zNorm, gp.Sigma, uint32(gp.Sigma*1.5)) } func BenchmarkGPVKeyGen(b *testing.B) { gp := SmallGPVParams() for range b.N { GPVKeyGen(gp) } } func BenchmarkGPVSign(b *testing.B) { gp := SmallGPVParams() _, sk := GPVKeyGen(gp) msg := []byte("benchmark message") b.ResetTimer() for range b.N { GPVSign(sk, msg) } } func BenchmarkGPVVerify(b *testing.B) { gp := SmallGPVParams() pk, sk := GPVKeyGen(gp) msg := []byte("benchmark message") sig := GPVSign(sk, msg) b.ResetTimer() for range b.N { GPVVerify(pk, msg, sig) } }