Skip to content

Commit c1b506b

Browse files
committed
more commnets and test
Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent 6b940ee commit c1b506b

File tree

4 files changed

+132
-15
lines changed

4 files changed

+132
-15
lines changed

token/core/zkatdlog/nogh/v1/crypto/common/array.go

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Copyright IBM Corp. All Rights Reserved.
44
SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
// Package common provides utility helpers used by the zkatdlog no-GH
8+
// crypto implementation (serialization and hashing helpers for math.G1 elements).
79
package common
810

911
import (
@@ -14,28 +16,46 @@ import (
1416
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/crypto"
1517
)
1618

17-
// Separator is used to delimit to end an array of bytes.
18-
// The bytes are the bytes of hex-encoded string.
19+
// Separator is used to delimit the end of an array of bytes.
20+
// The bytes are the bytes of a hex-encoded string.
1921
const Separator = "||"
2022

21-
// G1Array is an array of G1 elements
23+
// G1Array is an array of G1 elements.
2224
type G1Array []*math.G1
2325

24-
// Bytes serialize an array of G1 elements
25-
func (a G1Array) Bytes() ([]byte, error) {
26-
raw := make([][]byte, len([]*math.G1(a)))
27-
for i, e := range []*math.G1(a) {
26+
// Bytes returns the serialization of the G1Array as a byte slice.
27+
// It returns an error if any element cannot be marshaled.
28+
func (a *G1Array) Bytes() ([]byte, error) {
29+
raw := make([][]byte, len([]*math.G1(*a)))
30+
for i, e := range []*math.G1(*a) {
31+
if e == nil {
32+
return nil, errors.Errorf("failed to marshal array of G1")
33+
}
34+
raw[i] = e.Bytes()
35+
}
36+
return crypto.AppendFixed32([]byte{}, raw), nil
37+
}
38+
39+
// BytesTo writes the serialization of the G1Array into the provided buffer b
40+
// and returns the extended slice. The provided buffer b is cleared before use.
41+
// It returns an error if any element cannot be marshaled.
42+
func (a *G1Array) BytesTo(b []byte) ([]byte, error) {
43+
raw := make([][]byte, len([]*math.G1(*a)))
44+
for i, e := range []*math.G1(*a) {
2845
if e == nil {
2946
return nil, errors.Errorf("failed to marshal array of G1")
3047
}
3148
st := hex.EncodeToString(e.Bytes())
3249
raw[i] = []byte(st)
3350
}
34-
clear(b)
51+
// clear the provided buffer and reuse its capacity
52+
if len(b) != 0 {
53+
b = b[:0]
54+
}
3555
return crypto.AppendFixed32(b, raw), nil
3656
}
3757

38-
// GetG1Array takes a series of G1 elements and returns the corresponding array
58+
// GetG1Array takes multiple slices of *math.G1 and concatenates them into a single *G1Array.
3959
func GetG1Array(elements ...[]*math.G1) G1Array {
4060
// compute length
4161
length := 0
@@ -49,6 +69,8 @@ func GetG1Array(elements ...[]*math.G1) G1Array {
4969
return s
5070
}
5171

72+
// HashG1Array computes and returns the digest of the provided G1 elements
73+
// using the supplied hash.Hash. The hash is reset before use.
5274
func HashG1Array(h hash.Hash, elements ...*math.G1) []byte {
5375
h.Reset()
5476

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package common
8+
9+
import (
10+
"crypto/sha256"
11+
"testing"
12+
13+
math "github.com/IBM/mathlib"
14+
"github.com/stretchr/testify/require"
15+
16+
"github.com/hyperledger-labs/fabric-token-sdk/token/core/common/crypto"
17+
)
18+
19+
func randomG1(t *testing.T, c *math.Curve) *math.G1 {
20+
randReader, err := c.Rand()
21+
require.NoError(t, err)
22+
23+
zr := c.NewRandomZr(randReader)
24+
g := c.NewG1()
25+
g.Add(c.GenG1.Mul(zr))
26+
return g
27+
}
28+
29+
func TestGetG1ArrayAndBytes(t *testing.T) {
30+
require.Greater(t, len(math.Curves), 0)
31+
curve := math.Curves[0]
32+
33+
g1 := randomG1(t, curve)
34+
g2 := randomG1(t, curve)
35+
36+
a := GetG1Array([]*math.G1{g1}, []*math.G1{g2})
37+
b, err := a.Bytes()
38+
require.NoError(t, err)
39+
40+
raw := [][]byte{g1.Bytes(), g2.Bytes()}
41+
expected := crypto.AppendFixed32([]byte{}, raw)
42+
require.Equal(t, expected, b)
43+
}
44+
45+
func TestBytesToAndReuseBuffer(t *testing.T) {
46+
require.Greater(t, len(math.Curves), 0)
47+
curve := math.Curves[0]
48+
49+
g1 := randomG1(t, curve)
50+
g2 := randomG1(t, curve)
51+
a := GetG1Array([]*math.G1{g1, g2})
52+
53+
// produce canonical bytes
54+
canonical, err := a.Bytes()
55+
require.NoError(t, err)
56+
57+
// provide a non-empty buffer (should be cleared by BytesTo)
58+
buf := []byte("prefix-data")
59+
out, err := a.BytesTo(buf)
60+
require.NoError(t, err)
61+
require.Equal(t, canonical, out)
62+
}
63+
64+
func TestBytesWithNilElementErrors(t *testing.T) {
65+
require.Greater(t, len(math.Curves), 0)
66+
curve := math.Curves[0]
67+
68+
g1 := randomG1(t, curve)
69+
a := GetG1Array([]*math.G1{g1, nil})
70+
_, err := a.Bytes()
71+
require.Error(t, err)
72+
73+
_, err = a.BytesTo(nil)
74+
require.Error(t, err)
75+
}
76+
77+
func TestHashG1Array(t *testing.T) {
78+
require.Greater(t, len(math.Curves), 0)
79+
curve := math.Curves[0]
80+
81+
g1 := randomG1(t, curve)
82+
g2 := randomG1(t, curve)
83+
84+
h := sha256.New()
85+
hRes := HashG1Array(h, g1, g2)
86+
87+
// compute expected by hand
88+
h2 := sha256.New()
89+
h2.Reset()
90+
h2.Write(g1.Bytes())
91+
h2.Write(g2.Bytes())
92+
exp := h2.Sum(nil)
93+
require.Equal(t, exp, hRes)
94+
}
95+

token/core/zkatdlog/nogh/v1/crypto/rp/bulletproof_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ type bfSetup struct {
3333
curve *math.Curve
3434
}
3535

36-
func NewBfSetup(curveID math.CurveID) (*bfSetup, error) {
36+
func newBfSetup(curveID math.CurveID) (*bfSetup, error) {
3737
curve := math.Curves[curveID]
3838
l := uint64(64)
3939
nr := 63 - uint64(bits.LeadingZeros64(l))
@@ -73,7 +73,7 @@ func NewBfSetup(curveID math.CurveID) (*bfSetup, error) {
7373
}
7474

7575
func TestBFProofVerify(t *testing.T) {
76-
setup, err := NewBfSetup(math.BLS12_381_BBS_GURVY)
76+
setup, err := newBfSetup(math.BLS12_381_BBS_GURVY)
7777
require.NoError(t, err)
7878

7979
prover := rp.NewRangeProver(
@@ -115,7 +115,7 @@ func BenchmarkBFProver(b *testing.B) {
115115
defer pp.Stop()
116116
envs := make([]*bfSetup, 0, 128)
117117
for i := 0; i < 128; i++ {
118-
setup, err := NewBfSetup(math.BLS12_381_BBS_GURVY)
118+
setup, err := newBfSetup(math.BLS12_381_BBS_GURVY)
119119
require.NoError(b, err)
120120
envs = append(envs, setup)
121121
}

token/core/zkatdlog/nogh/v1/crypto/rp/ipa_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ type ipaSetup struct {
3030
nr uint64
3131
}
3232

33-
func NewIpaSetup(curveID math.CurveID) (*ipaSetup, error) {
33+
func newIpaSetup(curveID math.CurveID) (*ipaSetup, error) {
3434
curve := math.Curves[curveID]
3535
l := uint64(64)
3636
nr := 63 - uint64(bits.LeadingZeros64(l))
@@ -66,7 +66,7 @@ func NewIpaSetup(curveID math.CurveID) (*ipaSetup, error) {
6666
}
6767

6868
func TestIPAProofVerify(t *testing.T) {
69-
setup, err := NewIpaSetup(math.BLS12_381_BBS_GURVY)
69+
setup, err := newIpaSetup(math.BLS12_381_BBS_GURVY)
7070
require.NoError(t, err)
7171

7272
prover := rp.NewIPAProver(
@@ -104,7 +104,7 @@ func BenchmarkIPAProver(b *testing.B) {
104104
defer pp.Stop()
105105
envs := make([]*ipaSetup, 0, 128)
106106
for i := 0; i < 128; i++ {
107-
setup, err := NewIpaSetup(math.BLS12_381_BBS_GURVY)
107+
setup, err := newIpaSetup(math.BLS12_381_BBS_GURVY)
108108
require.NoError(b, err)
109109
envs = append(envs, setup)
110110
}

0 commit comments

Comments
 (0)