package pow import ( "crypto/rand" "time" ) // Generator handles creation of PoW challenges with HMAC signing type Generator struct { config *Config } // GenerateOption represents a functional option for challenge generation type generateOption func(*Challenge) // WithDifficulty sets custom difficulty for the challenge func WithDifficulty(difficulty int) generateOption { return func(c *Challenge) { c.Difficulty = difficulty } } // NewGenerator creates a new challenge generator func NewGenerator(config *Config) *Generator { return &Generator{ config: config, } } // GenerateChallenge creates a new HMAC-signed PoW challenge func (g *Generator) GenerateChallenge(opts ...generateOption) (*Challenge, error) { // Create challenge with defaults (no random data yet) challenge := &Challenge{ Timestamp: time.Now().Unix(), Difficulty: g.config.DefaultDifficulty, Resource: g.config.Resource, } // Apply options for _, opt := range opts { opt(challenge) } // Validate difficulty bounds if challenge.Difficulty < g.config.MinDifficulty || challenge.Difficulty > g.config.MaxDifficulty { return nil, ErrInvalidDifficulty } // Generate cryptographic random data challenge.Random = g.generateRandom(g.config.RandomBytes) // Sign the challenge with HMAC challenge.Sign(g.config.HMACSecret) return challenge, nil } // generateRandom creates cryptographic random bytes func (g *Generator) generateRandom(length int) []byte { bytes := make([]byte, length) rand.Read(bytes) return bytes }