@@ -16,6 +16,8 @@ import (
1616
1717var _ crypto.PublicKeySigningBytes = & PublicKey {}
1818var _ crypto.PublicKeySigningASN1 = & PublicKey {}
19+ var _ crypto.PublicKeyMultibase = & PublicKey {}
20+ var _ crypto.PublicKeyX509 = & PublicKey {}
1921
2022type PublicKey struct {
2123 k * secp256k1.PublicKey
@@ -44,6 +46,21 @@ func PublicKeyFromXY(x, y []byte) (*PublicKey, error) {
4446 return & PublicKey {k : secp256k1 .NewPublicKey (& xf , & yf )}, nil
4547}
4648
49+ // PublicKeyFromCompactRecovery recovers the secp256k1 public key from a compact signature
50+ // and the hash of the signed message. The signature must be 65 bytes:
51+ // [recovery_flag (1 byte) | R (32 bytes) | S (32 bytes)].
52+ // Returns an error if recovery fails or the signature is malformed.
53+ func PublicKeyFromCompactRecovery (hash , signature []byte ) (* PublicKey , error ) {
54+ if len (signature ) != 65 {
55+ return nil , fmt .Errorf ("secp256k1: invalid compact signature length: expected 65 bytes, got %d" , len (signature ))
56+ }
57+ pub , _ , err := ecdsa .RecoverCompact (signature , hash )
58+ if err != nil {
59+ return nil , fmt .Errorf ("secp256k1: failed to recover public key: %w" , err )
60+ }
61+ return & PublicKey {k : pub }, nil
62+ }
63+
4764// PublicKeyFromPublicKeyMultibase decodes the public key from its Multibase form
4865func PublicKeyFromPublicKeyMultibase (multibase string ) (* PublicKey , error ) {
4966 code , bytes , err := helpers .PublicKeyMultibaseDecode (multibase )
0 commit comments