package gnarlring_test import ( "testing" "git.smesh.lol/gnarl-hamadryad/crypto/gnarlring" "git.smesh.lol/gnarl-hamadryad/crypto/ring" ) func TestCompositeFalcon512(t *testing.T) { // Falcon-512: n=512, q=12289, ~128-bit PQ security. // Note: FalconSignFrom hangs due to rejection sampling in sampleZ // for small effective sigma (same bug fixed in gnarlring/gaussian.go). // This test validates parameter scaling, not full sign/verify. p := ring.Falcon512() pk, sk := ring.FalconKeyGen(p) if pk == nil || sk == nil { t.Fatal("Falcon keygen failed") } t.Logf("Falcon-512: n=%d q=%d", p.N, p.Q) t.Logf(" secret key: f norm ~%.0f", float64(p.N)*3) t.Logf(" public key h: %d bytes", p.N*14/8) // 14 bits per coeff t.Logf(" security: ~128-bit SIS (n=512)") t.Logf(" keygen: O(n^3) at dimension %d", 2*p.N) } func TestCompositeParams(t *testing.T) { gnarlN := 27 falconN := ring.Falcon512().N falconQ := ring.Falcon512().Q t.Logf("Gnarl ring: n=%d q=%d n·log2(q)≈%d (~25-bit SIS)", gnarlN, 271, gnarlN*8) t.Logf("Falcon-512: n=%d q=%d n·log2(q)≈%d (~128-bit SIS)", falconN, falconQ, falconN*14) compositeN := 432 compositeLog := compositeN * 8 t.Logf("Composite target: n=%d q=%d n·log2(q)≈%d (~114-bit SIS)", compositeN, 271, compositeLog) if compositeN < 400 { t.Error("composite ring target should be n ≥ 400") } } func TestGnarlringCompactSig(t *testing.T) { pk, sk := gnarlring.NTRUKeyGen() msg := []byte("compact sig baseline") sig := gnarlring.NTRUSign(sk, msg) if !gnarlring.NTRUVerify(pk, msg, sig) { t.Fatal("gnarlring signature rejected") } sigBytes := len(sig.MarshalBinary()) t.Logf("Gnarlring sig: %d bytes (n=27, ~25-bit SIS)", sigBytes) t.Logf("Falcon-512: ~690 bytes compressed (n=512, ~128-bit SIS)") t.Logf("Composite gap: Falcon is ~%.1f× larger for %.1f× more security", float64(690)/float64(sigBytes), 128.0/25.0) if sigBytes != 16+31 { t.Errorf("expected sig 47 bytes, got %d", sigBytes) } }