Published source
Download source ZIP
CH-J Server Manager
Browse directories and files for a specific application release.
Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.
1
"use strict";3
const CATEGORIES = Object.freeze({4
recommended: "Recommended / Cryptographic",5
xof: "XOF",6
legacy: "Legacy Cryptographic",7
broken: "Broken / Compatibility only",8
fast: "Fast non-cryptographic",9
checksums: "Checksums"10
});12
const definitions = [13
["sha224", "SHA-224", "legacy", 224, "node-crypto"],14
["sha256", "SHA-256", "recommended", 256, "node-crypto"],15
["sha384", "SHA-384", "recommended", 384, "node-crypto"],16
["sha512", "SHA-512", "recommended", 512, "node-crypto"],17
["sha512-224", "SHA-512/224", "recommended", 224, "noble-hashes"],18
["sha512-256", "SHA-512/256", "recommended", 256, "node-crypto"],19
["sha3-224", "SHA3-224", "recommended", 224, "noble-hashes"],20
["sha3-256", "SHA3-256", "recommended", 256, "noble-hashes"],21
["sha3-384", "SHA3-384", "recommended", 384, "noble-hashes"],22
["sha3-512", "SHA3-512", "recommended", 512, "noble-hashes"],23
["shake128", "SHAKE128", "xof", null, "noble-hashes", { xof: { defaultBytes: 32, minBytes: 16, maxBytes: 1024 } }],24
["shake256", "SHAKE256", "xof", null, "noble-hashes", { xof: { defaultBytes: 64, minBytes: 16, maxBytes: 1024 } }],25
["blake2b-512", "BLAKE2b-512", "recommended", 512, "noble-hashes"],26
["blake2s-256", "BLAKE2s-256", "recommended", 256, "noble-hashes"],27
["blake3", "BLAKE3", "recommended", 256, "hash-wasm"],28
["kangaroo-twelve", "KangarooTwelve", "xof", null, "noble-hashes", { xof: { defaultBytes: 32, minBytes: 16, maxBytes: 1024 } }],29
["ripemd160", "RIPEMD-160", "legacy", 160, "node-crypto"],30
["whirlpool", "Whirlpool", "legacy", 512, "hash-wasm"],31
["tiger", "Tiger", "legacy", 192, "bundled-js"],32
["tiger2", "Tiger2", "legacy", 192, "bundled-js"],33
["md5", "MD5", "broken", 128, "node-crypto"],34
["sha1", "SHA-1", "broken", 160, "node-crypto"],35
["xxh32", "XXH32", "fast", 32, "hash-wasm", { seeded: true, seedBits: 32 }],36
["xxh64", "XXH64", "fast", 64, "hash-wasm", { seeded: true, seedBits: 64 }],37
["xxh3-64", "XXH3-64", "fast", 64, "hash-wasm", { seeded: true, seedBits: 64 }],38
["xxh3-128", "XXH3-128", "fast", 128, "hash-wasm", { seeded: true, seedBits: 64 }],39
["murmur3-x86-32", "MurmurHash3 x86 32", "fast", 32, "bundled-js", { seeded: true, seedBits: 32 }],40
["murmur3-x86-128", "MurmurHash3 x86 128", "fast", 128, "bundled-js", { seeded: true, seedBits: 32 }],41
["murmur3-x64-128", "MurmurHash3 x64 128", "fast", 128, "bundled-js", { seeded: true, seedBits: 32 }],42
["cityhash32", "CityHash32", "fast", 32, "bundled-js", { randomAccess: true }],43
["cityhash64", "CityHash64", "fast", 64, "bundled-js", { randomAccess: true }],44
["cityhash128", "CityHash128", "fast", 128, "bundled-js", { randomAccess: true }],45
["farmhash32", "FarmHash32", "fast", 32, "farmhashjs", { randomAccess: true }],46
["farmhash64", "FarmHash64", "fast", 64, "farmhashjs", { randomAccess: true }],47
["farmhash128", "FarmHash128", "fast", 128, "bundled-js", { randomAccess: true }],48
["highwayhash64", "HighwayHash64", "fast", 64, "highwayhasher", { keyed: true, keyBytes: 32 }],49
["highwayhash128", "HighwayHash128", "fast", 128, "highwayhasher", { keyed: true, keyBytes: 32 }],50
["highwayhash256", "HighwayHash256", "fast", 256, "highwayhasher", { keyed: true, keyBytes: 32 }],51
["siphash-2-4", "SipHash-2-4", "fast", 64, "bundled-js", { keyed: true, keyBytes: 16 }],52
["fnv1-32", "FNV-1 32", "fast", 32, "bundled-js"],53
["fnv1-64", "FNV-1 64", "fast", 64, "bundled-js"],54
["fnv1a-32", "FNV-1a 32", "fast", 32, "bundled-js"],55
["fnv1a-64", "FNV-1a 64", "fast", 64, "bundled-js"],56
["crc16-ccitt-false", "CRC-16/CCITT-FALSE", "checksums", 16, "bundled-js", { parameters: "poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000" }],57
["crc32", "CRC-32/ISO-HDLC", "checksums", 32, "hash-wasm", { parameters: "poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff" }],58
["crc32c", "CRC-32C/Castagnoli", "checksums", 32, "hash-wasm", { parameters: "poly=0x1edc6f41 init=0xffffffff refin=true refout=true xorout=0xffffffff" }],59
["crc64-ecma", "CRC-64/ECMA-182", "checksums", 64, "bundled-js", { parameters: "poly=0x42f0e1eba9ea3693 init=0 refin=false refout=false xorout=0" }],60
["crc64-xz", "CRC-64/XZ", "checksums", 64, "bundled-js", { parameters: "poly=0x42f0e1eba9ea3693 init=all-ones refin=true refout=true xorout=all-ones" }],61
["adler32", "Adler-32", "checksums", 32, "hash-wasm"]62
];64
const ALGORITHMS = Object.freeze(definitions.map(([id, name, category, digestBits, backend, extra = {}]) => Object.freeze({65
id,66
name,67
category,68
categoryName: CATEGORIES[category],69
digestBits,70
backend,71
cryptographic: category === "recommended" || category === "xof" || category === "legacy" || category === "broken",72
securityStatus: category === "broken" ? "broken" : (category === "fast" || category === "checksums" ? "non-cryptographic" : "cryptographic"),73
supportsStreaming: !extra.randomAccess,74
...extra75
})));76
const BY_ID = new Map(ALGORITHMS.map((algorithm) => [algorithm.id, algorithm]));78
function getAlgorithms() {79
return ALGORITHMS.map((algorithm) => ({ ...algorithm, xof: algorithm.xof ? { ...algorithm.xof } : undefined }));80
}82
function normalizeAlgorithmRequests(input) {83
if (!Array.isArray(input) || input.length < 1 || input.length > ALGORITHMS.length) throw typedError("Select between one and all supported algorithms.", "HASH_INVALID_ALGORITHMS");84
const seen = new Set();85
return input.map((source) => {86
const request = typeof source === "string" ? { id: source } : source;87
const algorithm = BY_ID.get(String(request?.id || ""));88
if (!algorithm || seen.has(algorithm.id)) throw typedError(`Unsupported or duplicate algorithm: ${request?.id || "<empty>"}`, "HASH_UNSUPPORTED_ALGORITHM");89
seen.add(algorithm.id);90
const result = { id: algorithm.id };91
if (algorithm.xof) {92
const outputBytes = Number(request.outputBytes ?? algorithm.xof.defaultBytes);93
if (!Number.isSafeInteger(outputBytes) || outputBytes < algorithm.xof.minBytes || outputBytes > algorithm.xof.maxBytes) {94
throw typedError(`${algorithm.name} output must be ${algorithm.xof.minBytes}-${algorithm.xof.maxBytes} bytes.`, "HASH_INVALID_XOF_LENGTH");95
}96
result.outputBytes = outputBytes;97
}98
if (algorithm.seeded) result.seed = normalizeSeed(request.seed, algorithm.seedBits);99
if (algorithm.keyed) {100
const fallback = "00".repeat(algorithm.keyBytes);101
const keyHex = String(request.keyHex || fallback).trim().toLowerCase();102
if (!new RegExp(`^[0-9a-f]{${algorithm.keyBytes * 2}}$`).test(keyHex)) throw typedError(`${algorithm.name} key must be exactly ${algorithm.keyBytes} bytes in hexadecimal.`, "HASH_INVALID_KEY");103
result.keyHex = keyHex;104
result.defaultKey = !request.keyHex;105
}106
return result;107
});108
}110
function normalizeSeed(value, bits) {111
if (value === undefined || value === null || String(value).trim() === "") return "0";112
const source = String(value).trim();113
if (!/^(?:0x[0-9a-f]+|[0-9]+)$/i.test(source)) throw typedError("Seed must be an unsigned decimal or 0x-prefixed hexadecimal integer.", "HASH_INVALID_SEED");114
const seed = BigInt(source);115
if (seed < 0n || seed >= (1n << BigInt(bits))) throw typedError(`Seed must fit in ${bits} bits.`, "HASH_INVALID_SEED");116
return seed.toString();117
}119
function typedError(message, code) {120
const error = new Error(message);121
error.code = code;122
return error;123
}125
module.exports = { ALGORITHMS, BY_ID, CATEGORIES, getAlgorithms, normalizeAlgorithmRequests, typedError };SHA-256: de6c811c905eadfa04e3aa4166b59fc3f76ef770ffa6060f489ea194626e87e8
Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0