sign.go raw

   1  package find
   2  
   3  import (
   4  	"crypto/sha256"
   5  	"fmt"
   6  	"time"
   7  
   8  	"next.orly.dev/pkg/nostr/encoders/event"
   9  	"next.orly.dev/pkg/nostr/encoders/hex"
  10  	"next.orly.dev/pkg/nostr/interfaces/signer"
  11  )
  12  
  13  // SignTransferAuth creates a signature for transfer authorization
  14  // Message format: transfer:<name>:<new_owner_pubkey>:<timestamp>
  15  func SignTransferAuth(name, newOwner string, timestamp time.Time, s signer.I) (string, error) {
  16  	// Normalize name
  17  	name = NormalizeName(name)
  18  
  19  	// Construct message
  20  	message := fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
  21  
  22  	// Hash the message
  23  	hash := sha256.Sum256([]byte(message))
  24  
  25  	// Sign the hash
  26  	sig, err := s.Sign(hash[:])
  27  	if err != nil {
  28  		return "", fmt.Errorf("failed to sign transfer authorization: %w", err)
  29  	}
  30  
  31  	// Return hex-encoded signature
  32  	return hex.Enc(sig), nil
  33  }
  34  
  35  // SignChallengeProof creates a signature for certificate challenge proof
  36  // Message format: challenge||name||cert_pubkey||valid_until
  37  func SignChallengeProof(challenge, name, certPubkey string, validUntil time.Time, s signer.I) (string, error) {
  38  	// Normalize name
  39  	name = NormalizeName(name)
  40  
  41  	// Construct message
  42  	message := fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
  43  
  44  	// Hash the message
  45  	hash := sha256.Sum256([]byte(message))
  46  
  47  	// Sign the hash
  48  	sig, err := s.Sign(hash[:])
  49  	if err != nil {
  50  		return "", fmt.Errorf("failed to sign challenge proof: %w", err)
  51  	}
  52  
  53  	// Return hex-encoded signature
  54  	return hex.Enc(sig), nil
  55  }
  56  
  57  // SignWitnessMessage creates a witness signature for a certificate
  58  // Message format: cert_pubkey||name||valid_from||valid_until||challenge
  59  func SignWitnessMessage(certPubkey, name string, validFrom, validUntil time.Time, challenge string, s signer.I) (string, error) {
  60  	// Normalize name
  61  	name = NormalizeName(name)
  62  
  63  	// Construct message
  64  	message := fmt.Sprintf("%s||%s||%d||%d||%s",
  65  		certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
  66  
  67  	// Hash the message
  68  	hash := sha256.Sum256([]byte(message))
  69  
  70  	// Sign the hash
  71  	sig, err := s.Sign(hash[:])
  72  	if err != nil {
  73  		return "", fmt.Errorf("failed to sign witness message: %w", err)
  74  	}
  75  
  76  	// Return hex-encoded signature
  77  	return hex.Enc(sig), nil
  78  }
  79  
  80  // CreateTransferAuthMessage constructs the transfer authorization message
  81  // This is used for verification
  82  func CreateTransferAuthMessage(name, newOwner string, timestamp time.Time) []byte {
  83  	name = NormalizeName(name)
  84  	message := fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
  85  	hash := sha256.Sum256([]byte(message))
  86  	return hash[:]
  87  }
  88  
  89  // CreateChallengeProofMessage constructs the challenge proof message
  90  // This is used for verification
  91  func CreateChallengeProofMessage(challenge, name, certPubkey string, validUntil time.Time) []byte {
  92  	name = NormalizeName(name)
  93  	message := fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
  94  	hash := sha256.Sum256([]byte(message))
  95  	return hash[:]
  96  }
  97  
  98  // CreateWitnessMessage constructs the witness message
  99  // This is used for verification
 100  func CreateWitnessMessage(certPubkey, name string, validFrom, validUntil time.Time, challenge string) []byte {
 101  	name = NormalizeName(name)
 102  	message := fmt.Sprintf("%s||%s||%d||%d||%s",
 103  		certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
 104  	hash := sha256.Sum256([]byte(message))
 105  	return hash[:]
 106  }
 107  
 108  // ParseTimestampFromProposal extracts the timestamp from a transfer authorization message
 109  // Used for verification when the timestamp is embedded in the signature
 110  func ParseTimestampFromProposal(proposalTime time.Time) time.Time {
 111  	// Round to nearest second for consistency
 112  	return proposalTime.Truncate(time.Second)
 113  }
 114  
 115  // FormatTransferAuthString formats the transfer auth message for display/debugging
 116  func FormatTransferAuthString(name, newOwner string, timestamp time.Time) string {
 117  	name = NormalizeName(name)
 118  	return fmt.Sprintf("transfer:%s:%s:%d", name, newOwner, timestamp.Unix())
 119  }
 120  
 121  // FormatChallengeProofString formats the challenge proof message for display/debugging
 122  func FormatChallengeProofString(challenge, name, certPubkey string, validUntil time.Time) string {
 123  	name = NormalizeName(name)
 124  	return fmt.Sprintf("%s||%s||%s||%d", challenge, name, certPubkey, validUntil.Unix())
 125  }
 126  
 127  // FormatWitnessString formats the witness message for display/debugging
 128  func FormatWitnessString(certPubkey, name string, validFrom, validUntil time.Time, challenge string) string {
 129  	name = NormalizeName(name)
 130  	return fmt.Sprintf("%s||%s||%d||%d||%s",
 131  		certPubkey, name, validFrom.Unix(), validUntil.Unix(), challenge)
 132  }
 133  
 134  // SignProposal signs a registration proposal event
 135  func SignProposal(ev *event.E, s signer.I) error {
 136  	return ev.Sign(s)
 137  }
 138  
 139  // SignAttestation signs an attestation event
 140  func SignAttestation(ev *event.E, s signer.I) error {
 141  	return ev.Sign(s)
 142  }
 143  
 144  // SignTrustGraph signs a trust graph event
 145  func SignTrustGraph(ev *event.E, s signer.I) error {
 146  	return ev.Sign(s)
 147  }
 148  
 149  // SignNameState signs a name state event
 150  func SignNameState(ev *event.E, s signer.I) error {
 151  	return ev.Sign(s)
 152  }
 153  
 154  // SignNameRecord signs a name record event
 155  func SignNameRecord(ev *event.E, s signer.I) error {
 156  	return ev.Sign(s)
 157  }
 158  
 159  // SignCertificate signs a certificate event
 160  func SignCertificate(ev *event.E, s signer.I) error {
 161  	return ev.Sign(s)
 162  }
 163  
 164  // SignWitnessService signs a witness service event
 165  func SignWitnessService(ev *event.E, s signer.I) error {
 166  	return ev.Sign(s)
 167  }
 168