package deviceauth import ( "context" "crypto/sha256" "encoding/hex" "time" "github.com/redis/go-redis/v9" ) type ReplayGuard interface { Claim(context.Context, string, string, time.Duration) (bool, error) } type RedisReplayGuard struct { client *redis.Client prefix string } func NewRedisReplayGuard(client *redis.Client, prefix string) *RedisReplayGuard { return &RedisReplayGuard{client: client, prefix: prefix} } func (g *RedisReplayGuard) Claim(ctx context.Context, deviceID, nonce string, ttl time.Duration) (bool, error) { digest := sha256.Sum256([]byte(deviceID + "\x00" + nonce)) key := g.prefix + ":device-nonce:" + hex.EncodeToString(digest[:16]) return g.client.SetNX(ctx, key, "1", ttl).Result() }