
# Generate, compare, entropy

> Make a secret, check one without leaking timing, and measure how random something actually looks.

::note
**ELI5.** Three small tools that show up together. `secureGenerate` invents a password or token from real randomness instead of `Math.random()`. `secureCompare` checks a submitted secret against the real one in a way that takes the same time whether the first character is wrong or the last, so an attacker cannot feel their way to the answer one character at a time. `entropy` measures how varied a string looks, which is a useful heuristic for rejecting obvious junk and is not a security guarantee.
::

::card-group
::card{title="secureGenerate()" icon="i-lucide-wand-sparkles" to="/generate/secrets/generate"}
Passwords, tokens and PINs from a CSPRNG, with per-category guarantees.
::
::card{title="secureCompare()" icon="i-lucide-equal" to="/generate/secrets/compare"}
Constant-time comparison that treats untrusted input as a mismatch, not an error.
::
::card{title="entropy()" icon="i-lucide-activity" to="/generate/secrets/entropy"}
Shannon entropy, bigram entropy and monotonic-run detection.
::
::

## How they fit together

```ts
import { secureGenerate } from "unsecure/generate";
import { secureCompare } from "unsecure/compare";
import { entropy } from "unsecure/entropy";

// Make it
const token = secureGenerate({ length: 32, specials: false });

// Sanity-check something a user chose
const { bits, longestRun } = entropy(userSupplied);
if (bits < 60 || longestRun >= 5) reject();

// Check it, later, without leaking where it differs
if (!secureCompare(stored, submitted)) return unauthorized();
```

`entropy()` is a quality gate on human input. `secureCompare()` is a safety property of the check itself. `secureGenerate()` is how you avoid needing the first one at all.
