js实现elgamal
ElGamal 加密算法简介
ElGamal 是一种基于离散对数问题的非对称加密算法,常用于密钥交换和数字签名。其核心包括密钥生成、加密和解密三个阶段。

密钥生成
- 选择一个大素数 ( p ) 和一个生成元 ( g )(( g ) 是 ( \mathbb{Z}_p^* ) 的生成元)。
- 随机选择一个私钥 ( x )(( 1 < x < p-1 ))。
- 计算公钥 ( y = g^x \mod p )。
示例代码:

function generateKeys(p, g) {
const x = BigInt(Math.floor(Math.random() * (p - 2)) + 1); // 私钥
const y = (g x) % BigInt(p); // 公钥
return { publicKey: { p, g, y }, privateKey: x };
}
加密过程
- 明文 ( m ) 需要满足 ( 0 \leq m < p )。
- 随机选择一个数 ( k )(( 1 < k < p-1 ))。
- 计算密文分量:
- ( c1 = g^k \mod p )
- ( c2 = (m \cdot y^k) \mod p )
示例代码:
function encrypt(m, publicKey) {
const { p, g, y } = publicKey;
const k = BigInt(Math.floor(Math.random() * (p - 2)) + 1);
const c1 = (g k) % BigInt(p);
const c2 = (BigInt(m) * (y k)) % BigInt(p);
return { c1, c2 };
}
解密过程
- 使用私钥 ( x ) 计算共享秘密 ( s = c1^x \mod p )。
- 计算模反元素 ( s^{-1} \mod p )。
- 明文 ( m = (c2 \cdot s^{-1}) \mod p )。
示例代码:
function decrypt(ciphertext, privateKey, p) {
const { c1, c2 } = ciphertext;
const s = (c1 privateKey) % BigInt(p);
const sInverse = modInverse(s, p);
const m = (c2 * sInverse) % BigInt(p);
return m;
}
// 辅助函数:计算模反元素(扩展欧几里得算法)
function modInverse(a, m) {
a = ((a % m) + m) % m;
for (let x = 1n; x < m; x++) {
if ((a * x) % m === 1n) return x;
}
return 1n;
}
注意事项
- 大整数支持:JavaScript 原生支持
BigInt(后缀n),但需确保所有运算使用BigInt类型。 - 素数选择:实际应用中需使用安全素数(如 2048 位),示例仅作演示。
- 随机性:
k必须每次加密时重新生成,且不可预测。
完整示例
// 示例参数(实际需使用更大的素数)
const p = 23n;
const g = 5n;
// 密钥生成
const { publicKey, privateKey } = generateKeys(p, g);
console.log("公钥:", publicKey);
console.log("私钥:", privateKey);
// 加密
const m = 12n; // 明文
const ciphertext = encrypt(m, publicKey);
console.log("密文:", ciphertext);
// 解密
const decrypted = decrypt(ciphertext, privateKey, p);
console.log("解密结果:", decrypted.toString());
输出说明
- 公钥包含 ( p )、( g ) 和 ( y )。
- 密文为 ( (c1, c2) ) 对。
- 解密结果应与原始明文一致。
通过以上实现,可以在 JavaScript 中完成 ElGamal 的基本加密和解密操作。实际应用中需结合密码学库(如 node-forge)处理大素数和安全随机数。






