mirror of
https://github.com/luxfi/precompile.git
synced 2026-07-27 03:33:45 +00:00
201 lines
4.3 KiB
Go
201 lines
4.3 KiB
Go
// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package frost
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/binary"
|
|
"testing"
|
|
|
|
"github.com/luxfi/geth/common"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestFROSTVerify_ValidSignature(t *testing.T) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
// Create test input with valid threshold parameters
|
|
input := make([]byte, MinInputSize)
|
|
|
|
// threshold = 3, total signers = 5
|
|
binary.BigEndian.PutUint32(input[0:4], 3)
|
|
binary.BigEndian.PutUint32(input[4:8], 5)
|
|
|
|
// Mock public key (32 bytes)
|
|
publicKey := make([]byte, 32)
|
|
for i := range publicKey {
|
|
publicKey[i] = byte(i)
|
|
}
|
|
copy(input[8:40], publicKey)
|
|
|
|
// Message hash
|
|
messageHash := sha256.Sum256([]byte("test message"))
|
|
copy(input[40:72], messageHash[:])
|
|
|
|
// Mock signature (64 bytes)
|
|
signature := make([]byte, 64)
|
|
for i := range signature {
|
|
signature[i] = byte(i)
|
|
}
|
|
copy(input[72:136], signature)
|
|
|
|
// Run precompile
|
|
result, remainingGas, err := precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
|
|
// Should not error (even if verification fails, it returns 0)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
require.Len(t, result, 32)
|
|
require.Greater(t, remainingGas, uint64(0))
|
|
}
|
|
|
|
func TestFROSTVerify_InvalidThreshold(t *testing.T) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
input := make([]byte, MinInputSize)
|
|
|
|
// Invalid: threshold = 0
|
|
binary.BigEndian.PutUint32(input[0:4], 0)
|
|
binary.BigEndian.PutUint32(input[4:8], 5)
|
|
|
|
_, _, err := precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, ErrInvalidThreshold)
|
|
}
|
|
|
|
func TestFROSTVerify_ThresholdGreaterThanTotal(t *testing.T) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
input := make([]byte, MinInputSize)
|
|
|
|
// Invalid: threshold > total
|
|
binary.BigEndian.PutUint32(input[0:4], 6)
|
|
binary.BigEndian.PutUint32(input[4:8], 5)
|
|
|
|
_, _, err := precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, ErrInvalidThreshold)
|
|
}
|
|
|
|
func TestFROSTVerify_InputTooShort(t *testing.T) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
input := make([]byte, MinInputSize-1)
|
|
|
|
_, _, err := precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.ErrorIs(t, err, ErrInvalidInputLength)
|
|
}
|
|
|
|
func TestFROSTVerify_GasCost(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
threshold uint32
|
|
totalSigners uint32
|
|
expectedGas uint64
|
|
}{
|
|
{"2-of-3", 2, 3, FROSTVerifyBaseGas + 3*FROSTVerifyPerSignerGas},
|
|
{"3-of-5", 3, 5, FROSTVerifyBaseGas + 5*FROSTVerifyPerSignerGas},
|
|
{"5-of-7", 5, 7, FROSTVerifyBaseGas + 7*FROSTVerifyPerSignerGas},
|
|
{"10-of-15", 10, 15, FROSTVerifyBaseGas + 15*FROSTVerifyPerSignerGas},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
input := make([]byte, MinInputSize)
|
|
binary.BigEndian.PutUint32(input[0:4], tt.threshold)
|
|
binary.BigEndian.PutUint32(input[4:8], tt.totalSigners)
|
|
|
|
gasCost := FROSTVerifyGasCost(input)
|
|
require.Equal(t, tt.expectedGas, gasCost)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFROSTVerify_Address(t *testing.T) {
|
|
precompile := FROSTVerifyPrecompile
|
|
require.Equal(t, ContractFROSTVerifyAddress, precompile.Address())
|
|
}
|
|
|
|
func BenchmarkFROSTVerify_3of5(b *testing.B) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
input := make([]byte, MinInputSize)
|
|
binary.BigEndian.PutUint32(input[0:4], 3)
|
|
binary.BigEndian.PutUint32(input[4:8], 5)
|
|
|
|
// Fill with test data
|
|
for i := 8; i < MinInputSize; i++ {
|
|
input[i] = byte(i)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _, _ = precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
}
|
|
}
|
|
|
|
func BenchmarkFROSTVerify_10of15(b *testing.B) {
|
|
precompile := FROSTVerifyPrecompile
|
|
|
|
input := make([]byte, MinInputSize)
|
|
binary.BigEndian.PutUint32(input[0:4], 10)
|
|
binary.BigEndian.PutUint32(input[4:8], 15)
|
|
|
|
// Fill with test data
|
|
for i := 8; i < MinInputSize; i++ {
|
|
input[i] = byte(i)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, _, _ = precompile.Run(
|
|
nil,
|
|
common.Address{},
|
|
ContractFROSTVerifyAddress,
|
|
input,
|
|
1_000_000,
|
|
true,
|
|
)
|
|
}
|
|
}
|