Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
import { beforeAll, describe, expect, it } from "@suaveplan/testing/runner";
import { sodiumReady } from "../../init/init.js";
import { ristretto255 } from "./ristretto255.js";
describe("ristretto255", () => {
beforeAll(async () => {
await sodiumReady();
}, 30_000);
it("random() produces 32-byte group element", {
timeout: 30_000,
}, async () => {
const p = await ristretto255.random();
expect(p.length).toBe(32);
});
it("random() produces different elements each call", {
timeout: 30_000,
}, async () => {
const p = await ristretto255.random();
const q = await ristretto255.random();
expect(p).not.toEqual(q);
});
it("fromHash() maps 64 bytes to a group element", {
timeout: 30_000,
}, async () => {
const hash = new Uint8Array(64).fill(0x42);
const point = await ristretto255.fromHash(hash);
expect(point.length).toBe(32);
});
it("add(p, q) is commutative: add(p,q) == add(q,p)", {
timeout: 30_000,
}, async () => {
const p = await ristretto255.random();
const q = await ristretto255.random();
const pq = await ristretto255.add(p, q);
const qp = await ristretto255.add(q, p);
expect(pq).toEqual(qp);
});
it("add then sub is identity", { timeout: 30_000 }, async () => {
const p = await ristretto255.random();
const q = await ristretto255.random();
const sum = await ristretto255.add(p, q);
const back = await ristretto255.sub(sum, q);
expect(back).toEqual(p);
});
it("mul scalar*point produces a 32-byte element", {
timeout: 30_000,
}, async () => {
const p = await ristretto255.random();
// Use a small non-zero scalar
const scalar = new Uint8Array(32);
scalar[0] = 2;
const result = await ristretto255.mul(scalar, p);
expect(result.length).toBe(32);
});
it("toBytes returns a copy of the point", { timeout: 30_000 }, async () => {
const p = await ristretto255.random();
const bytes = await ristretto255.toBytes(p);
expect(bytes).toEqual(p);
// Mutation of result doesn't affect original
bytes[0] ^= 0xff;
expect(bytes).not.toEqual(p);
});
it("fromBytes accepts a valid point", { timeout: 30_000 }, async () => {
const p = await ristretto255.random();
const back = await ristretto255.fromBytes(p);
expect(back).toEqual(p);
});
it("fromBytes throws for invalid point", { timeout: 30_000 }, async () => {
// High-bit patterns outside the ristretto255 field are not valid points
const bad = new Uint8Array(32).fill(0xff);
await expect(ristretto255.fromBytes(bad)).rejects.toThrow(RangeError);
});
});