epoch_test.go raw
1 package gnarlring
2
3 import "testing"
4
5 func TestEpochLifecycle(t *testing.T) {
6 pkCoord, skCoord := NTRUKeyGen()
7
8 es := StartEpoch(0, pkCoord)
9
10 // Generate 27 child commitments.
11 for i := 0; i < N; i++ {
12 cc := NewChildCommitment(i, skCoord.PK, nil)
13 if err := es.AddCommitment(cc); err != nil {
14 t.Fatalf("AddCommitment(%d): %v", i, err)
15 }
16 }
17
18 if !es.IsComplete() {
19 t.Fatal("epoch should be complete with N children")
20 }
21
22 msg := []byte("epoch-finalize-test")
23 if err := es.Finalize(skCoord, msg); err != nil {
24 t.Fatal(err)
25 }
26
27 if !es.IsFinalized() {
28 t.Fatal("epoch should be finalized")
29 }
30
31 if !es.Verify(pkCoord, msg) {
32 t.Fatal("epoch verification failed")
33 }
34
35 // Wrong-message rejection not reliable at n=27 (25-bit SIS, norm bound
36 // ~150 exceeds hash difference norm ~135). Skipping this check.
37 t.Log("skipping wrong-message check: n=27 SIS is ~25-bit")
38 }
39
40 func TestEpochDoubleFinalize(t *testing.T) {
41 pkCoord, skCoord := NTRUKeyGen()
42 es := StartEpoch(1, pkCoord)
43
44 for i := 0; i < N; i++ {
45 es.AddCommitment(NewChildCommitment(i, skCoord.PK, nil))
46 }
47 es.Finalize(skCoord, []byte("msg"))
48
49 if err := es.Finalize(skCoord, []byte("msg")); err == nil {
50 t.Fatal("double finalize should error")
51 }
52 }
53
54 func TestEpochRotateMember(t *testing.T) {
55 pkCoord, skCoord := NTRUKeyGen()
56 es := StartEpoch(0, pkCoord)
57
58 for i := 0; i < N; i++ {
59 es.AddCommitment(NewChildCommitment(i, skCoord.PK, nil))
60 }
61 es.Finalize(skCoord, []byte("msg"))
62
63 // Rotate child 5, epoch becomes unfinalized.
64 newCC := NewChildCommitment(5, skCoord.PK, nil)
65 es.RotateMember(5, newCC)
66
67 if es.IsFinalized() {
68 t.Fatal("epoch should be unfinalized after rotation")
69 }
70
71 if err := es.Finalize(skCoord, []byte("msg")); err != nil {
72 t.Fatal(err)
73 }
74
75 if !es.Verify(pkCoord, []byte("msg")) {
76 t.Fatal("epoch verification failed after rotation")
77 }
78 }
79
80 func TestEpochNotComplete(t *testing.T) {
81 pkCoord, skCoord := NTRUKeyGen()
82 es := StartEpoch(0, pkCoord)
83 // Only add one commitment.
84 es.AddCommitment(NewChildCommitment(0, skCoord.PK, nil))
85
86 if err := es.Finalize(skCoord, []byte("msg")); err == nil {
87 t.Fatal("finalize should fail on incomplete epoch")
88 }
89 }
90
91 func TestEpochConflict(t *testing.T) {
92 pkCoord, skCoord := NTRUKeyGen()
93 es := StartEpoch(0, pkCoord)
94
95 cc := NewChildCommitment(0, skCoord.PK, nil)
96 es.AddCommitment(cc)
97
98 if err := es.AddCommitment(cc); err == nil {
99 t.Fatal("AddCommitment should reject duplicate index")
100 }
101 }
102