Files
p256k1/pkg/ecmult_test.go

283 lines
5.9 KiB
Go

package p256k1
import (
"crypto/rand"
"testing"
)
func TestOptimizedScalarMultiplication(t *testing.T) {
// Test optimized generator multiplication
ctx, err := ContextCreate(ContextNone)
if err != nil {
t.Fatalf("Failed to create context: %v", err)
}
defer ContextDestroy(ctx)
// Test with known scalar
var scalar Scalar
scalar.setInt(12345)
var result GroupElementJacobian
ecmultGen(&ctx.ecmultGenCtx, &result, &scalar)
if result.isInfinity() {
t.Error("Generator multiplication should not result in infinity for non-zero scalar")
}
t.Log("Optimized generator multiplication test passed")
}
func TestEcmultConst(t *testing.T) {
// Test constant-time scalar multiplication
var point GroupElementAffine
point = GeneratorAffine // Use generator as test point
var scalar Scalar
scalar.setInt(7)
var result GroupElementJacobian
EcmultConst(&result, &scalar, &point)
if result.isInfinity() {
t.Error("Constant-time multiplication should not result in infinity for non-zero inputs")
}
t.Log("Constant-time multiplication test passed")
}
func TestEcmultMulti(t *testing.T) {
// Test multi-scalar multiplication
var points [3]*GroupElementAffine
var scalars [3]*Scalar
// Initialize test data
for i := 0; i < 3; i++ {
points[i] = &GroupElementAffine{}
*points[i] = GeneratorAffine
scalars[i] = &Scalar{}
scalars[i].setInt(uint(i + 1))
}
var result GroupElementJacobian
EcmultMulti(&result, scalars[:], points[:])
if result.isInfinity() {
t.Error("Multi-scalar multiplication should not result in infinity for non-zero inputs")
}
t.Log("Multi-scalar multiplication test passed")
}
func TestHashFunctions(t *testing.T) {
// Test SHA-256
input := []byte("test message")
var output [32]byte
SHA256Simple(output[:], input)
// Verify output is not all zeros
allZero := true
for _, b := range output {
if b != 0 {
allZero = false
break
}
}
if allZero {
t.Error("SHA-256 output should not be all zeros")
}
t.Log("SHA-256 test passed")
}
func TestTaggedSHA256(t *testing.T) {
// Test tagged SHA-256 (BIP-340)
tag := []byte("BIP0340/challenge")
msg := []byte("test message")
var output [32]byte
TaggedSHA256(output[:], tag, msg)
// Verify output is not all zeros
allZero := true
for _, b := range output {
if b != 0 {
allZero = false
break
}
}
if allZero {
t.Error("Tagged SHA-256 output should not be all zeros")
}
t.Log("Tagged SHA-256 test passed")
}
func TestRFC6979Nonce(t *testing.T) {
// Test RFC 6979 nonce generation
var msg32, key32, nonce32 [32]byte
// Fill with test data
for i := range msg32 {
msg32[i] = byte(i)
key32[i] = byte(i + 1)
}
// Generate nonce
success := rfc6979NonceFunction(nonce32[:], msg32[:], key32[:], nil, nil, 0)
if !success {
t.Error("RFC 6979 nonce generation failed")
}
// Verify nonce is not all zeros
allZero := true
for _, b := range nonce32 {
if b != 0 {
allZero = false
break
}
}
if allZero {
t.Error("RFC 6979 nonce should not be all zeros")
}
// Test determinism - same inputs should produce same nonce
var nonce32_2 [32]byte
success2 := rfc6979NonceFunction(nonce32_2[:], msg32[:], key32[:], nil, nil, 0)
if !success2 {
t.Error("Second RFC 6979 nonce generation failed")
}
for i := range nonce32 {
if nonce32[i] != nonce32_2[i] {
t.Error("RFC 6979 nonce generation is not deterministic")
break
}
}
t.Log("RFC 6979 nonce generation test passed")
}
func TestContextBlinding(t *testing.T) {
// Test context blinding for side-channel protection
ctx, err := ContextCreate(ContextNone)
if err != nil {
t.Fatalf("Failed to create context: %v", err)
}
defer ContextDestroy(ctx)
// Generate random seed
var seed [32]byte
_, err = rand.Read(seed[:])
if err != nil {
t.Fatalf("Failed to generate random seed: %v", err)
}
// Apply blinding
err = ContextRandomize(ctx, seed[:])
if err != nil {
t.Errorf("Context randomization failed: %v", err)
}
// Test that blinded context still works
var seckey [32]byte
_, err = rand.Read(seckey[:])
if err != nil {
t.Fatalf("Failed to generate random secret key: %v", err)
}
// Ensure valid secret key
for i := 0; i < 10; i++ {
if ECSecKeyVerify(ctx, seckey[:]) {
break
}
_, err = rand.Read(seckey[:])
if err != nil {
t.Fatalf("Failed to generate random secret key: %v", err)
}
if i == 9 {
t.Fatal("Failed to generate valid secret key after 10 attempts")
}
}
var pubkey PublicKey
if !ECPubkeyCreate(ctx, &pubkey, seckey[:]) {
t.Error("Key generation failed with blinded context")
}
t.Log("Context blinding test passed")
}
func BenchmarkOptimizedEcmultGen(b *testing.B) {
ctx, err := ContextCreate(ContextNone)
if err != nil {
b.Fatalf("Failed to create context: %v", err)
}
defer ContextDestroy(ctx)
var scalar Scalar
scalar.setInt(12345)
var result GroupElementJacobian
b.ResetTimer()
for i := 0; i < b.N; i++ {
ecmultGen(&ctx.ecmultGenCtx, &result, &scalar)
}
}
func BenchmarkEcmultConst(b *testing.B) {
var point GroupElementAffine
point = GeneratorAffine
var scalar Scalar
scalar.setInt(12345)
var result GroupElementJacobian
b.ResetTimer()
for i := 0; i < b.N; i++ {
EcmultConst(&result, &scalar, &point)
}
}
func BenchmarkSHA256(b *testing.B) {
input := []byte("test message for benchmarking SHA-256 performance")
var output [32]byte
b.ResetTimer()
for i := 0; i < b.N; i++ {
SHA256Simple(output[:], input)
}
}
func BenchmarkTaggedSHA256(b *testing.B) {
tag := []byte("BIP0340/challenge")
msg := []byte("test message for benchmarking tagged SHA-256 performance")
var output [32]byte
b.ResetTimer()
for i := 0; i < b.N; i++ {
TaggedSHA256(output[:], tag, msg)
}
}
func BenchmarkRFC6979Nonce(b *testing.B) {
var msg32, key32, nonce32 [32]byte
// Fill with test data
for i := range msg32 {
msg32[i] = byte(i)
key32[i] = byte(i + 1)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
rfc6979NonceFunction(nonce32[:], msg32[:], key32[:], nil, nil, 0)
}
}