From d676555593b292ce0a0f88c6f37fdda6e117a18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Sza=C5=82achowski?= Date: Fri, 12 Jun 2026 09:58:02 +0200 Subject: [PATCH 1/5] MasterSecret.UnmarshalJSON fix --- go/tdh2/tdh2easy/tdh2easy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/tdh2/tdh2easy/tdh2easy.go b/go/tdh2/tdh2easy/tdh2easy.go index 132b800..1c38c33 100644 --- a/go/tdh2/tdh2easy/tdh2easy.go +++ b/go/tdh2/tdh2easy/tdh2easy.go @@ -117,7 +117,7 @@ func (m *MasterSecret) Unmarshal(data []byte) error { return m.m.Unmarshal(data) } -func (m MasterSecret) UnmarshalJSON(data []byte) error { +func (m *MasterSecret) UnmarshalJSON(data []byte) error { return m.Unmarshal(data) } From 39b696084c82541bbc8ab388f82db7d97b18e680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Sza=C5=82achowski?= Date: Fri, 12 Jun 2026 10:47:00 +0200 Subject: [PATCH 2/5] curvePoint.Equal and UnmarshalBinary small fixes --- go/tdh2/lib/group/nist/curve.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/go/tdh2/lib/group/nist/curve.go b/go/tdh2/lib/group/nist/curve.go index 9da4915..1e5a21d 100644 --- a/go/tdh2/lib/group/nist/curve.go +++ b/go/tdh2/lib/group/nist/curve.go @@ -33,17 +33,18 @@ func (p *curvePoint) String() string { } func (p *curvePoint) Equal(p2 group.Point) bool { - cp2 := p2.(*curvePoint) + cp2 := p2.(*curvePoint) //nolint:errcheck // Design pattern to emulate generics // Make sure both coordinates are normalized. // Apparently Go's elliptic curve code doesn't always ensure this. + // Use temporary big.Ints to avoid mutating the operands. M := p.c.p.P - p.x.Mod(p.x, M) - p.y.Mod(p.y, M) - cp2.x.Mod(cp2.x, M) - cp2.y.Mod(cp2.y, M) + x1 := new(big.Int).Mod(p.x, M) + y1 := new(big.Int).Mod(p.y, M) + x2 := new(big.Int).Mod(cp2.x, M) + y2 := new(big.Int).Mod(cp2.y, M) - return p.x.Cmp(cp2.x) == 0 && p.y.Cmp(cp2.y) == 0 + return x1.Cmp(x2) == 0 && y1.Cmp(y2) == 0 } func (p *curvePoint) Null() group.Point { @@ -134,8 +135,9 @@ func (p *curvePoint) UnmarshalBinary(buf []byte) error { if p.x == nil || !p.Valid() { return errors.New("invalid elliptic curve point") } + } else if buf[0] != 0x04 { + return errors.New("invalid elliptic curve point: non-canonical identity encoding") } else { - // All bytes are 0, so we initialize x and y p.x = big.NewInt(0) p.y = big.NewInt(0) } From adbbf684aba4c08a5d8b96a9e9a8dd5e9e600e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Sza=C5=82achowski?= Date: Tue, 23 Jun 2026 15:42:34 +0200 Subject: [PATCH 3/5] drop nolint --- go/tdh2/lib/group/nist/curve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/tdh2/lib/group/nist/curve.go b/go/tdh2/lib/group/nist/curve.go index 1e5a21d..1966dd5 100644 --- a/go/tdh2/lib/group/nist/curve.go +++ b/go/tdh2/lib/group/nist/curve.go @@ -33,7 +33,7 @@ func (p *curvePoint) String() string { } func (p *curvePoint) Equal(p2 group.Point) bool { - cp2 := p2.(*curvePoint) //nolint:errcheck // Design pattern to emulate generics + cp2 := p2.(*curvePoint) // Make sure both coordinates are normalized. // Apparently Go's elliptic curve code doesn't always ensure this. From 01391df58d3a3b3823b9af801d8b49788e0c8f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Sza=C5=82achowski?= Date: Fri, 26 Jun 2026 11:07:13 +0200 Subject: [PATCH 4/5] comments --- go/tdh2/lib/group/nist/curve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/tdh2/lib/group/nist/curve.go b/go/tdh2/lib/group/nist/curve.go index 1966dd5..f90d2f8 100644 --- a/go/tdh2/lib/group/nist/curve.go +++ b/go/tdh2/lib/group/nist/curve.go @@ -37,7 +37,6 @@ func (p *curvePoint) Equal(p2 group.Point) bool { // Make sure both coordinates are normalized. // Apparently Go's elliptic curve code doesn't always ensure this. - // Use temporary big.Ints to avoid mutating the operands. M := p.c.p.P x1 := new(big.Int).Mod(p.x, M) y1 := new(big.Int).Mod(p.y, M) @@ -138,6 +137,7 @@ func (p *curvePoint) UnmarshalBinary(buf []byte) error { } else if buf[0] != 0x04 { return errors.New("invalid elliptic curve point: non-canonical identity encoding") } else { + // All bytes are 0, so we initialize x and y p.x = big.NewInt(0) p.y = big.NewInt(0) } From 68b613845ec5b623b1c18fd850ead60e5f56a9e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Sza=C5=82achowski?= Date: Fri, 26 Jun 2026 12:02:43 +0200 Subject: [PATCH 5/5] marshal json test --- go/tdh2/tdh2easy/tdh2easy_test.go | 92 +++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/go/tdh2/tdh2easy/tdh2easy_test.go b/go/tdh2/tdh2easy/tdh2easy_test.go index 07121ba..023c09c 100644 --- a/go/tdh2/tdh2easy/tdh2easy_test.go +++ b/go/tdh2/tdh2easy/tdh2easy_test.go @@ -58,6 +58,27 @@ func TestPrivateShareMarshal(t *testing.T) { } } +func TestPrivateShareMarshalJSON(t *testing.T) { + _, _, want, err := GenerateKeys(2, 3) + if err != nil { + t.Fatalf("GenerateKeys: %v", err) + } + b, err := want[0].MarshalJSON() + if err != nil { + t.Fatalf("MarshalJSON: %v", err) + } + var got PrivateShare + if err := got.UnmarshalJSON(b); err != nil { + t.Fatalf("UnmarshalJSON: %v", err) + } + if !reflect.DeepEqual(got.p, want[0].p) { + t.Errorf("got=%v want=%v", got, want[0]) + } + if err := got.UnmarshalJSON([]byte("broken")); err == nil { + t.Errorf("Unmarshal did not fail") + } +} + func TestDecryptionShareMarshal(t *testing.T) { _, pk, sh, err := GenerateKeys(2, 3) if err != nil { @@ -87,6 +108,35 @@ func TestDecryptionShareMarshal(t *testing.T) { } } +func TestDecryptionShareMarshalJSON(t *testing.T) { + _, pk, sh, err := GenerateKeys(2, 3) + if err != nil { + t.Fatalf("GenerateKeys: %v", err) + } + c, err := Encrypt(pk, []byte("msg")) + if err != nil { + t.Fatalf("Encrypt: %v", err) + } + want, err := Decrypt(c, sh[0]) + if err != nil { + t.Fatalf("Decrypt: %v", err) + } + b, err := want.MarshalJSON() + if err != nil { + t.Fatalf("MarshalJSON: %v", err) + } + var got DecryptionShare + if err := got.UnmarshalJSON(b); err != nil { + t.Fatalf("UnmarshalJSON: %v", err) + } + if !reflect.DeepEqual(got.d, want.d) { + t.Errorf("got=%v want=%v", got, want) + } + if err := got.UnmarshalJSON([]byte("broken")); err == nil { + t.Errorf("UnmarshalJSON did not fail") + } +} + func TestPublicKeyMarshal(t *testing.T) { _, want, _, err := GenerateKeys(2, 3) if err != nil { @@ -108,6 +158,27 @@ func TestPublicKeyMarshal(t *testing.T) { } } +func TestPublicKeyMarshalJSON(t *testing.T) { + _, want, _, err := GenerateKeys(2, 3) + if err != nil { + t.Fatalf("GenerateKeys: %v", err) + } + b, err := want.MarshalJSON() + if err != nil { + t.Fatalf("MarshalJSON: %v", err) + } + var got PublicKey + if err := got.UnmarshalJSON(b); err != nil { + t.Fatalf("UnmarshalJSON: %v", err) + } + if !got.p.Equal(want.p) { + t.Errorf("got=%v want=%v", got, want) + } + if err := got.UnmarshalJSON([]byte("broken")); err == nil { + t.Errorf("UnmarshalJSON did not fail") + } +} + func TestMasterSecretMarshal(t *testing.T) { want, _, _, err := GenerateKeys(2, 3) if err != nil { @@ -129,6 +200,27 @@ func TestMasterSecretMarshal(t *testing.T) { } } +func TestMasterSecretMarshalJSON(t *testing.T) { + want, _, _, err := GenerateKeys(2, 3) + if err != nil { + t.Fatalf("GenerateKeys: %v", err) + } + b, err := want.MarshalJSON() + if err != nil { + t.Fatalf("MarshalJSON: %v", err) + } + var got MasterSecret + if err := got.UnmarshalJSON(b); err != nil { + t.Fatalf("UnmarshalJSON: %v", err) + } + if !reflect.DeepEqual(got.m, want.m) { + t.Errorf("got=%v want=%v", got, want) + } + if err := got.UnmarshalJSON([]byte("broken")); err == nil { + t.Errorf("UnmarshalJSON did not fail") + } +} + func TestCiphertextDecrypt(t *testing.T) { _, pk, share, err := GenerateKeys(1, 1) if err != nil {