react-native-quick-crypto
Version:
A fast implementation of Node's `crypto` module written in C/C++ JSI
100 lines (93 loc) • 2.87 kB
text/typescript
import type { HashAlgorithmIdentifier, HashAlgorithm } from './keys';
export enum HashContext {
Node,
WebCrypto,
JwkRsa,
JwkRsaPss,
JwkRsaOaep,
JwkHmac,
}
// WebCrypto and JWK use a bunch of different names for the
// standard set of SHA-* digest algorithms... which is ... fun.
// Here we provide a utility for mapping between them in order
// make it easier in the code.
type HashNames = {
[ ]: { [key in HashContext as string]: string };
};
const kHashNames: HashNames = {
sha1: {
[ ]: 'sha1',
[ ]: 'SHA-1',
[ ]: 'RS1',
[ ]: 'PS1',
[ ]: 'RSA-OAEP',
[ ]: 'HS1',
},
sha224: {
[ ]: 'sha224',
[ ]: 'SHA-224',
[ ]: 'RS224',
[ ]: 'PS224',
[ ]: 'RSA-OAEP-224',
[ ]: 'HS224',
},
sha256: {
[ ]: 'sha256',
[ ]: 'SHA-256',
[ ]: 'RS256',
[ ]: 'PS256',
[ ]: 'RSA-OAEP-256',
[ ]: 'HS256',
},
sha384: {
[ ]: 'sha384',
[ ]: 'SHA-384',
[ ]: 'RS384',
[ ]: 'PS384',
[ ]: 'RSA-OAEP-384',
[ ]: 'HS384',
},
sha512: {
[ ]: 'sha512',
[ ]: 'SHA-512',
[ ]: 'RS512',
[ ]: 'PS512',
[ ]: 'RSA-OAEP-512',
[ ]: 'HS512',
},
ripemd160: {
[ ]: 'ripemd160',
[ ]: 'RIPEMD-160',
},
};
{
// Index the aliases
const keys: string[] = Object.keys(kHashNames);
for (let n: number = 0; n < keys.length; n++) {
const contexts: string[] = Object.keys(kHashNames[keys[n]!]!);
for (let i: number = 0; i < contexts.length; i++) {
const alias: string = kHashNames[keys[n]!]![contexts[i]!]!.toLowerCase();
if (kHashNames[alias] === undefined)
kHashNames[alias] = kHashNames[keys[n]!]!;
}
}
}
export function normalizeHashName(
algo: string | HashAlgorithm | HashAlgorithmIdentifier | undefined,
context: HashContext = HashContext.Node,
): HashAlgorithm {
if (typeof algo !== 'undefined') {
if (typeof algo === 'object') {
algo = algo.name;
}
const normAlgo = algo.toString().toLowerCase();
try {
const alias = kHashNames[normAlgo]![context] as HashAlgorithm;
if (alias) return alias;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
} catch (_e: unknown) {
/* empty */
}
}
throw new Error(`Invalid Hash Algorithm: ${algo}`);
}