Files
next.orly.dev/pkg/crypto/p8k/utils.go
mleku e0a95ca1cd
Some checks failed
Go / build (push) Has been cancelled
Go / release (push) Has been cancelled
Refactor signer implementation to use p8k package
- 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.
2025-11-04 20:05:19 +00:00

269 lines
5.9 KiB
Go

package secp
import (
"crypto/rand"
"fmt"
)
// GeneratePrivateKey generates a random 32-byte private key
func GeneratePrivateKey() (privKey []byte, err error) {
privKey = make([]byte, PrivateKeySize)
if _, err = rand.Read(privKey); err != nil {
err = fmt.Errorf("failed to generate random key: %w", err)
return
}
return
}
// PublicKeyFromPrivate generates a public key from a private key
// Returns the serialized public key in compressed format
func PublicKeyFromPrivate(privKey []byte, compressed bool) (pubKey []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
internalPubKey, err := ctx.CreatePublicKey(privKey)
if err != nil {
return
}
pubKey, err = ctx.SerializePublicKey(internalPubKey, compressed)
return
}
// SignMessage signs a 32-byte message hash with a private key
// Returns the signature in compact format (64 bytes)
func SignMessage(msgHash []byte, privKey []byte) (sig []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
internalSig, err := ctx.Sign(msgHash, privKey)
if err != nil {
return
}
sig, err = ctx.SerializeSignatureCompact(internalSig)
return
}
// VerifyMessage verifies a compact signature against a message hash and serialized public key
func VerifyMessage(msgHash []byte, compactSig []byte, serializedPubKey []byte) (valid bool, err error) {
ctx, err := NewContext(ContextVerify)
if err != nil {
return
}
defer ctx.Destroy()
pubKey, err := ctx.ParsePublicKey(serializedPubKey)
if err != nil {
return
}
sig, err := ctx.ParseSignatureCompact(compactSig)
if err != nil {
return
}
valid, err = ctx.Verify(msgHash, sig, pubKey)
return
}
// SignMessageDER signs a message and returns DER-encoded signature
func SignMessageDER(msgHash []byte, privKey []byte) (derSig []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
internalSig, err := ctx.Sign(msgHash, privKey)
if err != nil {
return
}
derSig, err = ctx.SerializeSignatureDER(internalSig)
return
}
// VerifyMessageDER verifies a DER-encoded signature
func VerifyMessageDER(msgHash []byte, derSig []byte, serializedPubKey []byte) (valid bool, err error) {
ctx, err := NewContext(ContextVerify)
if err != nil {
return
}
defer ctx.Destroy()
pubKey, err := ctx.ParsePublicKey(serializedPubKey)
if err != nil {
return
}
sig, err := ctx.ParseSignatureDER(derSig)
if err != nil {
return
}
valid, err = ctx.Verify(msgHash, sig, pubKey)
return
}
// SchnorrSign signs a message with Schnorr signature (BIP-340)
// Returns 64-byte Schnorr signature
func SchnorrSign(msgHash []byte, privKey []byte, auxRand []byte) (sig []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
keypair, err := ctx.CreateKeypair(privKey)
if err != nil {
return
}
sig, err = ctx.SchnorrSign(msgHash, keypair, auxRand)
return
}
// SchnorrVerifyWithPubKey verifies a Schnorr signature (BIP-340)
// xonlyPubKey should be 32 bytes
func SchnorrVerifyWithPubKey(msgHash []byte, sig []byte, xonlyPubKey []byte) (valid bool, err error) {
ctx, err := NewContext(ContextVerify)
if err != nil {
return
}
defer ctx.Destroy()
valid, err = ctx.SchnorrVerify(sig, msgHash, xonlyPubKey)
return
}
// XOnlyPubKeyFromPrivate generates an x-only public key from a private key
func XOnlyPubKeyFromPrivate(privKey []byte) (xonly []byte, pkParity int32, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
keypair, err := ctx.CreateKeypair(privKey)
if err != nil {
return
}
var xonlyInternal XOnlyPublicKey
xonlyInternal, pkParity, err = ctx.KeypairXOnlyPub(keypair)
if err != nil {
return
}
xonly = xonlyInternal[:]
return
}
// ComputeECDH computes an ECDH shared secret
func ComputeECDH(serializedPubKey []byte, privKey []byte) (secret []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
pubKey, err := ctx.ParsePublicKey(serializedPubKey)
if err != nil {
return
}
secret, err = ctx.ECDH(pubKey, privKey)
return
}
// SignRecoverableCompact signs a message with a recoverable signature
// Returns compact signature (64 bytes) and recovery ID
func SignRecoverableCompact(msgHash []byte, privKey []byte) (sig []byte, recID int32, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
recSig, err := ctx.SignRecoverable(msgHash, privKey)
if err != nil {
return
}
sig, recID, err = ctx.SerializeRecoverableSignatureCompact(recSig)
return
}
// RecoverPubKey recovers a public key from a recoverable signature
// Returns serialized public key in compressed format
func RecoverPubKey(msgHash []byte, compactSig []byte, recID int32, compressed bool) (pubKey []byte, err error) {
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
recSig, err := ctx.ParseRecoverableSignatureCompact(compactSig, recID)
if err != nil {
return
}
recoveredPubKey, err := ctx.Recover(recSig, msgHash)
if err != nil {
return
}
pubKey, err = ctx.SerializePublicKey(recoveredPubKey, compressed)
return
}
// ValidatePrivateKey checks if a private key is valid
func ValidatePrivateKey(privKey []byte) (valid bool, err error) {
if len(privKey) != PrivateKeySize {
err = fmt.Errorf("private key must be %d bytes", PrivateKeySize)
return
}
ctx, err := NewContext(ContextSign)
if err != nil {
return
}
defer ctx.Destroy()
_, err = ctx.CreatePublicKey(privKey)
if err != nil {
valid = false
err = nil
return
}
valid = true
return
}
// IsPublicKeyValid checks if a serialized public key is valid
func IsPublicKeyValid(serializedPubKey []byte) (valid bool, err error) {
ctx, err := NewContext(ContextVerify)
if err != nil {
return
}
defer ctx.Destroy()
_, err = ctx.ParsePublicKey(serializedPubKey)
if err != nil {
valid = false
err = nil
return
}
valid = true
return
}