first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
# primitives/ristretto255
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `ristretto255` namespace exposes libsodium's Ristretto255 group operations — a prime-order group construction over Curve25519 that eliminates the cofactor pitfalls present in raw Edwards25519 arithmetic. Ristretto255 is used in zero-knowledge proofs, Oblivious Pseudorandom Functions (OPRFs), Password-Authenticated Key Exchanges (PAKEs), and Verifiable Random Functions (VRFs).
By wrapping libsodium's `crypto_core_ristretto255_*` and `crypto_scalarmult_ristretto255_*` APIs, this module provides the building blocks for advanced cryptographic protocols without requiring callers to reason about low-level curve arithmetic or cofactor clearing.
## Features
- Group element addition (`add`) and subtraction (`sub`) via `crypto_core_ristretto255_add/sub`.
- Scalar multiplication (`mul`) via `crypto_scalarmult_ristretto255`.
- Hash-to-curve via `fromHash` using `crypto_core_ristretto255_from_hash` (64-byte input).
- Point serialisation (`toBytes`) and deserialisation with validation (`fromBytes`).
- Random group element generation (`random`) via `crypto_core_ristretto255_random`.
- All operations are async and call `sodiumReady()` internally.
- `fromBytes` throws `RangeError` for invalid or identity points.
## Usage: Basic Example
```ts
import { ristretto255 } from "@suaveplan/crypto-sodium/primitives/ristretto255";
// Generate two random group elements
const p = await ristretto255.random();
const q = await ristretto255.random();
// Add them
const sum = await ristretto255.add(p, q);
// Verify commutativity
const sumQP = await ristretto255.add(q, p);
// sum deepEquals sumQP
```
## Usage: Advanced Example
Hash-to-curve for OPRF input blinding:
```ts
import { ristretto255 } from "@suaveplan/crypto-sodium/primitives/ristretto255";
// Hash the password to a group element (hash-to-curve)
// In a real OPRF you'd use a proper H2C function; fromHash works for demos
async function hashToPoint(input: Uint8Array): Promise<Uint8Array> {
// Pad/hash input to 64 bytes with SHA-512 first in production:
const padded = new Uint8Array(64);
padded.set(input.subarray(0, Math.min(input.length, 64)));
return ristretto255.fromHash(padded);
}
// Scalar multiplication: client blinds the point with a random scalar
const blindScalar = new Uint8Array(32);
crypto.getRandomValues(blindScalar);
const point = await hashToPoint(new TextEncoder().encode("password"));
const blinded = await ristretto255.mul(blindScalar, point);
```
## API Reference
### `ristretto255.add(p, q): Promise<Uint8Array>`
Adds two group elements. Commutative: `add(p, q) === add(q, p)`.
### `ristretto255.sub(p, q): Promise<Uint8Array>`
Subtracts `q` from `p`. Inverse of `add`.
### `ristretto255.mul(scalar, point): Promise<Uint8Array>`
Scalar multiplication: computes `scalar * point`. Scalar is a 32-byte little-endian integer.
### `ristretto255.fromHash(hash): Promise<Uint8Array>`
Maps a 64-byte hash uniformly to a group element via `crypto_core_ristretto255_from_hash`.
### `ristretto255.toBytes(point): Promise<Uint8Array>`
Returns a copy of the 32-byte canonical encoding of `point`.
### `ristretto255.fromBytes(bytes): Promise<Uint8Array>`
Validates and returns a group element. **Throws `RangeError`** if `bytes` is not a valid, non-identity Ristretto255 point.
### `ristretto255.random(): Promise<Uint8Array>`
Generates a uniformly random 32-byte group element.
## Implementation Notes
Ristretto255 represents each group element as a 32-byte canonical encoding. Unlike raw Edwards25519, every 32-byte encoding maps to at most one group element — there are no encoding ambiguities or cofactor issues.
`fromBytes` calls `crypto_core_ristretto255_is_valid_point` before returning, which rejects the identity element (all-zeros) and any bytes that do not correspond to a valid Ristretto255 point. This prevents callers from accidentally working with invalid inputs in downstream protocols.
All operations return new `Uint8Array` allocations; the input arrays are not mutated.