From 357ecfc2ade1deaf75e5e59eb3437139da47a259 Mon Sep 17 00:00:00 2001 From: Michael Primeaux Date: Wed, 8 Oct 2025 09:02:51 -0500 Subject: [PATCH] debt: Updated dependencies to latest stable versions --- .github/workflows/codeql-analysis.yaml | 6 +- CHANGELOG/CHANGELOG-1.x.md | 17 +++- README.md | 6 +- cmd/generate/generate.go | 15 +++- go.mod | 8 +- go.sum | 16 ++-- .../sixafter/aes-ctr-drbg/aes_ctr_drbg.go | 44 ++++++----- vendor/github.com/sixafter/nanoid/README.md | 20 +++-- vendor/github.com/sixafter/nanoid/config.go | 79 +++++++++++++++---- .../github.com/sixafter/prng-chacha/config.go | 43 ++++++++-- .../github.com/sixafter/prng-chacha/prng.go | 53 +++++++------ vendor/modules.txt | 10 +-- 12 files changed, 219 insertions(+), 98 deletions(-) diff --git a/.github/workflows/codeql-analysis.yaml b/.github/workflows/codeql-analysis.yaml index 8a3f6c5..4b57842 100644 --- a/.github/workflows/codeql-analysis.yaml +++ b/.github/workflows/codeql-analysis.yaml @@ -73,13 +73,13 @@ jobs: # Ref: https://github.com/github/codeql-action - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 diff --git a/CHANGELOG/CHANGELOG-1.x.md b/CHANGELOG/CHANGELOG-1.x.md index be30f33..67ef871 100644 --- a/CHANGELOG/CHANGELOG-1.x.md +++ b/CHANGELOG/CHANGELOG-1.x.md @@ -19,6 +19,20 @@ Date format: `YYYY-MM-DD` --- +## [1.38.0] - 2025-10-08 + +### Added +### Changed +- **debt:** Upgraded dependencies to their latest stable versions. +- **debt:** Updated documentation and Go-doc comments. + +### Deprecated +### Removed +### Fixed +### Security + +--- + ## [1.37.0] - 2025-09-30 ### Added @@ -620,7 +634,8 @@ Date format: `YYYY-MM-DD` ### Fixed ### Security -[Unreleased]: https://github.com/sixafter/nanoid-cli/compare/v1.37.0...HEAD +[Unreleased]: https://github.com/sixafter/nanoid-cli/compare/v1.38.0...HEAD +[1.38.0]: https://github.com/sixafter/nanoid-cli/compare/v1.37.0...v1.38.0 [1.37.0]: https://github.com/sixafter/nanoid-cli/compare/v1.36.0...v1.37.0 [1.36.0]: https://github.com/sixafter/nanoid-cli/compare/v1.35.0...v1.36.0 [1.35.0]: https://github.com/sixafter/nanoid-cli/compare/v1.34.0...v1.35.0 diff --git a/README.md b/README.md index 9059740..a10c257 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,10 @@ using the [NanoID](https://github.com/sixafter/nanoid) Go implementation. To verify the integrity of the release, you can use Cosign to check the signature and checksums. Follow these steps: ```sh -# Fetch the latest release tag from GitHub API (e.g., "v1.36.0") +# Fetch the latest release tag from GitHub API (e.g., "v1.38.0") TAG=$(curl -s https://api.github.com/repos/sixafter/nanoid-cli/releases/latest | jq -r .tag_name) -# Remove leading "v" for filenames (e.g., "v1.36.0" -> "1.36.0") +# Remove leading "v" for filenames (e.g., "v1.38.0" -> "1.38.0") VERSION=${TAG#v} # Verify the release tarball @@ -93,7 +93,7 @@ For casks to work, you'll need curl installed. If you don't have it, you can ins brew install curl ``` -🔐 Note for macOS users: If you see a killed error when running nanoid, macOS may have quarantined the binary due to it being unsigned or unnotarized. To resolve: +**Note for macOS users:** If you see a `killed` error when running nanoid, macOS may have quarantined the binary due to it being unsigned or unnotarized. To resolve: ```sh sudo xattr -d com.apple.quarantine /opt/homebrew/bin/nanoid diff --git a/cmd/generate/generate.go b/cmd/generate/generate.go index 07a7b9e..d0e9ad5 100644 --- a/cmd/generate/generate.go +++ b/cmd/generate/generate.go @@ -19,10 +19,21 @@ import ( ) var ( + // idLength specifies the desired length of the generated ID. + // It determines how many characters the resulting identifier will contain. idLength int + + // alphabet defines the set of characters that can be used when generating IDs. + // It should contain a unique sequence of runes from which random characters are selected. alphabet string - count int - verbose bool + + // count indicates how many IDs to generate during execution. + // Useful for batch operations or performance benchmarking. + count int + + // verbose controls whether detailed diagnostic or progress information is printed. + // When true, additional output such as timing or debug details may be displayed. + verbose bool ) // NewGenerateCommand creates and returns the generate command diff --git a/go.mod b/go.mod index f22939f..449fcc4 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ go 1.25 require ( github.com/dustin/go-humanize v1.0.1 - github.com/sixafter/nanoid v1.52.0 + github.com/sixafter/nanoid v1.53.0 github.com/sixafter/semver v1.9.0 github.com/spf13/cobra v1.10.1 github.com/stretchr/testify v1.11.1 @@ -19,10 +19,10 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/sixafter/aes-ctr-drbg v1.10.0 // indirect - github.com/sixafter/prng-chacha v1.6.0 // indirect + github.com/sixafter/aes-ctr-drbg v1.11.0 // indirect + github.com/sixafter/prng-chacha v1.7.0 // indirect github.com/spf13/pflag v1.0.10 // indirect golang.org/x/crypto v0.42.0 // indirect - golang.org/x/sys v0.36.0 // indirect + golang.org/x/sys v0.37.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 70c6eac..934fea5 100644 --- a/go.sum +++ b/go.sum @@ -10,12 +10,12 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sixafter/aes-ctr-drbg v1.10.0 h1:ZF3HBF9zVKOJHGcuvkjqp1QHYN5kuyYivmhFgO+yCnU= -github.com/sixafter/aes-ctr-drbg v1.10.0/go.mod h1:k0MnzFOGf7ks7ixN/N72wQAT/7u+lIknQWa7H9Iqew4= -github.com/sixafter/nanoid v1.52.0 h1:8eViRdll2B/4g8tOdVuywTeV6ir++GYK5xUCzD3mmMs= -github.com/sixafter/nanoid v1.52.0/go.mod h1:wV91+XpQYVG/ycSZv3PXLyQ9eupYSH0wp9Jhhl6d3jc= -github.com/sixafter/prng-chacha v1.6.0 h1:e0ADGI8dZoV9DRdGCBhtdD3E+iKBoqS4ydtXFu90FrQ= -github.com/sixafter/prng-chacha v1.6.0/go.mod h1:/qgtGyz1ueWauLV6JgIi6a2BNc/9IkLWXL98U2GEM7o= +github.com/sixafter/aes-ctr-drbg v1.11.0 h1:jwWSDZjY+t0Z/DszYc9fGKFva8y28zidKRn8caKwed8= +github.com/sixafter/aes-ctr-drbg v1.11.0/go.mod h1:k0MnzFOGf7ks7ixN/N72wQAT/7u+lIknQWa7H9Iqew4= +github.com/sixafter/nanoid v1.53.0 h1:QdeHnz36hBhrq0h8jE56N8s9+p8X4zwqsFxDs43XcvM= +github.com/sixafter/nanoid v1.53.0/go.mod h1:j5f/yGNQTahmaqaTABynKMV59MBGOL2FIaSLDcxlPDo= +github.com/sixafter/prng-chacha v1.7.0 h1:OJibJp5WE66Ief/xRMg8pKeUGIioJz2CHxY+hoR7kfQ= +github.com/sixafter/prng-chacha v1.7.0/go.mod h1:9oPJR3gITYPCazxNOovPTmkvzG28Snt1TLo+TeFpe3Q= github.com/sixafter/semver v1.9.0 h1:dM8RIBEEpZ0YKzcXA3+rnmmiRES37RYoaeQwtKAe/BQ= github.com/sixafter/semver v1.9.0/go.mod h1:kIkw1gO0r6JtGoOam9xesWKqOFUH8kfTViLVbiC4WmA= github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s= @@ -29,8 +29,8 @@ golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6 h1:SbTAbRFnd5kjQXbczszQ0hdk3ctwYf3qBNH9jIsGclE= golang.org/x/exp v0.0.0-20250813145105-42675adae3e6/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/vendor/github.com/sixafter/aes-ctr-drbg/aes_ctr_drbg.go b/vendor/github.com/sixafter/aes-ctr-drbg/aes_ctr_drbg.go index 7afb1f7..f38c7cf 100644 --- a/vendor/github.com/sixafter/aes-ctr-drbg/aes_ctr_drbg.go +++ b/vendor/github.com/sixafter/aes-ctr-drbg/aes_ctr_drbg.go @@ -131,27 +131,29 @@ func initShardPools(cfg Config) ([]*sync.Pool, error) { return d } } - // If all attempts fail, panic (either for fatal startup or to be caught below). - panic(fmt.Sprintf("ctrdrbg pool init failed after %d retries: %v", capturedCfg.MaxInitRetries, err)) + // If all attempts fail here, we return nil. The eager initialization below + // performs the same construction and will surface a concrete error to the caller. + return nil }, } // Eagerly test pool initialization to ensure catastrophic failures are caught immediately, - // not deferred until first use. If New panics, recover and convert it to an error. - var panicErr error - func() { - defer func() { - if r := recover(); r != nil { - panicErr = fmt.Errorf("ctrdrbg pool initialization failed: %v", r) - } - }() - item := pools[i].Get() - pools[i].Put(item) - }() - - // If initialization panicked, return error immediately. - if panicErr != nil { - return nil, panicErr + // not deferred until first use. Attempt construction directly and return an error on failure. + var ( + warm *drbg + err error + ) + for r := 0; r < capturedCfg.MaxInitRetries; r++ { + if warm, err = newDRBG(&capturedCfg); err == nil { + pools[i].Put(warm) + err = nil + break + } + } + + // If initialization failed, return error immediately. + if err != nil { + return nil, fmt.Errorf("ctrdrbg pool initialization failed after %d retries: %v", capturedCfg.MaxInitRetries, err) } } @@ -1006,9 +1008,9 @@ func newDRBG(cfg *Config) (*drbg, error) { // wrapping both as needed if their lengths exceed the seed length. This process is per NIST SP 800-90A. // // Parameters: -// - seed: The entropy seed buffer to be mixed into (usually key+V). -// - personalization: Optional domain-separation string; XOR-ed into the seed. -// - additionalInput: Optional caller-supplied input; further XOR-ed into the seed. +// - seed: The entropy seed buffer to be mixed into (usually key+V). +// - personalization: Optional domain-separation string; XOR-ed into the seed. +// - additionalInput: Optional caller-supplied input; further XOR-ed into the seed. // // Each byte of personalization and additionalInput is XOR-ed into seed at the corresponding // index, wrapping with modulo if necessary. @@ -1107,7 +1109,7 @@ func (d *drbg) asyncRekey() { // // The counter (V) is treated as a 128-bit unsigned integer in big-endian representation. // Each call increments the counter by one, wrapping as appropriate. This function -// is used for advancing the DRBG keystream per SP 800-90A section on counter mode. +// is used for advancing the DRBG keystream per SP 800-90A section on counter-mode. // Not concurrency safe; caller must synchronize if used from multiple goroutines. // // Parameters: diff --git a/vendor/github.com/sixafter/nanoid/README.md b/vendor/github.com/sixafter/nanoid/README.md index b4a8904..b38f4f9 100644 --- a/vendor/github.com/sixafter/nanoid/README.md +++ b/vendor/github.com/sixafter/nanoid/README.md @@ -45,7 +45,7 @@ Please see the [godoc](https://pkg.go.dev/github.com/sixafter/nanoid) for detail - **Customizable**: - Define your own set of characters for ID generation with a minimum length of 2 characters and maximum length of 256 characters. - Define your own random number generator. - - Unicode and ASCII alphabets supported. + - Unicode and ASCII alphabets are supported. - **Concurrency Safe**: Designed to be safe for use in concurrent environments. - **High Performance**: Optimized with buffer pooling to minimize allocations and enhance speed. - **Optimized for Low Allocations**: Carefully structured to minimize heap allocations, reducing memory overhead and improving cache locality. This optimization is crucial for applications where performance and resource usage are critical. @@ -70,10 +70,10 @@ Please see the [nanoid-cli](https://github.com/sixafter/nanoid-cli) for a comman To verify the integrity of the release, you can use Cosign to check the signature and checksums. Follow these steps: ```sh -# Fetch the latest release tag from GitHub API (e.g., "v1.51.0") +# Fetch the latest release tag from GitHub API (e.g., "v1.53.0") TAG=$(curl -s https://api.github.com/repos/sixafter/nanoid/releases/latest | jq -r .tag_name) -# Remove leading "v" for filenames (e.g., "v1.51.0" -> "1.51.0") +# Remove leading "v" for filenames (e.g., "v1.53.0" -> "1.53.0") VERSION=${TAG#v} # Verify the release tarball @@ -230,7 +230,7 @@ func main() { // Define a custom alphabet alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" - // Create a new generator with custom alphabet and length hint + // Create a new generator with a custom alphabet and length hint gen, err := nanoid.NewGenerator( nanoid.WithAlphabet(alphabet), nanoid.WithLengthHint(10), @@ -272,7 +272,7 @@ import ( ) func main() { - // Create a new generator with custom random number generator + // Create a new generator with a custom random number generator gen, err := nanoid.NewGenerator( nanoid.WithRandReader(rand.Reader), ) @@ -303,6 +303,16 @@ Generated ID: A8I8K3J0QY ## Performance Optimizations +The benchmark summary below highlights the performance optimizations achieved in this implementation of the Nano ID generator. The benchmarks were conducted on an Apple M4 Max CPU with 16 cores, and the results demonstrate significant improvements in latency, throughput, and memory allocations across various configurations. + +| Mode | Latency (ns/op) | Throughput (IDs/sec) | Memory (B/op) | Allocs | Notes | +|:-------------------------------------| --------------: | -------------------: | ------------: | -----: | :-------------------------- | +| **Serial** | 74.1 | ~13.5 M | 24 | 1 | Single-threaded allocation | +| **Parallel (16 cores)** | 5.6 | ~178 M | 24 | 1 | Near-linear scalability | +| **Buffered Read (optimal 3–5 B)** | 25.0 | ~40 M | 0 | 0 | Fastest buffered config | +| **ASCII ID (21 chars)** | 54.0 | ~18.5 M | 0 | 0 | Default configuration | +| **Unicode ID (21 chars)** | 125.0 | ~8.0 M | 48 | 1 | UTF-8 overhead (~2× slower) | + ### Cryptographically Secure Pseudo Random Number Generator (CSPRNG) This project integrates a cryptographically secure, high-performance random number generator (CSPRNG) from [prng-chacha](https://github.com/sixafter/prng-chacha) that can be used for UUIDv4 generation with Google’s UUID library. By replacing the default entropy source with this CSPRNG, UUIDv4 creation is significantly faster in both serial and concurrent workloads, while maintaining cryptographic quality. diff --git a/vendor/github.com/sixafter/nanoid/config.go b/vendor/github.com/sixafter/nanoid/config.go index b0087a8..8c74eca 100644 --- a/vendor/github.com/sixafter/nanoid/config.go +++ b/vendor/github.com/sixafter/nanoid/config.go @@ -236,24 +236,69 @@ func WithAutoRandReader() Option { } } -// runtimeConfig holds the runtime configuration for the Nano ID generator. -// It is immutable after initialization. +// runtimeConfig defines the immutable runtime parameters used by the Nano ID generator. +// +// It encapsulates all precomputed values derived from the user-provided configuration, +// such as alphabet characteristics, entropy requirements, and scaling multipliers. +// Once initialized, instances of runtimeConfig are treated as read-only and safe for +// concurrent access by multiple generator instances. type runtimeConfig struct { - randReader io.Reader // 16 bytes - byteAlphabet []byte // 24 bytes - runeAlphabet []rune // 24 bytes - mask uint // 8 bytes - bitsNeeded uint // 8 bytes - bytesNeeded uint // 8 bytes - bufferSize int // 8 bytes - bufferMultiplier int // 8 bytes - scalingFactor int // 8 bytes - baseMultiplier int // 8 bytes - maxBytesPerRune int // 8 bytes - alphabetLen uint16 // 2 bytes - lengthHint uint16 // 2 bytes - isASCII bool // 1 byte - isPowerOfTwo bool // 1 byte + // randReader provides the source of randomness used to generate IDs. + // Typically a cryptographically secure source such as crypto/rand.Reader. + randReader io.Reader + + // byteAlphabet contains the alphabet encoded as bytes for fast lookup + // when generating ASCII-based IDs. + byteAlphabet []byte + + // runeAlphabet holds the alphabet as runes, allowing full Unicode support + // when non-ASCII alphabets are used. + runeAlphabet []rune + + // mask is the bitmask applied to random bytes to constrain values within + // the alphabet length for efficient uniform selection. + mask uint + + // bitsNeeded represents the number of bits of entropy required to select + // a single character from the alphabet. + bitsNeeded uint + + // bytesNeeded defines the number of random bytes consumed to generate one ID. + bytesNeeded uint + + // bufferSize specifies the size of the internal random buffer used when + // reading entropy in bulk for performance. + bufferSize int + + // bufferMultiplier controls how many times the buffer may be reused before + // refilling from the random source, optimizing throughput for short IDs. + bufferMultiplier int + + // scalingFactor defines a scaling coefficient used to calculate how many + // random bytes are required relative to the target ID length. + scalingFactor int + + // baseMultiplier is a precomputed factor used to adjust scaling under + // non–power-of-two alphabets for uniform distribution. + baseMultiplier int + + // maxBytesPerRune specifies the maximum number of bytes required to encode + // a single rune from the alphabet, relevant for mixed-width alphabets. + maxBytesPerRune int + + // alphabetLen stores the total number of characters in the effective alphabet. + alphabetLen uint16 + + // lengthHint provides the default or expected length for generated IDs, + // aiding in preallocation and throughput optimization. + lengthHint uint16 + + // isASCII indicates whether the alphabet is composed entirely of ASCII characters. + isASCII bool + + // isPowerOfTwo marks whether the alphabet length is a power of two, + // allowing bitmask optimizations for uniform selection. + isPowerOfTwo bool } func buildRuntimeConfig(opts *ConfigOptions) (*runtimeConfig, error) { diff --git a/vendor/github.com/sixafter/prng-chacha/config.go b/vendor/github.com/sixafter/prng-chacha/config.go index 06724e1..c55b1df 100644 --- a/vendor/github.com/sixafter/prng-chacha/config.go +++ b/vendor/github.com/sixafter/prng-chacha/config.go @@ -85,11 +85,41 @@ type Config struct { // Default configuration constants for ChaCha20-PRNG. const ( - maxRekeyAttempts = 5 // Default max rekey attempts - rekeyBackoff = 100 * time.Millisecond // Default initial rekey backoff (100 ms) - maxRekeyBackoff = 2 * time.Second // Default max backoff for rekey (2 seconds) - maxBytesPerKey = 1 << 30 // Default max bytes per key (1 GiB) - defaultBufferSize = 64 // Default internal buffer size for XOR operations + // maxRekeyAttempts is the default maximum number of attempts to perform + // an asynchronous rekey operation before giving up. + // + // Rekey attempts are retried with exponential backoff (bounded by + // maxRekeyBackoff). Increasing this value makes the implementation more + // persistent when transient failures occur during key rotation. + maxRekeyAttempts = 5 + + // rekeyBackoff is the default initial backoff duration used when retrying + // failed rekey operations. + // + // The backoff doubles on each subsequent failure until the duration is + // clamped by maxRekeyBackoff. This value is small by default to allow + // quick recovery while avoiding tight busy loops. + rekeyBackoff = 100 * time.Millisecond + + // maxRekeyBackoff is the maximum backoff duration for exponential rekey retries. + // + // Backoff grows from rekeyBackoff up to this ceiling. This protects systems + // from unbounded retry delays while still allowing backoff escalation. + maxRekeyBackoff = 2 * time.Second + + // maxBytesPerKey is the default maximum number of output bytes produced + // per key/nonce pair before triggering an automatic rekey. + // + // Enforcing a maximum output window per key provides forward secrecy + // properties by limiting the amount of data encrypted with a single key. + // The default is 1 GiB. + maxBytesPerKey = 1 << 30 + + // defaultBufferSize is the default size (in bytes) of the internal zero-filled + // buffer used when UseZeroBuffer is enabled for XORKeyStream operations. + // + // This value offers a modest, cache-friendly buffer for common read sizes. + defaultBufferSize = 64 ) // DefaultConfig returns a Config struct populated with production-safe, recommended defaults. @@ -117,7 +147,8 @@ func DefaultConfig() Config { UseZeroBuffer: false, EnableKeyRotation: false, DefaultBufferSize: defaultBufferSize, - // Ref: Use of GOMAXPROCS is fine for now: https://github.com/golang/go/issues/73193 + // Use of GOMAXPROCS is CPU limit-aware. + // Ref: https://github.com/golang/go/issues/73193 Shards: runtime.GOMAXPROCS(0), } } diff --git a/vendor/github.com/sixafter/prng-chacha/prng.go b/vendor/github.com/sixafter/prng-chacha/prng.go index cb5e7ff..0b778c7 100644 --- a/vendor/github.com/sixafter/prng-chacha/prng.go +++ b/vendor/github.com/sixafter/prng-chacha/prng.go @@ -38,20 +38,29 @@ import ( // fmt.Printf("Read %d bytes of random data: %x\n", n, buffer) var Reader io.Reader -// Interface defines the contract for a ChaCha20-based cryptographically secure PRNG source. +// Interface defines the contract for a ChaCha20-based cryptographically secure +// pseudorandom number generator (PRNG). // -// Implementations satisfy io.Reader and provide access to the non-secret, immutable -// configuration in effect for the PRNG pool or instance. +// Implementations of Interface provide a thread-safe source of cryptographically +// strong random bytes derived from the ChaCha20 stream cipher. Each implementation +// must also satisfy the io.Reader interface, making it compatible with standard +// Go APIs that consume randomness (e.g., encoding, crypto, and token generation). // // All methods are safe for concurrent use unless otherwise noted. // -// The Config() method returns a copy of the PRNG configuration, allowing callers to -// inspect operational settings without risk of secret or mutable state exposure. +// The Config method allows callers to retrieve a copy of the immutable, +// non-secret configuration associated with the PRNG instance. This enables +// inspection of operational parameters—such as nonce, pool size, or reseed +// interval—without exposing any sensitive key material or mutable internal state. type Interface interface { io.Reader - // Config returns a copy of the PRNG configuration for this source. - // The returned Config omits any secrets or internal runtime state. + // Config returns a copy of the PRNG configuration in effect for this source. + // + // The returned Config contains only non-secret, immutable parameters and + // omits any runtime state or cryptographic keys. Callers may safely inspect + // the returned value to determine operational behavior without risk of + // secret exposure or race conditions. Config() Config } @@ -148,7 +157,7 @@ func NewReader(opts ...Option) (Interface, error) { // Step 2: Construct a sync.Pool for managing reusable prng instances. // The pool's New function attempts to construct a new *prng, // retrying up to cfg.MaxInitRetries times in case of failure (e.g., low entropy). - // If all attempts fail, the function panics—making the error immediately visible to the developer. + // If all attempts fail, the function returns nil, which is caught during eager initialization below. pools := make([]*sync.Pool, cfg.Shards) for i := range pools { cfg := cfg // Capture the current configuration for this shard @@ -163,28 +172,26 @@ func NewReader(opts ...Option) (Interface, error) { return p } } - // If initialization fails after all retries, panic. - panic(fmt.Sprintf("prng pool init failed after %d retries: %v", cfg.MaxInitRetries, err)) + // If initialization fails after all retries, return nil instead of panicking. + // The eager initialization step below will detect and return this as an error. + return nil }, } // Step 3: Eagerly test the pool initialization to ensure that any catastrophic // failure is caught immediately, not deferred to the first use. - // This triggers pool.New, which may panic on failure. The panic is recovered and stored as an error. - var panicErr error - func() { - defer func() { - if r := recover(); r != nil { - panicErr = fmt.Errorf("prng pool initialization failed: %v", r) - } - }() - item := pools[i].Get().(*prng) + // This triggers pool.New, which may return nil on failure. Any nil value is converted to an error. + var initErr error + item := pools[i].Get() + if item == nil { + initErr = fmt.Errorf("prng pool initialization failed after %d retries", cfg.MaxInitRetries) + } else { pools[i].Put(item) - }() + } - // Step 4: If initialization failed with a panic, return it as an error. - if panicErr != nil { - return nil, panicErr + // Step 4: If initialization failed, return it as an error. + if initErr != nil { + return nil, initErr } } diff --git a/vendor/modules.txt b/vendor/modules.txt index f23e59d..9742d5c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -10,13 +10,13 @@ github.com/inconshreveable/mousetrap # github.com/pmezard/go-difflib v1.0.0 ## explicit github.com/pmezard/go-difflib/difflib -# github.com/sixafter/aes-ctr-drbg v1.10.0 +# github.com/sixafter/aes-ctr-drbg v1.11.0 ## explicit; go 1.25 github.com/sixafter/aes-ctr-drbg -# github.com/sixafter/nanoid v1.52.0 +# github.com/sixafter/nanoid v1.53.0 ## explicit; go 1.25 github.com/sixafter/nanoid -# github.com/sixafter/prng-chacha v1.6.0 +# github.com/sixafter/prng-chacha v1.7.0 ## explicit; go 1.25 github.com/sixafter/prng-chacha # github.com/sixafter/semver v1.9.0 @@ -28,7 +28,7 @@ github.com/spf13/cobra # github.com/spf13/pflag v1.0.10 ## explicit; go 1.12 github.com/spf13/pflag -# github.com/stretchr/objx v0.5.2 +# github.com/stretchr/objx v0.5.3 ## explicit; go 1.20 # github.com/stretchr/testify v1.11.1 ## explicit; go 1.17 @@ -38,7 +38,7 @@ github.com/stretchr/testify/assert/yaml ## explicit; go 1.24.0 golang.org/x/crypto/chacha20 golang.org/x/crypto/internal/alias -# golang.org/x/sys v0.36.0 +# golang.org/x/sys v0.37.0 ## explicit; go 1.24.0 golang.org/x/sys/cpu # gopkg.in/yaml.v3 v3.0.1