Big Updated, added some tests, added comments for all functions, I forgot the rest
This commit is contained in:
parent
d77271e4b7
commit
90a1059cc8
59 changed files with 1816 additions and 203 deletions
88
packages/crypto/src/worker.test.ts
Normal file
88
packages/crypto/src/worker.test.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { x448 } from "@noble/curves/ed448.js";
|
||||
import { decrypt, encrypt, getSharedSecret } from "./worker";
|
||||
|
||||
/**
|
||||
* Encodes bytes to URL-safe base64 without padding.
|
||||
* @param value Input bytes.
|
||||
* @returns Base64url string.
|
||||
*/
|
||||
function bytesToB64u(value: Uint8Array): string {
|
||||
const b64 = Buffer.from(value).toString("base64");
|
||||
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts bytes to lowercase hex.
|
||||
* @param value Input bytes.
|
||||
* @returns Hex string.
|
||||
*/
|
||||
function bytesToHex(value: Uint8Array): string {
|
||||
return Array.from(value, (byte) => byte.toString(16).padStart(2, "0")).join(
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates deterministic 56-byte private key material for tests.
|
||||
* @param seed Offset seed used to vary generated bytes.
|
||||
* @returns Deterministic private key bytes.
|
||||
*/
|
||||
function createPrivateKey(seed: number): Uint8Array {
|
||||
const output = new Uint8Array(56);
|
||||
|
||||
for (let index = 0; index < output.length; index += 1) {
|
||||
output[index] = (seed + index) % 255;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
describe("crypto worker", () => {
|
||||
test("encrypt/decrypt round-trip returns original plaintext", async () => {
|
||||
const secret = "a1".repeat(56);
|
||||
const plaintext = "hello encrypted world";
|
||||
|
||||
const ciphertext = await encrypt(secret, plaintext);
|
||||
const decrypted = await decrypt(secret, ciphertext);
|
||||
|
||||
expect(decrypted).toBe(plaintext);
|
||||
});
|
||||
|
||||
test("decrypt fails with wrong shared secret", async () => {
|
||||
const secret = "0f".repeat(56);
|
||||
const wrongSecret = "f0".repeat(56);
|
||||
const plaintext = "sensitive";
|
||||
|
||||
const ciphertext = await encrypt(secret, plaintext);
|
||||
|
||||
let failed = false;
|
||||
try {
|
||||
await decrypt(wrongSecret, ciphertext);
|
||||
} catch {
|
||||
failed = true;
|
||||
}
|
||||
|
||||
expect(failed).toBe(true);
|
||||
});
|
||||
|
||||
test("getSharedSecret matches noble x448 derivation", async () => {
|
||||
const ownPrivateBytes = createPrivateKey(7);
|
||||
const peerPrivateBytes = createPrivateKey(23);
|
||||
|
||||
const ownPublicBytes = x448.getPublicKey(ownPrivateBytes);
|
||||
const peerPublicBytes = x448.getPublicKey(peerPrivateBytes);
|
||||
|
||||
const expected = bytesToHex(
|
||||
new Uint8Array(x448.getSharedSecret(ownPrivateBytes, peerPublicBytes)),
|
||||
);
|
||||
|
||||
const actual = await getSharedSecret(
|
||||
bytesToB64u(ownPrivateBytes),
|
||||
bytesToB64u(ownPublicBytes),
|
||||
bytesToB64u(peerPublicBytes),
|
||||
);
|
||||
|
||||
expect(actual).toBe(expected);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue