context.go raw
1 package p256k1
2
3 import (
4 "crypto/rand"
5 "errors"
6 )
7
8 // Context flags
9 const (
10 ContextSign = 1 << 0
11 ContextVerify = 1 << 1
12 ContextNone = 0
13 )
14
15 // Context represents a secp256k1 context
16 type Context struct {
17 flags uint
18 ecmultGenCtx *EcmultGenContext
19 // In a real implementation, this would also contain:
20 // - ecmult context for verification
21 // - callback functions
22 // - randomization state
23 }
24
25 // CallbackFunction represents an error callback
26 type CallbackFunction func(message string, data interface{})
27
28 // Default callback that panics on illegal arguments
29 func defaultIllegalCallback(message string, data interface{}) {
30 panic("illegal argument: " + message)
31 }
32
33 // Default callback that panics on errors
34 func defaultErrorCallback(message string, data interface{}) {
35 panic("error: " + message)
36 }
37
38 // ContextCreate creates a new secp256k1 context
39 func ContextCreate(flags uint) *Context {
40 ctx := &Context{
41 flags: flags,
42 }
43
44 // Initialize generator context if needed for signing
45 if flags&ContextSign != 0 {
46 ctx.ecmultGenCtx = NewEcmultGenContext()
47 }
48
49 // Initialize verification context if needed
50 if flags&ContextVerify != 0 {
51 // In a real implementation, this would initialize ecmult tables
52 }
53
54 return ctx
55 }
56
57 // ContextDestroy destroys a secp256k1 context
58 func ContextDestroy(ctx *Context) {
59 if ctx == nil {
60 return
61 }
62
63 // Clear sensitive data
64 if ctx.ecmultGenCtx != nil {
65 // Clear generator context
66 ctx.ecmultGenCtx.initialized = false
67 }
68
69 // Zero out the context
70 ctx.flags = 0
71 ctx.ecmultGenCtx = nil
72 }
73
74 // ContextRandomize randomizes the context to provide protection against side-channel attacks
75 func ContextRandomize(ctx *Context, seed32 []byte) error {
76 if ctx == nil {
77 return errors.New("context cannot be nil")
78 }
79
80 var seedBytes [32]byte
81
82 if seed32 != nil {
83 if len(seed32) != 32 {
84 return errors.New("seed must be 32 bytes")
85 }
86 copy(seedBytes[:], seed32)
87 } else {
88 // Generate random seed
89 if _, err := rand.Read(seedBytes[:]); err != nil {
90 return err
91 }
92 }
93
94 // In a real implementation, this would:
95 // 1. Randomize the precomputed tables
96 // 2. Add blinding to prevent side-channel attacks
97 // 3. Update the context state
98
99 // For now, we just validate the input
100 return nil
101 }
102
103 // Global static context (read-only, for verification only)
104 var ContextStatic = &Context{
105 flags: ContextVerify,
106 ecmultGenCtx: nil, // No signing capability
107 }
108
109 // Helper functions for argument checking
110
111 // argCheck checks a condition and calls the illegal callback if false
112 func (ctx *Context) argCheck(condition bool, message string) bool {
113 if !condition {
114 defaultIllegalCallback(message, nil)
115 return false
116 }
117 return true
118 }
119
120 // argCheckVoid is like argCheck but for void functions
121 func (ctx *Context) argCheckVoid(condition bool, message string) {
122 if !condition {
123 defaultIllegalCallback(message, nil)
124 }
125 }
126
127 // Capability checking
128
129 // canSign returns true if the context can be used for signing
130 func (ctx *Context) canSign() bool {
131 return ctx != nil && (ctx.flags&ContextSign) != 0 && ctx.ecmultGenCtx != nil
132 }
133
134 // canVerify returns true if the context can be used for verification
135 func (ctx *Context) canVerify() bool {
136 return ctx != nil && (ctx.flags&ContextVerify) != 0
137 }
138