UNPKG

@scintilla-network/signatures

Version:

Enhanced signature and key exchange functions for blockchain and crypto applications, including post-quantum algorithms

102 lines (96 loc) 3.58 kB
/** * @typedef {import('../types.js').Bytes} Bytes * @typedef {import('../types.js').PublicKey} PublicKey * @typedef {import('../types.js').PrivateKey} PrivateKey * @typedef {import('../types.js').Signature} Signature * @typedef {import('../types.js').Signing} Signing */ import { ml_dsa87 } from '@noble/post-quantum/ml-dsa'; import { isUint8Array } from '../utils/types.js'; import { formatMessage } from '../utils/format.js'; /** * ML-DSA-87 (Dilithium mode 3) signatures * Implements the {@link Signing} interface * Security level: NIST Level 5 (equivalent to AES-256) * @namespace dilithium87 */ export const dilithium87 = { /** * Generate a new private key * @param {Bytes} [seed] - Optional 32-byte seed for deterministic key generation * @returns {PrivateKey} Private key * @throws {Error} If seed is invalid */ generatePrivateKey(seed) { if (seed !== undefined) { if (!isUint8Array(seed)) { throw new Error('seed must be a Uint8Array'); } if (seed.length !== 32) { throw new Error('seed must be 32 bytes'); } return seed; } return crypto.getRandomValues(new Uint8Array(32)); }, /** * Generate a new key pair * @param {Bytes} [seed] - Optional 32-byte seed for deterministic key generation * @returns {{ publicKey: PublicKey; privateKey: PrivateKey }} Generated key pair * @throws {Error} If seed is invalid */ generateKeyPair(seed) { const genSeed = this.generatePrivateKey(seed); const { publicKey, secretKey: privateKey } = ml_dsa87.keygen(genSeed); return { publicKey, privateKey }; }, /** * Derive public key from private key * @param {PrivateKey} privateKey - Private key * @returns {PublicKey} Public key * @throws {Error} If private key is invalid */ getPublicKey(privateKey) { if (!isUint8Array(privateKey)) { throw new Error('privateKey must be a Uint8Array'); } const { publicKey } = ml_dsa87.keygen(privateKey); return publicKey; }, /** * Sign a message * @param {Bytes} message - Message to sign * @param {PrivateKey} privateKey - Private key * @returns {Signature} Signature * @throws {Error} If inputs are invalid */ sign(message, privateKey) { if (!isUint8Array(message)) { throw new Error('message must be a Uint8Array, use utils.formatMessage() for automatic conversion'); } if (!isUint8Array(privateKey)) { throw new Error('privateKey must be a Uint8Array'); } return ml_dsa87.sign(privateKey, formatMessage(message)); }, /** * Verify a signature * @param {Signature} signature - Signature to verify * @param {Bytes} message - Original message * @param {PublicKey} publicKey - Public key * @returns {boolean} True if signature is valid * @throws {Error} If inputs are invalid */ verify(signature, message, publicKey) { if (!isUint8Array(message)) { throw new Error('message must be a Uint8Array, use utils.formatMessage() for automatic conversion'); } if (!isUint8Array(signature)) { throw new Error('signature must be a Uint8Array'); } if (!isUint8Array(publicKey)) { throw new Error('publicKey must be a Uint8Array'); } return ml_dsa87.verify(publicKey, formatMessage(message), signature); } };