mirror of
https://github.com/luxfi/crypto.git
synced 2026-10-30 16:59:13 +00:00
315 lines
8.7 KiB
Go
315 lines
8.7 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package localsigner
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/luxfi/crypto/bls"
|
|
)
|
|
|
|
func AggregateAndVerify(publicKeys []*bls.PublicKey, signatures []*bls.Signature, message []byte) (bool, error) {
|
|
aggSig, err := bls.AggregateSignatures(signatures)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
aggPK, err := bls.AggregatePublicKeys(publicKeys)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return bls.Verify(aggPK, aggSig, message), nil
|
|
}
|
|
|
|
func NewSigner(require *require.Assertions) *LocalSigner {
|
|
sk, err := New()
|
|
require.NoError(err)
|
|
return sk
|
|
}
|
|
|
|
func mapSlice[T any, U any](arr []T, f func(T) U) []U {
|
|
result := make([]U, len(arr))
|
|
for i, val := range arr {
|
|
result[i] = f(val)
|
|
}
|
|
return result
|
|
}
|
|
|
|
func TestVerifyValidSignature(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyValidSignature local signer")
|
|
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.Verify(signer.PublicKey(), sig, msg)
|
|
require.True(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongMessageSignature(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyWrongMessageSignature local signer")
|
|
wrongMsg := []byte("TestVerifyWrongMessageSignature local signer with wrong message")
|
|
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.Verify(signer.PublicKey(), sig, wrongMsg)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongPubkeySignature(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
wrongPk := NewSigner(require).pk
|
|
|
|
msg := []byte("TestVerifyWrongPubkeySignature local signer")
|
|
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.Verify(wrongPk, sig, msg)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongMessageSignedSignature(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyWrongMessageSignedSignature local signer")
|
|
wrongMsg := []byte("TestVerifyWrongMessageSignedSignaturelocal local signer with wrong signature")
|
|
|
|
wrongSig, err := signer.Sign(wrongMsg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.Verify(signer.PublicKey(), wrongSig, msg)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestValidAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestValidAggregation local signer")
|
|
|
|
sigs := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
isValid, err := AggregateAndVerify(pks, sigs, msg)
|
|
require.NoError(err)
|
|
require.True(isValid)
|
|
}
|
|
|
|
func TestSingleKeyAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
pks := []*bls.PublicKey{signer.PublicKey()}
|
|
|
|
msg := []byte("TestSingleKeyAggregation local signer")
|
|
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
|
|
isValid, err := AggregateAndVerify(pks, []*bls.Signature{sig}, msg)
|
|
require.NoError(err)
|
|
require.True(isValid)
|
|
}
|
|
|
|
func TestIncorrectMessageAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestIncorrectMessageAggregation local signer")
|
|
|
|
signatures := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
isValid, err := AggregateAndVerify(pks, signatures, []byte("a different message"))
|
|
require.NoError(err)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestDifferentMessageAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestDifferentMessagesAggregation local signer")
|
|
differentMsg := []byte("TestDifferentMessagesAggregation local signer with different message")
|
|
|
|
diffSig, err := signers[0].Sign(differentMsg)
|
|
require.NoError(err)
|
|
|
|
sameSigs := mapSlice(signers[1:], func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
signatures := append([]*bls.Signature{diffSig}, sameSigs...)
|
|
|
|
isValid, err := AggregateAndVerify(pks, signatures, msg)
|
|
require.NoError(err)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestOneIncorrectPubKeyAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestOneIncorrectPubKeyAggregation local signer")
|
|
|
|
signatures := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
// incorrect pubkey
|
|
pks[0] = NewSigner(require).PublicKey()
|
|
|
|
isValid, err := AggregateAndVerify(pks, signatures, msg)
|
|
require.NoError(err)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestMorePubkeysThanSignaturesAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestMorePubkeysThanSignatures local signer")
|
|
|
|
signatures := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
// add an extra pubkey
|
|
pks = append(pks, NewSigner(require).PublicKey())
|
|
|
|
isValid, err := AggregateAndVerify(pks, signatures, msg)
|
|
require.NoError(err)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestMoreSignaturesThanPubkeysAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestMoreSignaturesThanPubkeys local signer")
|
|
|
|
signatures := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
isValid, err := AggregateAndVerify(pks[1:], signatures, msg)
|
|
require.NoError(err)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestNoPubkeysAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
|
|
msg := []byte("TestNoPubkeysAggregation local signer")
|
|
|
|
signatures := mapSlice(signers, func(signer *LocalSigner) *bls.Signature {
|
|
sig, err := signer.Sign(msg)
|
|
require.NoError(err)
|
|
return sig
|
|
})
|
|
|
|
isValid, err := AggregateAndVerify(nil, signatures, msg)
|
|
require.ErrorIs(err, bls.ErrNoPublicKeys)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestNoSignaturesAggregation(t *testing.T) {
|
|
require := require.New(t)
|
|
signers := []*LocalSigner{NewSigner(require), NewSigner(require), NewSigner(require)}
|
|
pks := mapSlice(signers, (*LocalSigner).PublicKey)
|
|
|
|
msg := []byte("TestNoSignaturesAggregation local signer")
|
|
|
|
isValid, err := AggregateAndVerify(pks, nil, msg)
|
|
require.ErrorIs(err, bls.ErrNoSignatures)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestVerifyValidProofOfPossession(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyValidProofOfPossession local signer")
|
|
|
|
sig, err := signer.SignProofOfPossession(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.VerifyProofOfPossession(signer.PublicKey(), sig, msg)
|
|
require.True(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongMessageProofOfPossession(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyWrongMessageProofOfPossession local signer")
|
|
wrongMsg := []byte("TestVerifyWrongMessageProofOfPossession local signer with wrong message")
|
|
|
|
sig, err := signer.SignProofOfPossession(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.VerifyProofOfPossession(signer.PublicKey(), sig, wrongMsg)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongPubkeyProofOfPossession(t *testing.T) {
|
|
require := require.New(t)
|
|
correctSigner := NewSigner(require)
|
|
wrongSigner := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyWrongPubkeyProofOfPossession local signer")
|
|
|
|
sig, err := correctSigner.SignProofOfPossession(msg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.VerifyProofOfPossession(wrongSigner.PublicKey(), sig, msg)
|
|
require.False(isValid)
|
|
}
|
|
|
|
func TestVerifyWrongMessageSignedProofOfPossession(t *testing.T) {
|
|
require := require.New(t)
|
|
signer := NewSigner(require)
|
|
|
|
msg := []byte("TestVerifyWrongMessageSignedProofOfPossession local signer")
|
|
wrongMsg := []byte("TestVerifyWrongMessageSignedProofOfPossession local signer with wrong signature")
|
|
|
|
wrongSig, err := signer.SignProofOfPossession(wrongMsg)
|
|
require.NoError(err)
|
|
|
|
isValid := bls.VerifyProofOfPossession(signer.PublicKey(), wrongSig, msg)
|
|
require.False(isValid)
|
|
}
|