verify_test.go raw

   1  //go:build !js && !wasm && !tinygo && !wasm32
   2  
   3  package p256k1
   4  
   5  import (
   6  	"testing"
   7  )
   8  
   9  // TestSecp256k1SchnorrsigVerifyComparison tests that secp256k1_schnorrsig_verify
  10  // produces the same results as the existing SchnorrVerify function
  11  func TestSecp256k1SchnorrsigVerifyComparison(t *testing.T) {
  12  	// Create a context (required by secp256k1_schnorrsig_verify)
  13  	ctx := &secp256k1_context{
  14  		ecmult_gen_ctx: secp256k1_ecmult_gen_context{built: 1},
  15  		declassify:     0,
  16  	}
  17  
  18  	// Test case 1: Valid signature
  19  	t.Run("ValidSignature", func(t *testing.T) {
  20  		// Generate keypair
  21  		kp, err := KeyPairGenerate()
  22  		if err != nil {
  23  			t.Fatalf("failed to generate keypair: %v", err)
  24  		}
  25  		defer kp.Clear()
  26  
  27  		// Get x-only pubkey
  28  		xonly, err := kp.XOnlyPubkey()
  29  		if err != nil {
  30  			t.Fatalf("failed to get x-only pubkey: %v", err)
  31  		}
  32  
  33  		// Create message
  34  		msg := make([]byte, 32)
  35  		for i := range msg {
  36  			msg[i] = byte(i)
  37  		}
  38  
  39  		// Sign
  40  		var sig [64]byte
  41  		if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
  42  			t.Fatalf("failed to sign: %v", err)
  43  		}
  44  
  45  		// Convert x-only pubkey to secp256k1_xonly_pubkey format
  46  		var secp_xonly secp256k1_xonly_pubkey
  47  		copy(secp_xonly.data[:], xonly.data[:])
  48  
  49  		// Test existing implementation (old)
  50  		existingResult := SchnorrVerifyOld(sig[:], msg, xonly)
  51  
  52  		// Test new implementation (C-translated)
  53  		newResult := SchnorrVerify(sig[:], msg, xonly)
  54  
  55  		// Compare results
  56  		if existingResult != newResult {
  57  			t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
  58  		}
  59  
  60  		if !existingResult {
  61  			t.Error("signature verification failed (both implementations)")
  62  		}
  63  	})
  64  
  65  	// Test case 2: Invalid signature (wrong message)
  66  	t.Run("InvalidSignature_WrongMessage", func(t *testing.T) {
  67  		// Generate keypair
  68  		kp, err := KeyPairGenerate()
  69  		if err != nil {
  70  			t.Fatalf("failed to generate keypair: %v", err)
  71  		}
  72  		defer kp.Clear()
  73  
  74  		// Get x-only pubkey
  75  		xonly, err := kp.XOnlyPubkey()
  76  		if err != nil {
  77  			t.Fatalf("failed to get x-only pubkey: %v", err)
  78  		}
  79  
  80  		// Create message
  81  		msg := make([]byte, 32)
  82  		for i := range msg {
  83  			msg[i] = byte(i)
  84  		}
  85  
  86  		// Sign
  87  		var sig [64]byte
  88  		if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
  89  			t.Fatalf("failed to sign: %v", err)
  90  		}
  91  
  92  		// Create wrong message
  93  		wrongMsg := make([]byte, 32)
  94  		copy(wrongMsg, msg)
  95  		wrongMsg[0] ^= 1
  96  
  97  		// Convert x-only pubkey to secp256k1_xonly_pubkey format
  98  		var secp_xonly secp256k1_xonly_pubkey
  99  		copy(secp_xonly.data[:], xonly.data[:])
 100  
 101  		// Test existing implementation (old)
 102  		existingResult := SchnorrVerifyOld(sig[:], wrongMsg, xonly)
 103  
 104  		// Test new implementation (C-translated)
 105  		newResult := SchnorrVerify(sig[:], wrongMsg, xonly)
 106  
 107  		// Compare results
 108  		if existingResult != newResult {
 109  			t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
 110  		}
 111  
 112  		if existingResult {
 113  			t.Error("signature verification should fail with wrong message (both implementations)")
 114  		}
 115  	})
 116  
 117  	// Test case 3: Invalid signature (wrong signature)
 118  	t.Run("InvalidSignature_WrongSignature", func(t *testing.T) {
 119  		// Generate keypair
 120  		kp, err := KeyPairGenerate()
 121  		if err != nil {
 122  			t.Fatalf("failed to generate keypair: %v", err)
 123  		}
 124  		defer kp.Clear()
 125  
 126  		// Get x-only pubkey
 127  		xonly, err := kp.XOnlyPubkey()
 128  		if err != nil {
 129  			t.Fatalf("failed to get x-only pubkey: %v", err)
 130  		}
 131  
 132  		// Create message
 133  		msg := make([]byte, 32)
 134  		for i := range msg {
 135  			msg[i] = byte(i)
 136  		}
 137  
 138  		// Sign
 139  		var sig [64]byte
 140  		if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
 141  			t.Fatalf("failed to sign: %v", err)
 142  		}
 143  
 144  		// Create wrong signature
 145  		wrongSig := make([]byte, 64)
 146  		copy(wrongSig, sig[:])
 147  		wrongSig[0] ^= 1
 148  
 149  		// Convert x-only pubkey to secp256k1_xonly_pubkey format
 150  		var secp_xonly secp256k1_xonly_pubkey
 151  		copy(secp_xonly.data[:], xonly.data[:])
 152  
 153  		// Test existing implementation (old)
 154  		existingResult := SchnorrVerifyOld(wrongSig, msg, xonly)
 155  
 156  		// Test new implementation (C-translated)
 157  		newResult := SchnorrVerify(wrongSig, msg, xonly)
 158  
 159  		// Compare results
 160  		if existingResult != newResult {
 161  			t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
 162  		}
 163  
 164  		if existingResult {
 165  			t.Error("signature verification should fail with wrong signature (both implementations)")
 166  		}
 167  	})
 168  
 169  	// Test case 4: Invalid signature (wrong pubkey)
 170  	t.Run("InvalidSignature_WrongPubkey", func(t *testing.T) {
 171  		// Generate two keypairs
 172  		kp1, err := KeyPairGenerate()
 173  		if err != nil {
 174  			t.Fatalf("failed to generate keypair 1: %v", err)
 175  		}
 176  		defer kp1.Clear()
 177  
 178  		kp2, err := KeyPairGenerate()
 179  		if err != nil {
 180  			t.Fatalf("failed to generate keypair 2: %v", err)
 181  		}
 182  		defer kp2.Clear()
 183  
 184  		// Get x-only pubkey for kp2 (we sign with kp1, verify with kp2)
 185  		xonly2, err := kp2.XOnlyPubkey()
 186  		if err != nil {
 187  			t.Fatalf("failed to get x-only pubkey 2: %v", err)
 188  		}
 189  
 190  		// Create message
 191  		msg := make([]byte, 32)
 192  		for i := range msg {
 193  			msg[i] = byte(i)
 194  		}
 195  
 196  		// Sign with keypair 1
 197  		var sig [64]byte
 198  		if err := SchnorrSign(sig[:], msg, kp1, nil); err != nil {
 199  			t.Fatalf("failed to sign: %v", err)
 200  		}
 201  
 202  		// Convert x-only pubkey 2 to secp256k1_xonly_pubkey format
 203  		var secp_xonly2 secp256k1_xonly_pubkey
 204  		copy(secp_xonly2.data[:], xonly2.data[:])
 205  
 206  		// Test existing implementation (old, verify with wrong pubkey)
 207  		existingResult := SchnorrVerifyOld(sig[:], msg, xonly2)
 208  
 209  		// Test new implementation (C-translated, verify with wrong pubkey)
 210  		newResult := SchnorrVerify(sig[:], msg, xonly2)
 211  
 212  		// Compare results
 213  		if existingResult != newResult {
 214  			t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
 215  		}
 216  
 217  		if existingResult {
 218  			t.Error("signature verification should fail with wrong pubkey (both implementations)")
 219  		}
 220  	})
 221  
 222  	// Test case 5: Edge cases - nil/invalid inputs
 223  	t.Run("EdgeCases", func(t *testing.T) {
 224  		// Generate keypair
 225  		kp, err := KeyPairGenerate()
 226  		if err != nil {
 227  			t.Fatalf("failed to generate keypair: %v", err)
 228  		}
 229  		defer kp.Clear()
 230  
 231  		// Get x-only pubkey
 232  		xonly, err := kp.XOnlyPubkey()
 233  		if err != nil {
 234  			t.Fatalf("failed to get x-only pubkey: %v", err)
 235  		}
 236  
 237  		msg := make([]byte, 32)
 238  		var sig [64]byte
 239  
 240  		// Test with nil context
 241  		var secp_xonly secp256k1_xonly_pubkey
 242  		copy(secp_xonly.data[:], xonly.data[:])
 243  
 244  		newResult := secp256k1_schnorrsig_verify(nil, sig[:], msg, len(msg), &secp_xonly)
 245  		if newResult != 0 {
 246  			t.Error("should return 0 with nil context")
 247  		}
 248  
 249  		// Test with nil signature
 250  		newResult = secp256k1_schnorrsig_verify(ctx, nil, msg, len(msg), &secp_xonly)
 251  		if newResult != 0 {
 252  			t.Error("should return 0 with nil signature")
 253  		}
 254  
 255  		// Test with nil pubkey
 256  		newResult = secp256k1_schnorrsig_verify(ctx, sig[:], msg, len(msg), nil)
 257  		if newResult != 0 {
 258  			t.Error("should return 0 with nil pubkey")
 259  		}
 260  
 261  		// Test with invalid signature length
 262  		if SchnorrVerify([]byte{1}, msg, xonly) {
 263  			t.Error("existing: should fail with invalid signature length")
 264  		}
 265  		newResult = secp256k1_schnorrsig_verify(ctx, []byte{1}, msg, len(msg), &secp_xonly)
 266  		if newResult != 0 {
 267  			t.Error("new: should return 0 with invalid signature length")
 268  		}
 269  	})
 270  
 271  	// Test case 6: Multiple signatures with different aux_rand
 272  	t.Run("MultipleSignatures_DifferentAuxRand", func(t *testing.T) {
 273  		// Generate keypair
 274  		kp, err := KeyPairGenerate()
 275  		if err != nil {
 276  			t.Fatalf("failed to generate keypair: %v", err)
 277  		}
 278  		defer kp.Clear()
 279  
 280  		// Get x-only pubkey
 281  		xonly, err := kp.XOnlyPubkey()
 282  		if err != nil {
 283  			t.Fatalf("failed to get x-only pubkey: %v", err)
 284  		}
 285  
 286  		msg := make([]byte, 32)
 287  
 288  		// Sign with different aux_rand values
 289  		auxRand1 := make([]byte, 32)
 290  		auxRand2 := make([]byte, 32)
 291  		for i := range auxRand1 {
 292  			auxRand1[i] = byte(i)
 293  			auxRand2[i] = byte(i + 1)
 294  		}
 295  
 296  		var sig1, sig2 [64]byte
 297  		if err := SchnorrSign(sig1[:], msg, kp, auxRand1); err != nil {
 298  			t.Fatalf("failed to sign: %v", err)
 299  		}
 300  		if err := SchnorrSign(sig2[:], msg, kp, auxRand2); err != nil {
 301  			t.Fatalf("failed to sign: %v", err)
 302  		}
 303  
 304  		// Convert x-only pubkey to secp256k1_xonly_pubkey format
 305  		var secp_xonly secp256k1_xonly_pubkey
 306  		copy(secp_xonly.data[:], xonly.data[:])
 307  
 308  		// Test both signatures with existing implementation
 309  		existingResult1 := SchnorrVerify(sig1[:], msg, xonly)
 310  		existingResult2 := SchnorrVerify(sig2[:], msg, xonly)
 311  
 312  		// Test both signatures with new implementation
 313  		newResult1 := secp256k1_schnorrsig_verify(ctx, sig1[:], msg, len(msg), &secp_xonly)
 314  		newResult2 := secp256k1_schnorrsig_verify(ctx, sig2[:], msg, len(msg), &secp_xonly)
 315  
 316  		// Compare results
 317  		if existingResult1 != (newResult1 != 0) {
 318  			t.Errorf("signature 1 results differ: existing=%v, new=%d", existingResult1, newResult1)
 319  		}
 320  		if existingResult2 != (newResult2 != 0) {
 321  			t.Errorf("signature 2 results differ: existing=%v, new=%d", existingResult2, newResult2)
 322  		}
 323  
 324  		if !existingResult1 || !existingResult2 {
 325  			t.Error("both signatures should verify")
 326  		}
 327  	})
 328  
 329  	// Test case 7: Empty message
 330  	t.Run("EmptyMessage", func(t *testing.T) {
 331  		// Generate keypair
 332  		kp, err := KeyPairGenerate()
 333  		if err != nil {
 334  			t.Fatalf("failed to generate keypair: %v", err)
 335  		}
 336  		defer kp.Clear()
 337  
 338  		// Get x-only pubkey
 339  		xonly, err := kp.XOnlyPubkey()
 340  		if err != nil {
 341  			t.Fatalf("failed to get x-only pubkey: %v", err)
 342  		}
 343  
 344  		// Create 32-byte message (all zeros)
 345  		msg := make([]byte, 32)
 346  
 347  		// Sign
 348  		var sig [64]byte
 349  		if err := SchnorrSign(sig[:], msg, kp, nil); err != nil {
 350  			t.Fatalf("failed to sign: %v", err)
 351  		}
 352  
 353  		// Convert x-only pubkey to secp256k1_xonly_pubkey format
 354  		var secp_xonly secp256k1_xonly_pubkey
 355  		copy(secp_xonly.data[:], xonly.data[:])
 356  
 357  		// Test existing implementation (old)
 358  		existingResult := SchnorrVerifyOld(sig[:], msg, xonly)
 359  
 360  		// Test new implementation (C-translated)
 361  		newResult := SchnorrVerify(sig[:], msg, xonly)
 362  
 363  		// Compare results
 364  		if existingResult != newResult {
 365  			t.Errorf("results differ: existing=%v, new=%v", existingResult, newResult)
 366  		}
 367  
 368  		if !existingResult {
 369  			t.Error("signature verification failed for empty message")
 370  		}
 371  	})
 372  }
 373