package secp256k1 import ( "bytes" "encoding/hex" "math/big" "testing" ) func TestTaggedHash(t *testing.T) { // Just verify it produces 32 bytes result := TaggedHash("test", []byte("hello")) if len(result) != 32 { t.Errorf("expected 32 bytes, got %d", len(result)) } // Same inputs should produce same output result2 := TaggedHash("test", []byte("hello")) if !bytes.Equal(result, result2) { t.Error("tagged hash should be deterministic") } // Different tag should produce different output result3 := TaggedHash("other", []byte("hello")) if bytes.Equal(result, result3) { t.Error("different tags should produce different hashes") } } func TestLiftX(t *testing.T) { // Lift G.x should give us G (or its negation with even y) p, err := liftX(Gx) if err != nil { t.Fatalf("failed to lift G.x: %v", err) } if !p.IsOnCurve() { t.Error("lifted point should be on curve") } // x should match if p.x.value.Cmp(Gx) != 0 { t.Error("lifted x should match input") } // y should be even (BIP-340 convention) if !hasEvenY(p) { t.Error("lifted point should have even y") } } func TestLiftXInvalid(t *testing.T) { // x = 0 is not on the curve (0³ + 7 = 7, and 7 has no sqrt mod p) _, err := liftX(big.NewInt(0)) if err == nil { t.Error("x=0 should not be on curve") } } func TestSignAndVerify(t *testing.T) { priv, _ := GeneratePrivateKey() pub := priv.PublicKey() message := []byte("hello world") sig, err := Sign(priv, message) if err != nil { t.Fatalf("signing failed: %v", err) } if !Verify(pub, message, sig) { t.Error("signature should verify") } } func TestSignatureIsDeteministic(t *testing.T) { priv, _ := NewPrivateKeyFromHex("0000000000000000000000000000000000000000000000000000000000000001") message := []byte("test message") sig1, _ := Sign(priv, message) sig2, _ := Sign(priv, message) if sig1.R.Cmp(sig2.R) != 0 || sig1.S.Cmp(sig2.S) != 0 { t.Error("BIP-340 signing should be deterministic") } } func TestVerifyWrongMessage(t *testing.T) { priv, _ := GeneratePrivateKey() pub := priv.PublicKey() sig, _ := Sign(priv, []byte("correct message")) if Verify(pub, []byte("wrong message"), sig) { t.Error("signature should not verify with wrong message") } } func TestVerifyWrongPublicKey(t *testing.T) { priv1, _ := GeneratePrivateKey() priv2, _ := GeneratePrivateKey() pub2 := priv2.PublicKey() message := []byte("test") sig, _ := Sign(priv1, message) if Verify(pub2, message, sig) { t.Error("signature should not verify with wrong public key") } } func TestVerifyTamperedSignature(t *testing.T) { priv, _ := GeneratePrivateKey() pub := priv.PublicKey() message := []byte("test") sig, _ := Sign(priv, message) // Tamper with s tamperedSig := &Signature{ R: sig.R, S: new(big.Int).Add(sig.S, big.NewInt(1)), } if Verify(pub, message, tamperedSig) { t.Error("tampered signature should not verify") } } func TestSignatureBytes(t *testing.T) { priv, _ := GeneratePrivateKey() message := []byte("test") sig, _ := Sign(priv, message) b := sig.Bytes() if len(b) != 64 { t.Errorf("signature should be 64 bytes, got %d", len(b)) } } func TestSignatureRoundTrip(t *testing.T) { priv, _ := GeneratePrivateKey() message := []byte("test") sig1, _ := Sign(priv, message) b := sig1.Bytes() sig2, err := SignatureFromBytes(b) if err != nil { t.Fatalf("failed to parse signature: %v", err) } if sig1.R.Cmp(sig2.R) != 0 || sig1.S.Cmp(sig2.S) != 0 { t.Error("signature should survive round-trip") } } func TestSignatureFromBytesInvalid(t *testing.T) { _, err := SignatureFromBytes(make([]byte, 63)) if err == nil { t.Error("should reject wrong-length input") } } // BIP-340 Test Vector 0 func TestBIP340Vector0(t *testing.T) { privHex := "0000000000000000000000000000000000000000000000000000000000000003" msgHex := "0000000000000000000000000000000000000000000000000000000000000000" expectedSigHex := "e907831f80848d1069a5371b402410364bdf1c5f8307b0084c55f1ce2dca821525f66a4a85ea8b71e482a74f382d2ce5ebeee8fdb2172f477df4900d310536c0" priv, err := NewPrivateKeyFromHex(privHex) if err != nil { t.Fatalf("failed to parse private key: %v", err) } msg, _ := hex.DecodeString(msgHex) sig, err := Sign(priv, msg) if err != nil { t.Fatalf("signing failed: %v", err) } sigHex := sig.Hex() if sigHex != expectedSigHex { t.Errorf("signature mismatch\ngot: %s\nwant: %s", sigHex, expectedSigHex) } // Also verify it pub := priv.PublicKey() if !Verify(pub, msg, sig) { t.Error("BIP-340 test vector should verify") } } // BIP-340 Test Vector 1 func TestBIP340Vector1(t *testing.T) { privHex := "b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfef" msgHex := "243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89" auxHex := "0000000000000000000000000000000000000000000000000000000000000001" expectedSigHex := "6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de33418906d11ac976abccb20b091292bff4ea897efcb639ea871cfa95f6de339e4b0a" priv, err := NewPrivateKeyFromHex(privHex) if err != nil { t.Fatalf("failed to parse private key: %v", err) } msg, _ := hex.DecodeString(msgHex) aux, _ := hex.DecodeString(auxHex) sig, err := Sign(priv, msg, aux) if err != nil { t.Fatalf("signing failed: %v", err) } sigHex := sig.Hex() if sigHex != expectedSigHex { t.Errorf("signature mismatch\ngot: %s\nwant: %s", sigHex, expectedSigHex) } pub := priv.PublicKey() if !Verify(pub, msg, sig) { t.Error("BIP-340 test vector should verify") } } func TestXOnlyBytes(t *testing.T) { priv, _ := NewPrivateKeyFromHex("0000000000000000000000000000000000000000000000000000000000000001") pub := priv.PublicKey() xOnly := pub.XOnlyBytes() if len(xOnly) != 32 { t.Errorf("x-only pubkey should be 32 bytes, got %d", len(xOnly)) } // Should match G.x expectedX := make([]byte, 32) gxBytes := Gx.Bytes() copy(expectedX[32-len(gxBytes):], gxBytes) if !bytes.Equal(xOnly, expectedX) { t.Error("x-only bytes should match G.x") } }