UNPKG

mima-kit

Version:

mima-kit is a cryptographic suite implemented in TypeScript. The goal is to provide an easy-to-use cryptographic library. mima-kit 是一个使用 TypeScript 实现的密码学套件。目标是提供一个简单易用的密码学库。

113 lines (112 loc) 2.96 kB
import { genPrime } from '../../core/prime'; import { KitError, U8, gcd, lcm, mod, modInverse, modPow } from '../../core/utils'; // * RSA Algorithm /** * RSA 加密原语 * * RSA encryption primitive */ function encryptionPrimitive(key, M) { const { n, e } = key; if (e === undefined || n === undefined) { throw new KitError('Invalid public key'); } M = typeof M === 'bigint' ? M : U8.from(M).toBI(); if (M >= n) { throw new KitError('Message representative out of range'); } return modPow(M, e, n); } /** * RSA 解密原语 * * RSA decryption primitive */ function decryptionPrimitive(key, C) { const { n, d } = key; if (d === undefined || n === undefined) { throw new KitError('Invalid private key'); } C = typeof C === 'bigint' ? C : U8.from(C).toBI(); if (C >= n) { throw new KitError('Ciphertext representative out of range'); } return modPow(C, d, n); } /** * RSA 签名原语 * * RSA signature primitive */ function signaturePrimitive(key, M) { const { n, d } = key; if (d === undefined || n === undefined) { throw new KitError('Invalid private key'); } M = typeof M === 'bigint' ? M : U8.from(M).toBI(); if (M >= n) { throw new KitError('Message representative out of range'); } return modPow(M, d, n); } /** * RSA 验证原语 * * RSA verification primitive */ function verificationPrimitive(key, S) { const { n, e } = key; if (e === undefined || n === undefined) { throw new KitError('Invalid public key'); } S = typeof S === 'bigint' ? S : U8.from(S).toBI(); if (S >= n) { throw new KitError('Signature is too long'); } return modPow(S, e, n); } /** * RSA 密钥生成 * * RSA key generation * * @param {number} b - RSA 私钥长度 / RSA private key length (bit) * @param {RandomPrimeGenerator} rpg - 随机素数生成器 / Random prime generator */ function genKey(b, rpg = genPrime) { const p = rpg(b >> 1); const q = rpg(b >> 1); const n = p * q; const λ = lcm(p - 1n, q - 1n); // public key const e = 65537n; if (gcd(e, λ) !== 1n) { throw new KitError('Invalid public exponent'); } // private key const d = modInverse(e, λ); const dP = mod(d, p - 1n); const dQ = mod(d, q - 1n); const qInv = modInverse(q, p); const privateKey = { n, e, d, p, q, dP, dQ, qInv }; return privateKey; } function fromKey(key) { const encrypt = (M) => encryptionPrimitive(key, M); const decrypt = (C) => decryptionPrimitive(key, C); const sign = (M) => signaturePrimitive(key, M); const verify = (S) => verificationPrimitive(key, S); return { ...key, encrypt, decrypt, sign, verify, }; } export function rsa(b, rpg = genPrime) { if (typeof b === 'number') { return fromKey(genKey(b, rpg)); } return fromKey(b); }