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