main
Raw Download raw file
 1import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
 2
 3class DHPublicKey {
 4    constructor(key) {
 5        this._key = key;
 6    }
 7
 8    get algorithm() {
 9        return { name: "DH" };
10    }
11
12    exportKey() {
13        return this._key;
14    }
15}
16
17export class DHCipher {
18    constructor() {
19        this._g = null;
20        this._p = null;
21        this._gBigInt = null;
22        this._pBigInt = null;
23        this._privateKey = null;
24    }
25
26    get algorithm() {
27        return { name: "DH" };
28    }
29
30    static generateKey(algorithm, _extractable) {
31        const cipher = new DHCipher;
32        cipher._generateKey(algorithm);
33        return { privateKey: cipher, publicKey: new DHPublicKey(cipher._publicKey) };
34    }
35
36    _generateKey(algorithm) {
37        const g = algorithm.g;
38        const p = algorithm.p;
39        this._keyBytes = p.length;
40        this._gBigInt = u8ArrayToBigInt(g);
41        this._pBigInt = u8ArrayToBigInt(p);
42        this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes));
43        this._privateKeyBigInt = u8ArrayToBigInt(this._privateKey);
44        this._publicKey = bigIntToU8Array(modPow(
45            this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes);
46    }
47
48    deriveBits(algorithm, length) {
49        const bytes = Math.ceil(length / 8);
50        const pkey = new Uint8Array(algorithm.public);
51        const len = bytes > this._keyBytes ? bytes : this._keyBytes;
52        const secret = modPow(u8ArrayToBigInt(pkey), this._privateKeyBigInt, this._pBigInt);
53        return bigIntToU8Array(secret, len).slice(0, len);
54    }
55}