refactor(reef): use Noble byte utilities

This commit is contained in:
Peter Steinberger
2026-07-14 22:18:59 +01:00
parent d252d635e9
commit 243eecbee1
3 changed files with 7 additions and 34 deletions
+3 -9
View File
@@ -1,7 +1,7 @@
import { gcm } from "@noble/ciphers/aes.js";
import { ed25519 } from "@noble/curves/ed25519.js";
import { sha256 } from "@noble/hashes/sha2.js";
import { randomBytes } from "@noble/hashes/utils.js";
import { concatBytes, randomBytes } from "@noble/hashes/utils.js";
import { canonicalBytes, canonicalJson } from "./canonical.js";
import { base64, base64url, decodeUtf8, fromBase64, fromBase64url, hex, utf8 } from "./encoding.js";
@@ -187,10 +187,7 @@ function encryptSensitive(
throw new Error("invalid audit nonce");
}
const ciphertext = gcm(key, nonce).encrypt(utf8(child));
const combined = new Uint8Array(nonce.length + ciphertext.length);
combined.set(nonce);
combined.set(ciphertext, nonce.length);
output[field] = { enc: base64(combined) };
output[field] = { enc: base64(concatBytes(nonce, ciphertext)) };
} else {
output[field] = encryptSensitive(child, key, rng);
}
@@ -230,10 +227,7 @@ function decryptSensitive(value: unknown, key: Uint8Array, field?: string): unkn
function hashEntry(previous: string, event: AuditEvent): string {
const previousBytes = previous === "" ? new Uint8Array() : fromHex(previous);
const eventBytes = canonicalBytes(event);
const combined = new Uint8Array(previousBytes.length + eventBytes.length);
combined.set(previousBytes);
combined.set(eventBytes, previousBytes.length);
return hex(sha256(combined));
return hex(sha256(concatBytes(previousBytes, eventBytes)));
}
function validateAuditKey(key: Uint8Array): Uint8Array {
+2 -20
View File
@@ -1,13 +1,10 @@
const encoder = new TextEncoder();
export { bytesToHex as hex, equalBytes, utf8ToBytes as utf8 } from "@noble/ciphers/utils.js";
const decoder = new TextDecoder("utf-8", { fatal: true });
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
const base64Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
export function utf8(value: string): Uint8Array {
return encoder.encode(value);
}
export function decodeUtf8(value: Uint8Array): string {
return decoder.decode(value);
}
@@ -99,18 +96,3 @@ export function fromBase64(value: string): Uint8Array {
}
return output;
}
export function hex(value: Uint8Array): string {
return Array.from(value, (byte) => byte.toString(16).padStart(2, "0")).join("");
}
export function equalBytes(a: Uint8Array, b: Uint8Array): boolean {
if (a.length !== b.length) {
return false;
}
let difference = 0;
for (let index = 0; index < a.length; index++) {
difference |= a[index]! ^ b[index]!;
}
return difference === 0;
}
+2 -5
View File
@@ -1,7 +1,7 @@
import { mkdir, open as openFile, readFile } from "node:fs/promises";
import { dirname } from "node:path";
import { gcm } from "@noble/ciphers/aes.js";
import { randomBytes } from "@noble/hashes/utils.js";
import { concatBytes, randomBytes } from "@noble/hashes/utils.js";
import { createAuditEntry, verifyChain, type AuditEntry, type AuditStore } from "./audit.js";
import { canonicalBytes } from "./canonical.js";
import { base64, decodeUtf8, fromBase64 } from "./encoding.js";
@@ -293,10 +293,7 @@ function encryptReplayBody(
throw new Error("replay body rng returned invalid nonce");
}
const ciphertext = gcm(key, nonce).encrypt(canonicalBytes(body));
const packed = new Uint8Array(nonce.length + ciphertext.length);
packed.set(nonce);
packed.set(ciphertext, nonce.length);
return { enc: base64(packed) };
return { enc: base64(concatBytes(nonce, ciphertext)) };
}
function decryptReplayBody(body: EncryptedReplayBody, key: Uint8Array): MessageBody {