Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion token/core/zkatdlog/nogh/v1/crypto/common/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,26 @@ import (

//go:generate counterfeiter -o ../mock/signing_identity.go -fake-name SigningIdentity . SigningIdentity

// SigningIdentity defines the interface for a signing identity.
type SigningIdentity interface {
driver.SigningIdentity
}

// WrappedSigningIdentity wraps an identity and its corresponding signer.
type WrappedSigningIdentity struct {
// Identity represents the public identity bytes.
Identity driver.Identity
Signer driver.Signer
// Signer is the cryptographic signer for this identity.
Signer driver.Signer
}

// Serialize returns the byte representation of the identity.
func (w *WrappedSigningIdentity) Serialize() ([]byte, error) {
return w.Identity, nil
}

// Sign signs the provided raw bytes using the underlying signer.
// It returns an error if the signer is not initialized.
func (w *WrappedSigningIdentity) Sign(raw []byte) ([]byte, error) {
if w.Signer == nil {
return nil, errors.New("please initialize signing identity in WrappedSigningIdentity")
Expand Down
48 changes: 48 additions & 0 deletions token/core/zkatdlog/nogh/v1/crypto/common/identity_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package common

import (
"testing"

"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
"github.com/hyperledger-labs/fabric-token-sdk/token/driver/mock"
"github.com/stretchr/testify/require"
)

func TestWrappedSigningIdentity(t *testing.T) {
id := driver.Identity("alice")
signer := &mock.Signer{}
w := &WrappedSigningIdentity{
Identity: id,
Signer: signer,
}

// Test Serialize
serialized, err := w.Serialize()
require.NoError(t, err)
require.Equal(t, []byte(id), serialized)

// Test Sign
raw := []byte("hello")
sig := []byte("signature")
signer.SignReturns(sig, nil)
signed, err := w.Sign(raw)
require.NoError(t, err)
require.Equal(t, sig, signed)
require.Equal(t, 1, signer.SignCallCount())
require.Equal(t, raw, signer.SignArgsForCall(0))

// Test Sign with nil signer
wNil := &WrappedSigningIdentity{
Identity: id,
Signer: nil,
}
_, err = wNil.Sign(raw)
require.Error(t, err)
require.Contains(t, err.Error(), "please initialize signing identity in WrappedSigningIdentity")
}
24 changes: 24 additions & 0 deletions token/core/zkatdlog/nogh/v1/crypto/math/curves_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ func TestZeroOneTwoAndCached(t *testing.T) {
require.True(t, ok)
rz := NewCachedZrFromInt(c, 3)
zrEquals(t, rz, v)

// test cache miss (curve id)
delete(valueCache, c.ID())
missed := NewCachedZrFromInt(c, 3)
zrEquals(t, missed, c.NewZrFromUint64(3))

// restore and test cache miss (index)
restoreCaches(vSnapshot, pSnapshot, sSnapshot)
missed = NewCachedZrFromInt(c, 999)
zrEquals(t, missed, c.NewZrFromUint64(999))
}

func TestPowerOfTwoAndSum(t *testing.T) {
Expand All @@ -53,6 +63,16 @@ func TestPowerOfTwoAndSum(t *testing.T) {
require.True(t, ok)
zrEquals(t, p0, PowerOfTwo(c, 0))

// test cache miss for PowerOfTwo (curve id)
delete(powerCache, c.ID())
missedP := PowerOfTwo(c, 10)
zrEquals(t, missedP, c.NewZrFromUint64(2).PowMod(c.NewZrFromUint64(10)))

// restore and test cache miss for PowerOfTwo (index)
restoreCaches(vSnapshot, pSnapshot, sSnapshot)
missedP = PowerOfTwo(c, 999)
zrEquals(t, missedP, c.NewZrFromUint64(2).PowMod(c.NewZrFromUint64(999)))

// cached sum
sc := sumOfPowerCache[c.ID()]
require.NotNil(t, sc)
Expand All @@ -79,6 +99,10 @@ func TestPowerOfTwoAndSum(t *testing.T) {
} else {
require.Panics(t, func() { SumOfPowersOfTwo(c, n) })
}

// test cache miss for SumOfPowersOfTwo (curve id)
delete(sumOfPowerCache, c.ID())
require.Panics(t, func() { SumOfPowersOfTwo(c, 1) })
}

// helper: compare Zr values using Equals
Expand Down
12 changes: 12 additions & 0 deletions token/core/zkatdlog/nogh/v1/crypto/math/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ import (
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
)

// BaseElement is an interface for elements that belong to a mathematical curve.
type BaseElement interface {
// CurveID returns the identifier of the curve this element belongs to.
CurveID() mathlib.CurveID
}

// Element is an interface for curve elements that can also be checked for infinity.
type Element interface {
BaseElement
// IsInfinity returns true if the element is the point at infinity.
IsInfinity() bool
}

// CheckElements validates a slice of elements against a curve ID and an expected length.
// It returns an error if the length is incorrect or if any element is invalid.
func CheckElements[E Element](elements []E, curveID mathlib.CurveID, length uint64) error {
if uint64(len(elements)) != length {
return errors.Errorf("length of elements does not match length of curveID")
Expand All @@ -35,6 +41,8 @@ func CheckElements[E Element](elements []E, curveID mathlib.CurveID, length uint
return nil
}

// CheckZrElements validates a slice of base elements against a curve ID and an expected length.
// It returns an error if the length is incorrect or if any element is invalid.
func CheckZrElements[E BaseElement](elements []E, curveID mathlib.CurveID, length uint64) error {
if uint64(len(elements)) != length {
return errors.Errorf("length of elements does not match length of curveID")
Expand All @@ -48,6 +56,8 @@ func CheckZrElements[E BaseElement](elements []E, curveID mathlib.CurveID, lengt
return nil
}

// CheckElement validates a single element: it must not be nil, must belong to the specified curve,
// and must not be the point at infinity.
func CheckElement[E Element](element E, curveID mathlib.CurveID) (err error) {
defer func() {
if e := recover(); e != nil {
Expand All @@ -68,6 +78,8 @@ func CheckElement[E Element](element E, curveID mathlib.CurveID) (err error) {
return nil
}

// CheckBaseElement validates a single base element: it must not be nil and must belong
// to the specified curve.
func CheckBaseElement[E BaseElement](element E, curveID mathlib.CurveID) (err error) {
defer func() {
if e := recover(); e != nil {
Expand Down
83 changes: 80 additions & 3 deletions token/core/zkatdlog/nogh/v1/crypto/math/math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,90 @@ import (
"testing"

math "github.com/IBM/mathlib"
"github.com/test-go/testify/require"
"github.com/stretchr/testify/require"
)

func TestCheckElement(t *testing.T) {
var g1 *math.G1
require.Error(t, CheckElement(g1, 0))
err := CheckElement(g1, math.BN254)
require.Error(t, err)
require.Contains(t, err.Error(), "elememt is nil")

g1 = &math.G1{}
require.Error(t, CheckElement(g1, 0))
err = CheckElement(g1, math.BN254)
require.Error(t, err)
// mathlib G1{} might panic on CurveID() or IsInfinity() if not initialized
// The CheckElement has a recover block

curve := math.Curves[math.BN254]
g1 = curve.GenG1
err = CheckElement(g1, math.BN254)
require.NoError(t, err)

err = CheckElement(g1, math.BLS12_381_BBS)
require.Error(t, err)
require.Contains(t, err.Error(), "element curve must equal curve ID")

inf := curve.NewG1()
err = CheckElement(inf, math.BN254)
require.Error(t, err)
require.Contains(t, err.Error(), "element is infinity")
}

func TestCheckBaseElement(t *testing.T) {
var zr *math.Zr
err := CheckBaseElement(zr, math.BN254)
require.Error(t, err)
require.Contains(t, err.Error(), "elememt is nil")

curve := math.Curves[math.BN254]
zr = curve.NewZrFromUint64(1)
err = CheckBaseElement(zr, math.BN254)
require.NoError(t, err)

err = CheckBaseElement(zr, math.BLS12_381_BBS)
require.Error(t, err)
require.Contains(t, err.Error(), "element curve must equal curve ID")
}

func TestCheckElements(t *testing.T) {
curve := math.Curves[math.BN254]
g1 := curve.GenG1
g2 := curve.GenG1

err := CheckElements([]*math.G1{g1, g2}, math.BN254, 2)
require.NoError(t, err)

err = CheckElements([]*math.G1{g1, g2}, math.BN254, 3)
require.Error(t, err)
require.Contains(t, err.Error(), "length of elements does not match length of curveID")

err = CheckElements([]*math.G1{g1, nil}, math.BN254, 2)
require.Error(t, err)
require.Contains(t, err.Error(), "elememt is nil")
}

func TestCheckZrElements(t *testing.T) {
curve := math.Curves[math.BN254]
zr1 := curve.NewZrFromUint64(1)
zr2 := curve.NewZrFromUint64(2)

err := CheckZrElements([]*math.Zr{zr1, zr2}, math.BN254, 2)
require.NoError(t, err)

err = CheckZrElements([]*math.Zr{zr1, zr2}, math.BN254, 1)
require.Error(t, err)
require.Contains(t, err.Error(), "length of elements does not match length of curveID")

err = CheckZrElements([]*math.Zr{zr1, nil}, math.BN254, 2)
require.Error(t, err)
require.Contains(t, err.Error(), "elememt is nil")
}

func TestIsNilInterface(t *testing.T) {
require.True(t, isNilInterface(nil))
var g1 *math.G1
require.True(t, isNilInterface(g1))
require.False(t, isNilInterface(math.Curves[math.BN254].GenG1))
require.False(t, isNilInterface(10))
}
Loading
Loading