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