- Replaced all instances of p256k1signer with the new p8k.Signer across various modules, including event creation, policy handling, and database interactions. - Updated related test cases and benchmarks to ensure compatibility with the new signer interface. - Bumped version to v0.25.0 to reflect these significant changes and improvements in cryptographic operations.
479 lines
11 KiB
Go
479 lines
11 KiB
Go
package secp
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"testing"
|
|
)
|
|
|
|
func TestContextCreation(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign | ContextVerify)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
if ctx.ctx == 0 {
|
|
t.Fatal("Context handle is null")
|
|
}
|
|
}
|
|
|
|
func TestPublicKeyGeneration(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
pubKey, err := ctx.CreatePublicKey(privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create public key: %v", err)
|
|
}
|
|
|
|
if len(pubKey) != PublicKeySize {
|
|
t.Fatalf("Public key size incorrect: got %d, want %d", len(pubKey), PublicKeySize)
|
|
}
|
|
}
|
|
|
|
func TestPublicKeySerialization(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
pubKey, err := ctx.CreatePublicKey(privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create public key: %v", err)
|
|
}
|
|
|
|
// Test compressed
|
|
compressed, err := ctx.SerializePublicKey(pubKey, true)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize compressed: %v", err)
|
|
}
|
|
if len(compressed) != CompressedPublicKeySize {
|
|
t.Fatalf("Compressed size incorrect: got %d, want %d", len(compressed), CompressedPublicKeySize)
|
|
}
|
|
|
|
// Test uncompressed
|
|
uncompressed, err := ctx.SerializePublicKey(pubKey, false)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize uncompressed: %v", err)
|
|
}
|
|
if len(uncompressed) != UncompressedPublicKeySize {
|
|
t.Fatalf("Uncompressed size incorrect: got %d, want %d", len(uncompressed), UncompressedPublicKeySize)
|
|
}
|
|
|
|
// Parse back compressed
|
|
parsed, err := ctx.ParsePublicKey(compressed)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse compressed: %v", err)
|
|
}
|
|
if len(parsed) != PublicKeySize {
|
|
t.Fatalf("Parsed size incorrect: got %d, want %d", len(parsed), PublicKeySize)
|
|
}
|
|
}
|
|
|
|
func TestECDSASignAndVerify(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign | ContextVerify)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
pubKey, err := ctx.CreatePublicKey(privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create public key: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
sig, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
valid, err := ctx.Verify(msgHash[:], sig, pubKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to verify: %v", err)
|
|
}
|
|
|
|
if !valid {
|
|
t.Fatal("Signature should be valid")
|
|
}
|
|
|
|
// Test with wrong message
|
|
wrongMsg := []byte("Wrong message")
|
|
wrongHash := sha256.Sum256(wrongMsg)
|
|
valid2, err := ctx.Verify(wrongHash[:], sig, pubKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to verify wrong message: %v", err)
|
|
}
|
|
|
|
if valid2 {
|
|
t.Fatal("Signature should be invalid for wrong message")
|
|
}
|
|
}
|
|
|
|
func TestDERSignatureSerialization(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
sig, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
derSig, err := ctx.SerializeSignatureDER(sig)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize DER: %v", err)
|
|
}
|
|
|
|
parsed, err := ctx.ParseSignatureDER(derSig)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse DER: %v", err)
|
|
}
|
|
|
|
if len(parsed) != SignatureSize {
|
|
t.Fatalf("Parsed signature size incorrect: got %d, want %d", len(parsed), SignatureSize)
|
|
}
|
|
}
|
|
|
|
func TestCompactSignatureSerialization(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
sig, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
compact, err := ctx.SerializeSignatureCompact(sig)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize compact: %v", err)
|
|
}
|
|
|
|
if len(compact) != CompactSignatureSize {
|
|
t.Fatalf("Compact size incorrect: got %d, want %d", len(compact), CompactSignatureSize)
|
|
}
|
|
|
|
parsed, err := ctx.ParseSignatureCompact(compact)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse compact: %v", err)
|
|
}
|
|
|
|
if len(parsed) != SignatureSize {
|
|
t.Fatalf("Parsed signature size incorrect: got %d, want %d", len(parsed), SignatureSize)
|
|
}
|
|
}
|
|
|
|
func TestSignatureNormalization(t *testing.T) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
sig, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
normalized, wasNormalized, err := ctx.NormalizeSignature(sig)
|
|
if err != nil {
|
|
t.Fatalf("Failed to normalize: %v", err)
|
|
}
|
|
|
|
if len(normalized) != SignatureSize {
|
|
t.Fatalf("Normalized signature size incorrect: got %d, want %d", len(normalized), SignatureSize)
|
|
}
|
|
|
|
_ = wasNormalized // May or may not be normalized
|
|
}
|
|
|
|
func TestSchnorrSignAndVerify(t *testing.T) {
|
|
if schnorrsigSign32 == nil {
|
|
t.Skip("Schnorr module not available")
|
|
}
|
|
|
|
ctx, err := NewContext(ContextSign | ContextVerify)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
keypair, err := ctx.CreateKeypair(privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create keypair: %v", err)
|
|
}
|
|
|
|
xonly, _, err := ctx.KeypairXOnlyPub(keypair)
|
|
if err != nil {
|
|
t.Fatalf("Failed to extract xonly pubkey: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
auxRand := make([]byte, 32)
|
|
if _, err := rand.Read(auxRand); err != nil {
|
|
t.Fatalf("Failed to generate aux_rand: %v", err)
|
|
}
|
|
|
|
sig, err := ctx.SchnorrSign(msgHash[:], keypair, auxRand)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
if len(sig) != SchnorrSignatureSize {
|
|
t.Fatalf("Signature size incorrect: got %d, want %d", len(sig), SchnorrSignatureSize)
|
|
}
|
|
|
|
valid, err := ctx.SchnorrVerify(sig, msgHash[:], xonly[:])
|
|
if err != nil {
|
|
t.Fatalf("Failed to verify: %v", err)
|
|
}
|
|
|
|
if !valid {
|
|
t.Fatal("Schnorr signature should be valid")
|
|
}
|
|
|
|
// Test with wrong message
|
|
wrongMsg := []byte("Wrong message")
|
|
wrongHash := sha256.Sum256(wrongMsg)
|
|
valid2, err := ctx.SchnorrVerify(sig, wrongHash[:], xonly[:])
|
|
if err != nil {
|
|
t.Fatalf("Failed to verify wrong message: %v", err)
|
|
}
|
|
|
|
if valid2 {
|
|
t.Fatal("Schnorr signature should be invalid for wrong message")
|
|
}
|
|
}
|
|
|
|
func TestECDH(t *testing.T) {
|
|
if ecdh == nil {
|
|
t.Skip("ECDH module not available")
|
|
}
|
|
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
// Alice's keys
|
|
alicePriv := make([]byte, 32)
|
|
if _, err := rand.Read(alicePriv); err != nil {
|
|
t.Fatalf("Failed to generate Alice's key: %v", err)
|
|
}
|
|
alicePub, err := ctx.CreatePublicKey(alicePriv)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create Alice's public key: %v", err)
|
|
}
|
|
|
|
// Bob's keys
|
|
bobPriv := make([]byte, 32)
|
|
if _, err := rand.Read(bobPriv); err != nil {
|
|
t.Fatalf("Failed to generate Bob's key: %v", err)
|
|
}
|
|
bobPub, err := ctx.CreatePublicKey(bobPriv)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create Bob's public key: %v", err)
|
|
}
|
|
|
|
// Compute shared secrets
|
|
aliceShared, err := ctx.ECDH(bobPub, alicePriv)
|
|
if err != nil {
|
|
t.Fatalf("Failed to compute Alice's shared secret: %v", err)
|
|
}
|
|
|
|
bobShared, err := ctx.ECDH(alicePub, bobPriv)
|
|
if err != nil {
|
|
t.Fatalf("Failed to compute Bob's shared secret: %v", err)
|
|
}
|
|
|
|
if len(aliceShared) != SharedSecretSize {
|
|
t.Fatalf("Shared secret size incorrect: got %d, want %d", len(aliceShared), SharedSecretSize)
|
|
}
|
|
|
|
// Secrets should match
|
|
if string(aliceShared) != string(bobShared) {
|
|
t.Fatal("Shared secrets should match")
|
|
}
|
|
}
|
|
|
|
func TestRecovery(t *testing.T) {
|
|
if ecdsaSignRecoverable == nil {
|
|
t.Skip("Recovery module not available")
|
|
}
|
|
|
|
ctx, err := NewContext(ContextSign | ContextVerify)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
if _, err := rand.Read(privKey); err != nil {
|
|
t.Fatalf("Failed to generate random key: %v", err)
|
|
}
|
|
|
|
originalPubKey, err := ctx.CreatePublicKey(privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create public key: %v", err)
|
|
}
|
|
|
|
message := []byte("Test message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
recSig, err := ctx.SignRecoverable(msgHash[:], privKey)
|
|
if err != nil {
|
|
t.Fatalf("Failed to sign recoverable: %v", err)
|
|
}
|
|
|
|
sigBytes, recID, err := ctx.SerializeRecoverableSignatureCompact(recSig)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize recoverable: %v", err)
|
|
}
|
|
|
|
if len(sigBytes) != 64 {
|
|
t.Fatalf("Signature size incorrect: got %d, want 64", len(sigBytes))
|
|
}
|
|
|
|
if recID < 0 || recID > 3 {
|
|
t.Fatalf("Recovery ID out of range: %d", recID)
|
|
}
|
|
|
|
parsedSig, err := ctx.ParseRecoverableSignatureCompact(sigBytes, recID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to parse recoverable: %v", err)
|
|
}
|
|
|
|
recoveredPubKey, err := ctx.Recover(parsedSig, msgHash[:])
|
|
if err != nil {
|
|
t.Fatalf("Failed to recover public key: %v", err)
|
|
}
|
|
|
|
// Serialize both for comparison
|
|
origSer, err := ctx.SerializePublicKey(originalPubKey, true)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize original: %v", err)
|
|
}
|
|
|
|
recSer, err := ctx.SerializePublicKey(recoveredPubKey, true)
|
|
if err != nil {
|
|
t.Fatalf("Failed to serialize recovered: %v", err)
|
|
}
|
|
|
|
if string(origSer) != string(recSer) {
|
|
t.Fatal("Recovered public key should match original")
|
|
}
|
|
}
|
|
|
|
func BenchmarkSign(b *testing.B) {
|
|
ctx, err := NewContext(ContextSign)
|
|
if err != nil {
|
|
b.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
rand.Read(privKey)
|
|
|
|
message := []byte("Benchmark message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
b.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func BenchmarkVerify(b *testing.B) {
|
|
ctx, err := NewContext(ContextSign | ContextVerify)
|
|
if err != nil {
|
|
b.Fatalf("Failed to create context: %v", err)
|
|
}
|
|
defer ctx.Destroy()
|
|
|
|
privKey := make([]byte, 32)
|
|
rand.Read(privKey)
|
|
|
|
pubKey, err := ctx.CreatePublicKey(privKey)
|
|
if err != nil {
|
|
b.Fatalf("Failed to create public key: %v", err)
|
|
}
|
|
|
|
message := []byte("Benchmark message")
|
|
msgHash := sha256.Sum256(message)
|
|
|
|
sig, err := ctx.Sign(msgHash[:], privKey)
|
|
if err != nil {
|
|
b.Fatalf("Failed to sign: %v", err)
|
|
}
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
_, err := ctx.Verify(msgHash[:], sig, pubKey)
|
|
if err != nil {
|
|
b.Fatalf("Failed to verify: %v", err)
|
|
}
|
|
}
|
|
}
|