summaryrefslogtreecommitdiff
path: root/core/crypto/dh.js
diff options
context:
space:
mode:
authorpdlan <pengdinglan@gmail.com>2023-01-20 05:54:00 -0500
committerpdlan <pengdinglan@gmail.com>2023-01-20 05:54:00 -0500
commitf974b7313762f791ca8376def9525100258ebf46 (patch)
tree446ae648eff7bd66563c7c9dfdb4c9857ab4b5d4 /core/crypto/dh.js
parent5b7d2a622ea5441ae750ea4d3e5cf56ee5737ac5 (diff)
downloadnovnc-f974b7313762f791ca8376def9525100258ebf46.tar.gz
Cleanup for the cryptographic algorithms that are not supported by SubtleCrypto
Diffstat (limited to 'core/crypto/dh.js')
-rw-r--r--core/crypto/dh.js55
1 files changed, 55 insertions, 0 deletions
diff --git a/core/crypto/dh.js b/core/crypto/dh.js
new file mode 100644
index 0000000..bd705d9
--- /dev/null
+++ b/core/crypto/dh.js
@@ -0,0 +1,55 @@
+import { modPow, bigIntToU8Array, u8ArrayToBigInt } from "./bigint.js";
+
+class DHPublicKey {
+ constructor(key) {
+ this._key = key;
+ }
+
+ get algorithm() {
+ return { name: "DH" };
+ }
+
+ exportKey() {
+ return this._key;
+ }
+}
+
+export class DHCipher {
+ constructor() {
+ this._g = null;
+ this._p = null;
+ this._gBigInt = null;
+ this._pBigInt = null;
+ this._privateKey = null;
+ }
+
+ get algorithm() {
+ return { name: "DH" };
+ }
+
+ static generateKey(algorithm, _extractable) {
+ const cipher = new DHCipher;
+ cipher._generateKey(algorithm);
+ return { privateKey: cipher, publicKey: new DHPublicKey(cipher._publicKey) };
+ }
+
+ _generateKey(algorithm) {
+ const g = algorithm.g;
+ const p = algorithm.p;
+ this._keyBytes = p.length;
+ this._gBigInt = u8ArrayToBigInt(g);
+ this._pBigInt = u8ArrayToBigInt(p);
+ this._privateKey = window.crypto.getRandomValues(new Uint8Array(this._keyBytes));
+ this._privateKeyBigInt = u8ArrayToBigInt(this._privateKey);
+ this._publicKey = bigIntToU8Array(modPow(
+ this._gBigInt, this._privateKeyBigInt, this._pBigInt), this._keyBytes);
+ }
+
+ deriveBits(algorithm, length) {
+ const bytes = Math.ceil(length / 8);
+ const pkey = new Uint8Array(algorithm.public);
+ const len = bytes > this._keyBytes ? bytes : this._keyBytes;
+ const secret = modPow(u8ArrayToBigInt(pkey), this._privateKeyBigInt, this._pBigInt);
+ return bigIntToU8Array(secret, len).slice(0, len);
+ }
+}