mirror of
https://github.com/logos-messaging/js-waku.git
synced 2026-01-02 13:53:12 +00:00
106 lines
2.7 KiB
TypeScript
106 lines
2.7 KiB
TypeScript
import nodeCrypto from "crypto";
|
|
|
|
import * as secp from "@noble/secp256k1";
|
|
import { concat } from "@waku/utils/bytes";
|
|
import sha3 from "js-sha3";
|
|
|
|
import { Asymmetric, Symmetric } from "../misc.js";
|
|
|
|
declare const self: Record<string, any> | undefined;
|
|
const crypto: { node?: any; web?: any } = {
|
|
node: nodeCrypto,
|
|
web: typeof self === "object" && "crypto" in self ? self.crypto : undefined
|
|
};
|
|
|
|
export function getSubtle(): SubtleCrypto {
|
|
if (crypto.web) {
|
|
return crypto.web.subtle;
|
|
} else if (crypto.node) {
|
|
return crypto.node.webcrypto.subtle;
|
|
} else {
|
|
throw new Error(
|
|
"The environment doesn't have Crypto Subtle API (if in the browser, be sure to use to be in a secure context, ie, https)"
|
|
);
|
|
}
|
|
}
|
|
|
|
export const randomBytes = secp.utils.randomBytes;
|
|
export const sha256 = secp.utils.sha256;
|
|
|
|
/**
|
|
* Generate a new private key to be used for asymmetric encryption.
|
|
*
|
|
* Use {@link getPublicKey} to get the corresponding Public Key.
|
|
*/
|
|
export function generatePrivateKey(): Uint8Array {
|
|
return randomBytes(Asymmetric.keySize);
|
|
}
|
|
|
|
/**
|
|
* Generate a new symmetric key to be used for symmetric encryption.
|
|
*/
|
|
export function generateSymmetricKey(): Uint8Array {
|
|
return randomBytes(Symmetric.keySize);
|
|
}
|
|
|
|
/**
|
|
* Return the public key for the given private key, to be used for asymmetric
|
|
* encryption.
|
|
*/
|
|
export const getPublicKey = secp.getPublicKey;
|
|
|
|
/**
|
|
* ECDSA Sign a message with the given private key.
|
|
*
|
|
* @param message The message to sign, usually a hash.
|
|
* @param privateKey The ECDSA private key to use to sign the message.
|
|
*
|
|
* @returns The signature and the recovery id concatenated.
|
|
*/
|
|
export async function sign(
|
|
message: Uint8Array,
|
|
privateKey: Uint8Array
|
|
): Promise<Uint8Array> {
|
|
const [signature, recoveryId] = await secp.sign(message, privateKey, {
|
|
recovered: true,
|
|
der: false
|
|
});
|
|
return concat(
|
|
[signature, new Uint8Array([recoveryId])],
|
|
signature.length + 1
|
|
);
|
|
}
|
|
|
|
export function keccak256(input: Uint8Array): Uint8Array {
|
|
return new Uint8Array(sha3.keccak256.arrayBuffer(input));
|
|
}
|
|
|
|
/**
|
|
* Compare two public keys, can be used to verify that a given signature matches
|
|
* expectations.
|
|
*
|
|
* @param publicKeyA - The first public key to compare
|
|
* @param publicKeyB - The second public key to compare
|
|
* @returns true if the public keys are the same
|
|
*/
|
|
export function comparePublicKeys(
|
|
publicKeyA: Uint8Array | undefined,
|
|
publicKeyB: Uint8Array | undefined
|
|
): boolean {
|
|
if (!publicKeyA || !publicKeyB) {
|
|
return false;
|
|
}
|
|
|
|
if (publicKeyA.length !== publicKeyB.length) {
|
|
return false;
|
|
}
|
|
|
|
for (let i = 0; i < publicKeyA.length; i++) {
|
|
if (publicKeyA[i] !== publicKeyB[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|