main.go raw

   1  package main
   2  
   3  import (
   4  	"bytes"
   5  	"crypto/rand"
   6  	"crypto/sha256"
   7  	"fmt"
   8  	"log"
   9  
  10  	secp "p8k.mleku.dev"
  11  )
  12  
  13  func main() {
  14  	ctx, err := secp.NewContext(secp.ContextSign | secp.ContextVerify)
  15  	if err != nil {
  16  		log.Fatal(err)
  17  	}
  18  	defer ctx.Destroy()
  19  
  20  	// Generate keys
  21  	privKey := make([]byte, 32)
  22  	if _, err := rand.Read(privKey); err != nil {
  23  		log.Fatal(err)
  24  	}
  25  	originalPubKey, err := ctx.CreatePublicKey(privKey)
  26  	if err != nil {
  27  		log.Fatal(err)
  28  	}
  29  
  30  	// Sign with recovery
  31  	message := []byte("Recover me!")
  32  	msgHash := sha256.Sum256(message)
  33  
  34  	recSig, err := ctx.SignRecoverable(msgHash[:], privKey)
  35  	if err != nil {
  36  		log.Fatal(err)
  37  	}
  38  
  39  	// Serialize to get recovery ID
  40  	sigBytes, recID, err := ctx.SerializeRecoverableSignatureCompact(recSig)
  41  	if err != nil {
  42  		log.Fatal(err)
  43  	}
  44  	fmt.Printf("Signature: %x\n", sigBytes)
  45  	fmt.Printf("Recovery ID: %d\n", recID)
  46  
  47  	// Parse back
  48  	parsedSig, err := ctx.ParseRecoverableSignatureCompact(sigBytes, recID)
  49  	if err != nil {
  50  		log.Fatal(err)
  51  	}
  52  
  53  	// Recover public key
  54  	recoveredPubKey, err := ctx.Recover(parsedSig, msgHash[:])
  55  	if err != nil {
  56  		log.Fatal(err)
  57  	}
  58  
  59  	// Serialize both for comparison
  60  	origSer, err := ctx.SerializePublicKey(originalPubKey, true)
  61  	if err != nil {
  62  		log.Fatal(err)
  63  	}
  64  	recSer, err := ctx.SerializePublicKey(recoveredPubKey, true)
  65  	if err != nil {
  66  		log.Fatal(err)
  67  	}
  68  
  69  	fmt.Printf("Original public key:  %x\n", origSer)
  70  	fmt.Printf("Recovered public key: %x\n", recSer)
  71  	fmt.Printf("Keys match: %v\n", bytes.Equal(origSer, recSer))
  72  }
  73