first commit
This commit is contained in:
58
docs/security-stack/security/otp/src/hotp/encode-counter.md
Normal file
58
docs/security-stack/security/otp/src/hotp/encode-counter.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# `hotp/encode-counter`
|
||||
|
||||
## Purpose
|
||||
|
||||
Encode an HOTP counter as the 8-byte big-endian block required by RFC 4226
|
||||
§5.1. `bigint` is the canonical input type because `Number` loses precision
|
||||
past `2^53` and the RFC permits counters up to `2^64 − 1`. Shared by HOTP
|
||||
itself, by OCRA's optional `C` directive, and by OCRA's `T` timestamp block
|
||||
(which is also written as an 8-byte big-endian integer per RFC 6287 §5.1).
|
||||
|
||||
## Features
|
||||
|
||||
- BigInt input — no precision loss across the full 0..2^64-1 range.
|
||||
- Range guard: negative counters and counters past `2^64-1` raise
|
||||
`OtpError(OTP.INVALID_OPTIONS)`.
|
||||
- Pure: returns a freshly-allocated `Uint8Array(8)` per call.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { encodeCounter } from "@suaveplan/otp";
|
||||
|
||||
const block = encodeCounter(1n);
|
||||
// block === Uint8Array([0, 0, 0, 0, 0, 0, 0, 1])
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { encodeCounter } from "@suaveplan/otp";
|
||||
|
||||
// Counter past Number.MAX_SAFE_INTEGER round-trips losslessly.
|
||||
const block = encodeCounter((1n << 53n) + 1n);
|
||||
// `block` is exactly 8 bytes; the high bytes carry the counter's high bits.
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `encodeCounter(counter: bigint): Uint8Array` — returns an 8-byte
|
||||
big-endian block. Negative input raises `OtpError(OTP.INVALID_OPTIONS)`;
|
||||
values >= 2^64 raise the same code.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The function loops from byte index 7 back to 0 shifting `counter` right by 8
|
||||
bits each step. The mask `0xffn` keeps the operation inside the `bigint`
|
||||
domain so no implicit `Number` conversion can lose precision. The function
|
||||
is the single source of truth for big-endian counter framing — both HOTP and
|
||||
OCRA route through it so any future endianness change propagates atomically.
|
||||
|
||||
The upper-bound check `counter > MAX_U64` catches the niche case where a
|
||||
caller passes a programmatically-generated counter past the RFC 4226
|
||||
limit. Without the check the encoder would silently truncate the high
|
||||
bits and produce two distinct counters that hash to the same byte block,
|
||||
which would silently break the per-counter uniqueness invariant HOTP
|
||||
relies on. The lower-bound check on negative counters covers the
|
||||
symmetric case for callers who derive counters via `BigInt()` arithmetic
|
||||
that may go negative under bug conditions.
|
||||
Reference in New Issue
Block a user