Files
zeekay ede37547f6 refactor(platformvm): consolidate block code, drop atomic_block, add v0 lift
- Drop atomic_block.go + legacy *_block_test.go (consolidated)
- Add block/v0/ subdir + lift_v0.go for old version handling
- Copyright header: 'Lux Industries, Inc.' → 'Lux Industries Inc' (no comma)
- block_adapter.go: new adapter layer
2026-06-01 15:22:27 -07:00

144 lines
3.9 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package signer
import (
"github.com/luxfi/crypto/bls/signer/localsigner"
"testing"
"github.com/stretchr/testify/require"
"github.com/luxfi/crypto/bls"
)
// TestBLSSingleNodeProofOfPossession tests BLS PoP for single node BFT
func TestBLSSingleNodeProofOfPossession(t *testing.T) {
require := require.New(t)
// Generate BLS key
sk, err := bls.NewSecretKey()
require.NoError(err)
// Create proof of possession
pop, err := NewProofOfPossession(func() bls.Signer { s, _ := localsigner.FromBytes(bls.SecretKeyToBytes(sk)); return s }())
require.NotNil(pop)
// Verify proof of possession
err = pop.Verify()
require.NoError(err, "Single node BLS proof of possession must be valid")
// Get public key
pk := pop.Key()
require.NotNil(pk)
// Verify it's the same as original
originalPk := sk.PublicKey()
require.Equal(bls.PublicKeyToCompressedBytes(originalPk), pop.PublicKey[:])
}
// TestBLSAggregateOfOne tests BLS aggregate signature with single validator
func TestBLSAggregateOfOne(t *testing.T) {
require := require.New(t)
// Generate key
sk, err := bls.NewSecretKey()
require.NoError(err)
// Message to sign
msg := []byte("consensus block data")
// Sign
sig, err := sk.Sign(msg)
require.NoError(err)
require.NotNil(sig)
// Create aggregate of 1
aggSig, err := bls.AggregateSignatures([]*bls.Signature{sig})
require.NoError(err, "Must support aggregate signature of 1")
// Aggregate public key of 1
pk := sk.PublicKey()
aggPk, err := bls.AggregatePublicKeys([]*bls.PublicKey{pk})
require.NoError(err, "Must support aggregate public key of 1")
// Verify
valid := bls.Verify(aggPk, aggSig, msg)
require.True(valid, "Aggregate signature of 1 must verify")
}
// TestInvalidProofOfPossession tests invalid PoP scenarios
func TestInvalidProofOfPossession(t *testing.T) {
tests := []struct {
name string
setupPoP func() *ProofOfPossession
expectErr bool
}{
{
name: "valid PoP",
setupPoP: func() *ProofOfPossession {
sk, _ := bls.NewSecretKey()
pop, _ := NewProofOfPossession(func() bls.Signer { s, _ := localsigner.FromBytes(bls.SecretKeyToBytes(sk)); return s }())
return pop
},
expectErr: false,
},
{
name: "corrupted signature",
setupPoP: func() *ProofOfPossession {
sk, _ := bls.NewSecretKey()
pop, _ := NewProofOfPossession(func() bls.Signer { s, _ := localsigner.FromBytes(bls.SecretKeyToBytes(sk)); return s }())
// Corrupt signature
pop.ProofOfPossession[0] ^= 0xFF
return pop
},
expectErr: true,
},
{
name: "corrupted public key",
setupPoP: func() *ProofOfPossession {
sk, _ := bls.NewSecretKey()
pop, _ := NewProofOfPossession(func() bls.Signer { s, _ := localsigner.FromBytes(bls.SecretKeyToBytes(sk)); return s }())
// Corrupt public key
pop.PublicKey[0] ^= 0xFF
return pop
},
expectErr: true,
},
{
name: "mismatched signature",
setupPoP: func() *ProofOfPossession {
sk1, _ := bls.NewSecretKey()
sk2, _ := bls.NewSecretKey()
// Use pk from sk1 but signature from sk2
pop, _ := NewProofOfPossession(func() bls.Signer { s, _ := localsigner.FromBytes(bls.SecretKeyToBytes(sk1)); return s }())
pk2 := sk2.PublicKey()
pk2Bytes := bls.PublicKeyToCompressedBytes(pk2)
sig2, _ := sk2.SignProofOfPossession(pk2Bytes)
copy(pop.ProofOfPossession[:], bls.SignatureToBytes(sig2))
return pop
},
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
pop := tt.setupPoP()
err := pop.Verify()
if tt.expectErr {
require.Error(err, "Invalid PoP must fail verification")
// Different corruption types can cause different errors
// from the BLS library or from our validation
} else {
require.NoError(err, "Valid PoP must pass verification")
}
})
}
}