From 8848f5090319c918783a3f65530e77e757e39b20 Mon Sep 17 00:00:00 2001 From: tj Date: Mon, 19 Jul 2021 16:48:24 -0400 Subject: [PATCH 01/13] import Node `crypto.webcrypto` --- package-lock.json | 168 ++++++++++++++++++++++++++++++---------------- package.json | 3 +- src/native.ts | 8 +++ 3 files changed, 120 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index c9f37cb..145fe72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,13 +27,14 @@ "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-node-resolve": "^11.1.1", "@types/mocha": "^8.2.0", - "@types/node": "^14.14.25", + "@types/node": "^16.0.0", "babel-preset-minify": "^0.5.1", "coveralls": "^3.1.0", "mocha": "^8.2.1", "nyc": "^15.1.0", "rimraf": "^3.0.2", "rollup": "^2.38.5", + "rollup-plugin-polyfill-node": "^0.6.2", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.29.0", "ts-node": "^9.1.1", @@ -1183,6 +1184,20 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "dev": true }, + "node_modules/@rollup/plugin-inject": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.2.tgz", + "integrity": "sha512-TSLMA8waJ7Dmgmoc8JfPnwUwVZgLjjIAM6MqeIFqPO2ODK36JqE0Cf2F54UTgCUuW8da93Mvoj75a6KAVWgylw==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.0.4", + "estree-walker": "^1.0.1", + "magic-string": "^0.25.5" + }, + "peerDependencies": { + "rollup": "^1.20.0 || ^2.0.0" + } + }, "node_modules/@rollup/plugin-node-resolve": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.1.1.tgz", @@ -1232,9 +1247,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "14.14.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz", - "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==", + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.3.tgz", + "integrity": "sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ==", "dev": true }, "node_modules/@types/resolve": { @@ -1719,22 +1734,26 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" }, "bin": { "browserslist": "cli.js" }, "engines": { "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/buffer-from": { @@ -1787,10 +1806,14 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001185", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz", - "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==", - "dev": true + "version": "1.0.30001245", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", + "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/caseless": { "version": "0.12.0", @@ -1904,9 +1927,9 @@ "dev": true }, "node_modules/colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "node_modules/combined-stream": { @@ -2121,9 +2144,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.3.657", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.657.tgz", - "integrity": "sha512-/9ROOyvEflEbaZFUeGofD+Tqs/WynbSTbNgNF+/TJJxH1ePD/e6VjZlDJpW3FFFd3nj5l3Hd8ki2vRwy+gyRFw==", + "version": "1.3.779", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", + "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==", "dev": true }, "node_modules/elliptic": { @@ -2419,9 +2442,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" @@ -3006,9 +3029,9 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.flattendeep": { @@ -3331,9 +3354,9 @@ } }, "node_modules/node-releases": { - "version": "1.1.70", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", - "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "node_modules/normalize-path": { @@ -4040,6 +4063,15 @@ "fsevents": "~2.3.1" } }, + "node_modules/rollup-plugin-polyfill-node": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.6.2.tgz", + "integrity": "sha512-gMCVuR0zsKq0jdBn8pSXN1Ejsc458k2QsFFvQdbHoM0Pot5hEnck+pBP/FDwFS6uAi77pD3rDTytsaUStsOMlA==", + "dev": true, + "dependencies": { + "@rollup/plugin-inject": "^4.0.0" + } + }, "node_modules/rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", @@ -5990,6 +6022,17 @@ } } }, + "@rollup/plugin-inject": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@rollup/plugin-inject/-/plugin-inject-4.0.2.tgz", + "integrity": "sha512-TSLMA8waJ7Dmgmoc8JfPnwUwVZgLjjIAM6MqeIFqPO2ODK36JqE0Cf2F54UTgCUuW8da93Mvoj75a6KAVWgylw==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.4", + "estree-walker": "^1.0.1", + "magic-string": "^0.25.5" + } + }, "@rollup/plugin-node-resolve": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.1.1.tgz", @@ -6033,9 +6076,9 @@ "dev": true }, "@types/node": { - "version": "14.14.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz", - "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==", + "version": "16.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.3.tgz", + "integrity": "sha512-8h7k1YgQKxKXWckzFCMfsIwn0Y61UK6tlD6y2lOb3hTOIMlK3t9/QwHOhc81TwU+RMf0As5fj7NPjroERCnejQ==", "dev": true }, "@types/resolve": { @@ -6487,16 +6530,16 @@ "dev": true }, "browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" } }, "buffer-from": { @@ -6540,9 +6583,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001185", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz", - "integrity": "sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==", + "version": "1.0.30001245", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", + "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==", "dev": true }, "caseless": { @@ -6639,9 +6682,9 @@ "dev": true }, "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "combined-stream": { @@ -6819,9 +6862,9 @@ } }, "electron-to-chromium": { - "version": "1.3.657", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.657.tgz", - "integrity": "sha512-/9ROOyvEflEbaZFUeGofD+Tqs/WynbSTbNgNF+/TJJxH1ePD/e6VjZlDJpW3FFFd3nj5l3Hd8ki2vRwy+gyRFw==", + "version": "1.3.779", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", + "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==", "dev": true }, "elliptic": { @@ -7056,9 +7099,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -7521,9 +7564,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.flattendeep": { @@ -7782,9 +7825,9 @@ } }, "node-releases": { - "version": "1.1.70", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", - "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "normalize-path": { @@ -8359,6 +8402,15 @@ } } }, + "rollup-plugin-polyfill-node": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-polyfill-node/-/rollup-plugin-polyfill-node-0.6.2.tgz", + "integrity": "sha512-gMCVuR0zsKq0jdBn8pSXN1Ejsc458k2QsFFvQdbHoM0Pot5hEnck+pBP/FDwFS6uAi77pD3rDTytsaUStsOMlA==", + "dev": true, + "requires": { + "@rollup/plugin-inject": "^4.0.0" + } + }, "rollup-plugin-terser": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", diff --git a/package.json b/package.json index 6c804c0..a41860c 100644 --- a/package.json +++ b/package.json @@ -50,13 +50,14 @@ "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-node-resolve": "^11.1.1", "@types/mocha": "^8.2.0", - "@types/node": "^14.14.25", + "@types/node": "^16.0.0", "babel-preset-minify": "^0.5.1", "coveralls": "^3.1.0", "mocha": "^8.2.1", "nyc": "^15.1.0", "rimraf": "^3.0.2", "rollup": "^2.38.5", + "rollup-plugin-polyfill-node": "^0.6.2", "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.29.0", "ts-node": "^9.1.1", diff --git a/src/native.ts b/src/native.ts index c3693a6..4b1fc20 100644 --- a/src/native.ts +++ b/src/native.ts @@ -1,5 +1,12 @@ import * as core from "webcrypto-core"; +let NodeJSWebCrypto: any = null; + +if (typeof process !== 'undefined' && process.version) { + const { webcrypto } = require('crypto'); + NodeJSWebCrypto = webcrypto; +} + let window: any = {}; if (typeof self !== "undefined") { window = self; @@ -8,6 +15,7 @@ if (typeof self !== "undefined") { export let nativeCrypto: core.NativeCrypto = window["msCrypto"] // IE || window.crypto // other browsers + || NodeJSWebCrypto // Node || {}; // if crypto is empty export let nativeSubtle: core.NativeSubtleCrypto | null = null; try { From 73168df4fbe9e780518d6fa58d0e01690e7b6532 Mon Sep 17 00:00:00 2001 From: tj Date: Mon, 19 Jul 2021 16:58:36 -0400 Subject: [PATCH 02/13] Fixed html example --- examples/html/index.html | 14 ++++++++------ package-lock.json | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/examples/html/index.html b/examples/html/index.html index 8c0400b..e1cc9d0 100644 --- a/examples/html/index.html +++ b/examples/html/index.html @@ -6,6 +6,8 @@ WebCrypto Liner + + @@ -13,19 +15,19 @@

WebCrypto Liner example

Signing

-
- +
+

Verifying

-
+
-
+
-
+
- +
diff --git a/package-lock.json b/package-lock.json index 145fe72..729254b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ }, "devDependencies": { "@babel/core": "^7.12.13", + "@babel/polyfill": "^7.12.1", "@babel/preset-env": "^7.12.13", "@peculiar/webcrypto": "^1.1.6", "@rollup/plugin-babel": "^5.2.3", @@ -900,6 +901,25 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "node_modules/@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.", + "dev": true, + "dependencies": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + } + }, + "node_modules/@babel/polyfill/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, "node_modules/@babel/preset-env": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.13.tgz", @@ -5764,6 +5784,24 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/polyfill": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz", + "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "dev": true + } + } + }, "@babel/preset-env": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.13.tgz", diff --git a/package.json b/package.json index a41860c..75408ef 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ }, "devDependencies": { "@babel/core": "^7.12.13", + "@babel/polyfill": "^7.12.1", "@babel/preset-env": "^7.12.13", "@peculiar/webcrypto": "^1.1.6", "@rollup/plugin-babel": "^5.2.3", From 79c4a8dd8b89665b291f3c8f3fe947db9ebd0337 Mon Sep 17 00:00:00 2001 From: tj Date: Mon, 19 Jul 2021 17:18:10 -0400 Subject: [PATCH 03/13] updated assert statement for tests --- test/utils/helper.ts | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/test/utils/helper.ts b/test/utils/helper.ts index 1b84e99..a78fcf4 100644 --- a/test/utils/helper.ts +++ b/test/utils/helper.ts @@ -166,20 +166,20 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { action.keyUsages, ); - assert.equal(!!key, true); + assert.strictEqual(!!key, true); if (!key.privateKey) { - assert.equal(key.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); - assert.equal(key.extractable, action.extractable); - assert.deepEqual([...key.usages].sort(), [...action.keyUsages].sort()); + assert.strictEqual(key.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); + assert.strictEqual(key.extractable, action.extractable); + assert.deepStrictEqual([...key.usages].sort(), [...action.keyUsages].sort()); } else { - assert.equal(!!key.privateKey, true); - assert.equal(key.privateKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); - assert.equal(key.privateKey.extractable, action.extractable); + assert.strictEqual(!!key.privateKey, true); + assert.strictEqual(key.privateKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); + assert.strictEqual(key.privateKey.extractable, action.extractable); - assert.equal(!!key.publicKey, true); - assert.equal(key.publicKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); - assert.equal(key.publicKey.extractable, true); + assert.strictEqual(!!key.publicKey, true); + assert.strictEqual(key.publicKey.algorithm.name, action.algorithm.name, "Algorithm name MUST be equal to incoming algorithm and in the same case"); + assert.strictEqual(key.publicKey.extractable, true); } }, action, index); }); @@ -204,10 +204,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { const enc = await crypto.subtle.encrypt(algorithm, encKey, action.data); // decrypt let dec = await crypto.subtle.decrypt(algorithm, decKey, enc); - assert.equal(Convert.ToHex(dec), Convert.ToHex(action.data)); + assert.strictEqual(Convert.ToHex(dec), Convert.ToHex(action.data)); dec = await crypto.subtle.decrypt(algorithm, decKey, action.encData); - assert.equal(Convert.ToHex(dec), Convert.ToHex(action.data)); + assert.strictEqual(Convert.ToHex(dec), Convert.ToHex(action.data)); }, action, index); }); }); @@ -238,9 +238,9 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { if (action.format === "jwk") { exportedData.key_ops.sort(); (action.data as JsonWebKey).key_ops.sort(); - assert.deepEqual(exportedData, action.data); + assert.deepStrictEqual(exportedData, action.data); } else { - assert.equal(Convert.ToHex(exportedData as ArrayBuffer), Convert.ToHex(action.data as ArrayBuffer)); + assert.strictEqual(Convert.ToHex(exportedData as ArrayBuffer), Convert.ToHex(action.data as ArrayBuffer)); } }, action, index); }); @@ -265,13 +265,13 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { const signature = await crypto.subtle.sign(algorithm, signKey, action.data); // verify let ok = await crypto.subtle.verify(algorithm, verifyKey, signature, action.data); - assert.equal(true, ok, "Cannot verify signature from Action data"); + assert.strictEqual(true, ok, "Cannot verify signature from Action data"); ok = await crypto.subtle.verify(algorithm, verifyKey, action.signature, action.data); if (!ok) { - assert.equal(Convert.ToHex(signature), Convert.ToHex(action.signature)); + assert.strictEqual(Convert.ToHex(signature), Convert.ToHex(action.signature)); } - assert.equal(true, ok); + assert.strictEqual(true, ok); }, action, index); }); }); @@ -291,7 +291,7 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { // derive bits const derivedBits = await crypto.subtle.deriveBits(algorithm, keys.privateKey, action.length); - assert.equal(Convert.ToHex(derivedBits), Convert.ToHex(action.data)); + assert.strictEqual(Convert.ToHex(derivedBits), Convert.ToHex(action.data)); }, action, index); }); }); @@ -313,9 +313,9 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { const derivedKey = await crypto.subtle.deriveKey(algorithm, keys.privateKey, action.derivedKeyType, true, action.keyUsages); const keyData = await crypto.subtle.exportKey(action.format, derivedKey); if (action.format === "jwk") { - assert.deepEqual(keyData, action.keyData); + assert.deepStrictEqual(keyData, action.keyData); } else { - assert.equal(Convert.ToHex(keyData as ArrayBuffer), Convert.ToHex(action.keyData as ArrayBuffer)); + assert.strictEqual(Convert.ToHex(keyData as ArrayBuffer), Convert.ToHex(action.keyData as ArrayBuffer)); } }, action, index); }); @@ -329,7 +329,7 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { param.actions.digest!.forEach((action, index) => { wrapTest(async () => { const hash = await crypto.subtle.digest(action.algorithm, action.data); - assert.equal(Convert.ToHex(hash), Convert.ToHex(action.hash)); + assert.strictEqual(Convert.ToHex(hash), Convert.ToHex(action.hash)); }, action, index); }); }); @@ -347,7 +347,7 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { const wrappedKey = await crypto.subtle.wrapKey(action.wKey.format, wKey, key.publicKey, action.algorithm); if (action.wrappedKey) { - assert.equal(Convert.ToHex(wrappedKey), Convert.ToHex(action.wrappedKey)); + assert.strictEqual(Convert.ToHex(wrappedKey), Convert.ToHex(action.wrappedKey)); } const unwrappedKey = await crypto.subtle.unwrapKey( @@ -359,7 +359,7 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { action.wKey.extractable, action.wKey.keyUsages); - assert.deepEqual(unwrappedKey.algorithm, wKey.algorithm); + assert.deepStrictEqual(unwrappedKey.algorithm, wKey.algorithm); }, action, index); }); }); From 9d0e73403b2b0d4b760348fa76a78f5b72488195 Mon Sep 17 00:00:00 2001 From: tj Date: Wed, 21 Jul 2021 11:01:47 -0400 Subject: [PATCH 04/13] start work on deriveBits --- package-lock.json | 101 ++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/mechs/ed/crypto.ts | 3 +- src/subtle.ts | 2 +- test/ed.ts | 103 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 208 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 729254b..03cd76e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@peculiar/asn1-schema": "^2.0.27", "@peculiar/json-schema": "^1.1.12", + "@stablelib/x25519": "^1.0.1", "asmcrypto.js": "^2.3.2", "asn1js": "^2.0.26", "core-js": "^3.8.3", @@ -1249,6 +1250,56 @@ "node": ">= 8.0.0" } }, + "node_modules/@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "dependencies": { + "@stablelib/int": "^1.0.1" + } + }, + "node_modules/@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "node_modules/@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "node_modules/@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "dependencies": { + "@stablelib/bytes": "^1.0.1" + } + }, + "node_modules/@stablelib/random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.1.tgz", + "integrity": "sha512-zOh+JHX3XG9MSfIB0LZl/YwPP9w3o6WBiJkZvjPoKKu5LKFW4OLV71vMxWp9qG5T43NaWyn0QQTWgqCdO+yOBQ==", + "dependencies": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "node_modules/@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "node_modules/@stablelib/x25519": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.1.tgz", + "integrity": "sha512-nmyUI2ZArxYDh1PhdoSCPEtlTYE0DYugp2qqx8OtjrX3Hmh7boIlDsD0X71ihAxzxqJf3TyQqN/p58ToWhnp+Q==", + "dependencies": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, "node_modules/@types/asn1js": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-2.0.0.tgz", @@ -6096,6 +6147,56 @@ "picomatch": "^2.2.2" } }, + "@stablelib/binary": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/binary/-/binary-1.0.1.tgz", + "integrity": "sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==", + "requires": { + "@stablelib/int": "^1.0.1" + } + }, + "@stablelib/bytes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/bytes/-/bytes-1.0.1.tgz", + "integrity": "sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==" + }, + "@stablelib/int": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/int/-/int-1.0.1.tgz", + "integrity": "sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==" + }, + "@stablelib/keyagreement": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz", + "integrity": "sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==", + "requires": { + "@stablelib/bytes": "^1.0.1" + } + }, + "@stablelib/random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/random/-/random-1.0.1.tgz", + "integrity": "sha512-zOh+JHX3XG9MSfIB0LZl/YwPP9w3o6WBiJkZvjPoKKu5LKFW4OLV71vMxWp9qG5T43NaWyn0QQTWgqCdO+yOBQ==", + "requires": { + "@stablelib/binary": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, + "@stablelib/wipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/wipe/-/wipe-1.0.1.tgz", + "integrity": "sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==" + }, + "@stablelib/x25519": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@stablelib/x25519/-/x25519-1.0.1.tgz", + "integrity": "sha512-nmyUI2ZArxYDh1PhdoSCPEtlTYE0DYugp2qqx8OtjrX3Hmh7boIlDsD0X71ihAxzxqJf3TyQqN/p58ToWhnp+Q==", + "requires": { + "@stablelib/keyagreement": "^1.0.1", + "@stablelib/random": "^1.0.1", + "@stablelib/wipe": "^1.0.1" + } + }, "@types/asn1js": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-2.0.0.tgz", diff --git a/package.json b/package.json index 75408ef..b07632b 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "dependencies": { "@peculiar/asn1-schema": "^2.0.27", "@peculiar/json-schema": "^1.1.12", + "@stablelib/x25519": "^1.0.1", "asmcrypto.js": "^2.3.2", "asn1js": "^2.0.26", "core-js": "^3.8.3", diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index f21b8d6..e531197 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -1,6 +1,7 @@ import { AsnConvert, OctetString } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as elliptic from "elliptic"; +import * as stable from "@stablelib/x25519"; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; import { nativeCrypto } from "../../native"; @@ -41,7 +42,7 @@ export class EdCrypto { const raw = nativeCrypto.getRandomValues(new Uint8Array(32)); const eddsa = new elliptic.eddsa(curve); edKey = eddsa.keyFromSecret(raw); - } else { + } else if (curve === "curve25519") { edKey = elliptic.ec(curve).genKeyPair(); edKey.getPublic(); // Fills internal `pub` field } diff --git a/src/subtle.ts b/src/subtle.ts index 57e80f1..8b42efc 100644 --- a/src/subtle.ts +++ b/src/subtle.ts @@ -91,7 +91,7 @@ export class SubtleCrypto extends core.SubtleCrypto { //#region ECDH-ES // TODO Elliptic.js has got issue (https://github.com/indutny/elliptic/issues/243). Uncomment the next line after fix - // this.providers.set(new EcdhEsProvider()); + this.providers.set(new EcdhEsProvider()); //#endregion } diff --git a/test/ed.ts b/test/ed.ts index f76596f..3e8a1c5 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -80,3 +80,106 @@ context("ED", () => { }); + + +context("ECDH_ES", () => { + + context("generate/export/import/sign/verify", () => { + const alg = { name: "ECDH-ES", namedCurve: "x25519" }; + const data = Buffer.from("Some message to sign"); + + it("pkcs8/spki", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const spki = await liner.subtle.exportKey("spki", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("spki", nodePublicKey), + await liner.subtle.exportKey("spki", linerPublicKey) + ); + + }); + + it("jwk", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); + const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePrivateKey), + await liner.subtle.exportKey("jwk", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePublicKey), + await liner.subtle.exportKey("jwk", linerPublicKey) + ); + + }); + + it("pkcs8/raw", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const raw = await liner.subtle.exportKey("raw", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("raw", nodePublicKey), + await liner.subtle.exportKey("raw", linerPublicKey) + ); + }); + + it("deriveBits", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + + const privateJwk = { + kty: "OKP", + crv: "X25519", + key_ops: ["deriveBits"], + ext: true, + d: "YP_Dbf6rotbZd-2gBwSIdr_MM8ZKiAG33CPvOHo97WI" + // d(hex): 60ffc36dfeaba2d6d977eda007048876bfcc33c64a8801b7dc23ef387a3ded62 + }; + + const publicJwk = { + kty: "OKP", + crv: "X25519", + key_ops: [], + ext: true, + x: "4fMe1l0XMe8q8pf3V8Eyz8GSChoLfULmrr0dAHK0uVA" + // x(hex): e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950 + }; + + const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), + Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).toString("hex") + ) + }); + }); + + + +}); \ No newline at end of file From 6c42326abe6d69cf1e545d8bfd02452a0401e5ba Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 11:38:42 -0400 Subject: [PATCH 05/13] start work integrating x25519 --- package-lock.json | 11 +++ package.json | 1 + src/mechs/ed/crypto.ts | 20 +++--- src/mechs/ed/private_key.ts | 5 +- test/ed.ts | 133 +++++++++++++++++++----------------- 5 files changed, 95 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index 03cd76e..f3b6f76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "asmcrypto.js": "^2.3.2", "asn1js": "^2.0.26", "core-js": "^3.8.3", + "curve25519-js": "^0.0.4", "des.js": "^1.0.1", "elliptic": "^6.5.4", "pvtsutils": "^1.1.2", @@ -2111,6 +2112,11 @@ "node": ">= 8" } }, + "node_modules/curve25519-js": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/curve25519-js/-/curve25519-js-0.0.4.tgz", + "integrity": "sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==" + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -6921,6 +6927,11 @@ "which": "^2.0.1" } }, + "curve25519-js": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/curve25519-js/-/curve25519-js-0.0.4.tgz", + "integrity": "sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==" + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", diff --git a/package.json b/package.json index b07632b..c9b3d82 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "asmcrypto.js": "^2.3.2", "asn1js": "^2.0.26", "core-js": "^3.8.3", + "curve25519-js": "^0.0.4", "des.js": "^1.0.1", "elliptic": "^6.5.4", "pvtsutils": "^1.1.2", diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index e531197..927b2bf 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -1,7 +1,7 @@ import { AsnConvert, OctetString } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as elliptic from "elliptic"; -import * as stable from "@stablelib/x25519"; +import { sharedKey, generateKeyPair } from 'curve25519-js'; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; import { nativeCrypto } from "../../native"; @@ -87,21 +87,23 @@ export class EdCrypto { public static async deriveBits(algorithm: EcdhKeyDeriveParams, baseKey: EdPrivateKey, length: number): Promise { this.checkLib(); - const shared = baseKey.data.derive((algorithm.public as EdPublicKey).data.getPublic()); - let array = new Uint8Array(shared.toArray()); + const publicKeyHex = (await crypto.subtle.exportKey("jwk", algorithm.public)).x; + const privateKeyHex = (baseKey.toJSON()).d; - // Padding - let len = array.length; - len = (len > 32 ? (len > 48 ? 66 : 48) : 32); - if (array.length < len) { - array = EdCrypto.concat(new Uint8Array(len - array.length), array); + const cU8 = (h) => { + let nBuf: Buffer = Buffer.alloc(32); + let hex: ArrayBuffer = Convert.FromBase64Url(h); + let hexString: string = Buffer.from(hex, 0).toString("hex"); + nBuf.write(hexString, 0); + return nBuf; } - const buf = array.slice(0, length / 8).buffer; + const buf = sharedKey(cU8(privateKeyHex), cU8(publicKeyHex)); return buf; } public static async exportKey(format: KeyFormat, key: EdPrivateKey | EdPublicKey): Promise { this.checkLib(); + //TODO x25519 switch (format.toLowerCase()) { case "jwk": diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index 5fc1288..1c3d81b 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -37,8 +37,9 @@ export class EdPrivateKey extends CryptoKey implements IJsonConvertible { const eddsa = new elliptic.eddsa(json.crv.toLowerCase()); this.data = eddsa.keyFromSecret(hexPrivateKey); } else { - const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); - this.data = ecdhEs.keyFromPrivate(hexPrivateKey, "hex"); + //TODO x25519 + // const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); + // this.data = ecdhEs.keyFromPrivate(hexPrivateKey, "hex"); } return this; diff --git a/test/ed.ts b/test/ed.ts index 3e8a1c5..0da4da9 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -5,7 +5,7 @@ import { Crypto } from "../src"; const crypto = new NodeCrypto(); const liner = new Crypto(); - +/* context("ED", () => { context("generate/export/import/sign/verify", () => { @@ -81,73 +81,73 @@ context("ED", () => { }); - +*/ context("ECDH_ES", () => { context("generate/export/import/sign/verify", () => { const alg = { name: "ECDH-ES", namedCurve: "x25519" }; const data = Buffer.from("Some message to sign"); - - it("pkcs8/spki", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); - const spki = await liner.subtle.exportKey("spki", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); - - assert.deepStrictEqual( - await crypto.subtle.exportKey("pkcs8", nodePrivateKey), - await liner.subtle.exportKey("pkcs8", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("spki", nodePublicKey), - await liner.subtle.exportKey("spki", linerPublicKey) - ); - - }); - - it("jwk", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); - const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); - assert.deepStrictEqual( - await crypto.subtle.exportKey("jwk", nodePrivateKey), - await liner.subtle.exportKey("jwk", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("jwk", nodePublicKey), - await liner.subtle.exportKey("jwk", linerPublicKey) - ); - - }); - - it("pkcs8/raw", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); - const raw = await liner.subtle.exportKey("raw", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); - assert.deepStrictEqual( - await crypto.subtle.exportKey("pkcs8", nodePrivateKey), - await liner.subtle.exportKey("pkcs8", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("raw", nodePublicKey), - await liner.subtle.exportKey("raw", linerPublicKey) - ); - }); - + /* + it("pkcs8/spki", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const spki = await liner.subtle.exportKey("spki", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("spki", nodePublicKey), + await liner.subtle.exportKey("spki", linerPublicKey) + ); + + }); + + it("jwk", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); + const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePrivateKey), + await liner.subtle.exportKey("jwk", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePublicKey), + await liner.subtle.exportKey("jwk", linerPublicKey) + ); + + }); + + it("pkcs8/raw", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const raw = await liner.subtle.exportKey("raw", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("raw", nodePublicKey), + await liner.subtle.exportKey("raw", linerPublicKey) + ); + }); + */ it("deriveBits", async () => { const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); @@ -173,9 +173,14 @@ context("ECDH_ES", () => { const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + + let pKNode = await crypto.subtle.exportKey("jwk", nodePublicKey); + let pKLiner = await liner.subtle.exportKey("jwk", linerPublicKey); + assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); + assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); assert.deepStrictEqual( Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), - Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).toString("hex") + Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).reverse().toString("hex") ) }); }); From 491c10ff532442769f03a54b3e5e728ba81d0451 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 14:52:15 -0400 Subject: [PATCH 06/13] still working on shim --- package-lock.json | 19 ++++++++++++++++ package.json | 1 + src/mechs/ed/private_key.ts | 44 +++++++++++++++++++++++++++++++++++-- test/ed.ts | 4 ++-- tsconfig.json | 3 ++- 5 files changed, 66 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index f3b6f76..62c7e22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "@rollup/plugin-babel": "^5.2.3", "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-node-resolve": "^11.1.1", + "@types/bn.js": "^5.1.0", "@types/mocha": "^8.2.0", "@types/node": "^16.0.0", "babel-preset-minify": "^0.5.1", @@ -1306,6 +1307,15 @@ "resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-2.0.0.tgz", "integrity": "sha512-Jjzp5EqU0hNpADctc/UqhiFbY1y2MqIxBVa2S4dBlbnZHTLPMuggoL5q43X63LpsOIINRDirBjP56DUUKIUWIA==" }, + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", @@ -6208,6 +6218,15 @@ "resolved": "https://registry.npmjs.org/@types/asn1js/-/asn1js-2.0.0.tgz", "integrity": "sha512-Jjzp5EqU0hNpADctc/UqhiFbY1y2MqIxBVa2S4dBlbnZHTLPMuggoL5q43X63LpsOIINRDirBjP56DUUKIUWIA==" }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", diff --git a/package.json b/package.json index c9b3d82..2c8b13e 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@rollup/plugin-babel": "^5.2.3", "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-node-resolve": "^11.1.1", + "@types/bn.js": "^5.1.0", "@types/mocha": "^8.2.0", "@types/node": "^16.0.0", "babel-preset-minify": "^0.5.1", diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index 1c3d81b..0a60bf8 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -2,7 +2,10 @@ import { IJsonConvertible } from "@peculiar/json-schema"; import * as core from "webcrypto-core"; import { CryptoKey } from "../../key"; import * as elliptic from "elliptic"; +import { sharedKey, generateKeyPair } from 'curve25519-js'; +import BN from "bn.js"; import { Convert } from "pvtsutils"; +import { Any } from "asn1js"; export class EdPrivateKey extends CryptoKey implements IJsonConvertible { public algorithm!: EcKeyAlgorithm; @@ -38,8 +41,45 @@ export class EdPrivateKey extends CryptoKey implements IJsonConvertible { this.data = eddsa.keyFromSecret(hexPrivateKey); } else { //TODO x25519 - // const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); - // this.data = ecdhEs.keyFromPrivate(hexPrivateKey, "hex"); + // const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); + // this.data = ecdhEs.keyFromPrivate(hexPrivateKey, "hex"); + const keys = generateKeyPair(new Uint8Array(Convert.FromBase64Url(json.d))); + const pubBigNum: EllipticJS.BN = { + toBytes: () => { return keys.public }, + toArray: () => { return Array.from(keys.public) } + } + pubBigNum.toBytes = function () { + return keys.public + }; + + type Point = any; + + const blankBN = { + toBytes: () => { return new Uint8Array() }, + toArray: () => { return [] } + }; + + this.data = { + getSecret: () => { return keys.private }, + getPrivate: () => { return keys.private }, + getPublic: (enc?: "hex" | "der"): number[] | string | Point => { + if (enc === "hex") { + return Convert.ToHex(keys.public); + } else if (enc === "der") { + return Uint8Array.from(keys.public); + } else { + return keys.public; + } + }, + priv: keys.private, + pub: { + x: pubBigNum, y: blankBN + }, + sign: (data: number[]) => { return false }, + verify: (data: number[], signature: string | object): boolean => { return false }, + derive: (point: any) => { return blankBN } + + }; } return this; diff --git a/test/ed.ts b/test/ed.ts index 0da4da9..d4ea869 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -178,10 +178,10 @@ context("ECDH_ES", () => { let pKLiner = await liner.subtle.exportKey("jwk", linerPublicKey); assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); - assert.deepStrictEqual( + /*assert.deepStrictEqual( Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).reverse().toString("hex") - ) + )*/ }); }); diff --git a/tsconfig.json b/tsconfig.json index f7e916c..70f79f9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "outDir": "build", "importHelpers": true, "removeComments": true, - "experimentalDecorators": true + "experimentalDecorators": true, + "esModuleInterop": true, }, "exclude": [ "index.d.ts" From a3cd56c94af0eed1ad92db8f41450b9be943b339 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 15:16:05 -0400 Subject: [PATCH 07/13] potentially working --- src/mechs/ed/crypto.ts | 3 +-- src/mechs/ed/public_key.ts | 41 ++++++++++++++++++++++++++++++++++---- test/ed.ts | 8 ++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index 927b2bf..4f18dad 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -103,8 +103,7 @@ export class EdCrypto { public static async exportKey(format: KeyFormat, key: EdPrivateKey | EdPublicKey): Promise { this.checkLib(); - //TODO x25519 - + switch (format.toLowerCase()) { case "jwk": return JsonSerializer.toJSON(key); diff --git a/src/mechs/ed/public_key.ts b/src/mechs/ed/public_key.ts index 4c6cf08..f4483d1 100644 --- a/src/mechs/ed/public_key.ts +++ b/src/mechs/ed/public_key.ts @@ -1,10 +1,8 @@ -import { AsnConvert } from "@peculiar/asn1-schema"; import { IJsonConvertible } from "@peculiar/json-schema"; import * as elliptic from "elliptic"; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; import { CryptoKey } from "../../key"; -import { getOidByNamedCurve } from "./helper"; export class EdPublicKey extends CryptoKey implements IJsonConvertible { @@ -40,8 +38,43 @@ export class EdPublicKey extends CryptoKey implements IJsonConvertible { const eddsa = new elliptic.eddsa(json.crv.toLowerCase()); this.data = eddsa.keyFromPublic(hexPublicKey, "hex"); } else { - const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); - this.data = ecdhEs.keyFromPublic(hexPublicKey, "hex"); + const keys = { public: new Uint8Array(Convert.FromBase64Url(json.x)), private: null }; + const pubBigNum: EllipticJS.BN = { + toBytes: () => { return keys.public }, + toArray: () => { return Array.from(keys.public) } + } + pubBigNum.toBytes = function () { + return keys.public + }; + + type Point = any; + + const blankBN = { + toBytes: () => { return new Uint8Array() }, + toArray: () => { return [] } + }; + + this.data = { + getSecret: () => { return keys.private }, + getPrivate: () => { return keys.private }, + getPublic: (enc?: "hex" | "der"): number[] | string | Point => { + if (enc === "hex") { + return Convert.ToHex(keys.public); + } else if (enc === "der") { + return Uint8Array.from(keys.public); + } else { + return keys.public; + } + }, + priv: keys.private, + pub: { + x: pubBigNum, y: blankBN + }, + sign: (data: number[]) => { return false }, + verify: (data: number[], signature: string | object): boolean => { return false }, + derive: (point: any) => { return blankBN } + + }; } return this; diff --git a/test/ed.ts b/test/ed.ts index d4ea869..3bd813f 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -176,8 +176,12 @@ context("ECDH_ES", () => { let pKNode = await crypto.subtle.exportKey("jwk", nodePublicKey); let pKLiner = await liner.subtle.exportKey("jwk", linerPublicKey); - assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); - assert.deepStrictEqual(Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex"), "e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950"); + /* console.log(pKLiner); + / assert.deepStrictEqual(JSON.stringify(pKLiner), false); + assert.deepStrictEqual(Convert.FromBase64Url(publicJwk.x), false);*/ + assert.deepStrictEqual( + Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), + Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex")); /*assert.deepStrictEqual( Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).reverse().toString("hex") From 2edd42870b569bbd0f25bfed72cb21d6686d0aa6 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 15:38:59 -0400 Subject: [PATCH 08/13] deriveBits works --- src/mechs/ed/crypto.ts | 17 ++++++----------- src/mechs/ed/private_key.ts | 13 +++++++++++-- test/ed.ts | 6 +++--- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index 4f18dad..ff69a94 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -86,24 +86,19 @@ export class EdCrypto { public static async deriveBits(algorithm: EcdhKeyDeriveParams, baseKey: EdPrivateKey, length: number): Promise { this.checkLib(); + const publicArray = Convert.FromBase64Url((await crypto.subtle.exportKey("jwk", algorithm.public)).x); + const privateArray = Convert.FromBase64Url(((baseKey.toJSON()).d)); - const publicKeyHex = (await crypto.subtle.exportKey("jwk", algorithm.public)).x; - const privateKeyHex = (baseKey.toJSON()).d; + const publicUint8 = new Uint8Array(publicArray); + const privateUint8 = new Uint8Array(privateArray); - const cU8 = (h) => { - let nBuf: Buffer = Buffer.alloc(32); - let hex: ArrayBuffer = Convert.FromBase64Url(h); - let hexString: string = Buffer.from(hex, 0).toString("hex"); - nBuf.write(hexString, 0); - return nBuf; - } - const buf = sharedKey(cU8(privateKeyHex), cU8(publicKeyHex)); + const buf = sharedKey(privateUint8, publicUint8); return buf; } public static async exportKey(format: KeyFormat, key: EdPrivateKey | EdPublicKey): Promise { this.checkLib(); - + switch (format.toLowerCase()) { case "jwk": return JsonSerializer.toJSON(key); diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index 0a60bf8..ddb1c3c 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -59,9 +59,18 @@ export class EdPrivateKey extends CryptoKey implements IJsonConvertible { toArray: () => { return [] } }; + const pF = (enc: any) => { + if (enc === "hex") { + return Convert.ToHex(keys.private); + } else if (enc === "der") { + return Uint8Array.from(keys.private); + } else { + return keys.private; + } + }; this.data = { - getSecret: () => { return keys.private }, - getPrivate: () => { return keys.private }, + getSecret: pF, + getPrivate: pF, getPublic: (enc?: "hex" | "der"): number[] | string | Point => { if (enc === "hex") { return Convert.ToHex(keys.public); diff --git a/test/ed.ts b/test/ed.ts index 3bd813f..aca5713 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -182,10 +182,10 @@ context("ECDH_ES", () => { assert.deepStrictEqual( Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex")); - /*assert.deepStrictEqual( + assert.deepStrictEqual( Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), - Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).reverse().toString("hex") - )*/ + Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).toString("hex") + ) }); }); From 146f49e4fc84dddfc0e634c1453c1ec2cdbba8f1 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 15:40:30 -0400 Subject: [PATCH 09/13] removed doc --- src/mechs/ed/crypto.ts | 4 ++-- src/mechs/ed/private_key.ts | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index ff69a94..5c04155 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -1,7 +1,7 @@ import { AsnConvert, OctetString } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as elliptic from "elliptic"; -import { sharedKey, generateKeyPair } from 'curve25519-js'; +import { sharedKey } from 'curve25519-js'; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; import { nativeCrypto } from "../../native"; @@ -16,7 +16,7 @@ export class EdCrypto { public static privateKeyUsages = ["sign", "deriveKey", "deriveBits"]; public static checkLib() { - if (typeof (elliptic) === "undefined") { + if (typeof (elliptic) === "undefined" || typeof (sharedKey) === "undefined") { throw new core.OperationError("Cannot implement EC mechanism. Add 'https://peculiarventures.github.io/pv-webcrypto-tests/src/elliptic.js' script to your project"); } } diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index ddb1c3c..229494e 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -40,9 +40,6 @@ export class EdPrivateKey extends CryptoKey implements IJsonConvertible { const eddsa = new elliptic.eddsa(json.crv.toLowerCase()); this.data = eddsa.keyFromSecret(hexPrivateKey); } else { - //TODO x25519 - // const ecdhEs = elliptic.ec(json.crv.replace(/^x/i, "curve")); - // this.data = ecdhEs.keyFromPrivate(hexPrivateKey, "hex"); const keys = generateKeyPair(new Uint8Array(Convert.FromBase64Url(json.d))); const pubBigNum: EllipticJS.BN = { toBytes: () => { return keys.public }, From 42097b0092e0d387d859b54ae877cf75db27f044 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 15:45:31 -0400 Subject: [PATCH 10/13] start work on generateKeys --- src/mechs/ed/private_key.ts | 4 +- test/ed.ts | 122 ++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 64 deletions(-) diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index 229494e..f2cf751 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -2,10 +2,8 @@ import { IJsonConvertible } from "@peculiar/json-schema"; import * as core from "webcrypto-core"; import { CryptoKey } from "../../key"; import * as elliptic from "elliptic"; -import { sharedKey, generateKeyPair } from 'curve25519-js'; -import BN from "bn.js"; +import { generateKeyPair } from 'curve25519-js'; import { Convert } from "pvtsutils"; -import { Any } from "asn1js"; export class EdPrivateKey extends CryptoKey implements IJsonConvertible { public algorithm!: EcKeyAlgorithm; diff --git a/test/ed.ts b/test/ed.ts index aca5713..438732f 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -5,7 +5,7 @@ import { Crypto } from "../src"; const crypto = new NodeCrypto(); const liner = new Crypto(); -/* + context("ED", () => { context("generate/export/import/sign/verify", () => { @@ -81,72 +81,72 @@ context("ED", () => { }); -*/ + context("ECDH_ES", () => { context("generate/export/import/sign/verify", () => { const alg = { name: "ECDH-ES", namedCurve: "x25519" }; const data = Buffer.from("Some message to sign"); /* - it("pkcs8/spki", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); - const spki = await liner.subtle.exportKey("spki", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); - - assert.deepStrictEqual( - await crypto.subtle.exportKey("pkcs8", nodePrivateKey), - await liner.subtle.exportKey("pkcs8", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("spki", nodePublicKey), - await liner.subtle.exportKey("spki", linerPublicKey) - ); - - }); - - it("jwk", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); - const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); - assert.deepStrictEqual( - await crypto.subtle.exportKey("jwk", nodePrivateKey), - await liner.subtle.exportKey("jwk", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("jwk", nodePublicKey), - await liner.subtle.exportKey("jwk", linerPublicKey) - ); - - }); - - it("pkcs8/raw", async () => { - const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); - const raw = await liner.subtle.exportKey("raw", linerKeys.publicKey); - - const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const nodePublicKey = await crypto.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); - const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); - const linerPublicKey = await liner.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); - assert.deepStrictEqual( - await crypto.subtle.exportKey("pkcs8", nodePrivateKey), - await liner.subtle.exportKey("pkcs8", linerPrivateKey) - ); - assert.deepStrictEqual( - await crypto.subtle.exportKey("raw", nodePublicKey), - await liner.subtle.exportKey("raw", linerPublicKey) - ); - }); + it("pkcs8/spki", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const spki = await liner.subtle.exportKey("spki", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("spki", spki, alg, true, ["deriveKey"]); + + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("spki", nodePublicKey), + await liner.subtle.exportKey("spki", linerPublicKey) + ); + + }); + + it("jwk", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); + const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePrivateKey), + await liner.subtle.exportKey("jwk", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("jwk", nodePublicKey), + await liner.subtle.exportKey("jwk", linerPublicKey) + ); + + }); + + it("pkcs8/raw", async () => { + const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); + const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); + const raw = await liner.subtle.exportKey("raw", linerKeys.publicKey); + + const nodePrivateKey = await crypto.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const nodePublicKey = await crypto.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + const linerPrivateKey = await liner.subtle.importKey("pkcs8", pkcs8, alg, true, ["deriveBits"]); + const linerPublicKey = await liner.subtle.importKey("raw", raw, alg, true, ["deriveKey"]); + assert.deepStrictEqual( + await crypto.subtle.exportKey("pkcs8", nodePrivateKey), + await liner.subtle.exportKey("pkcs8", linerPrivateKey) + ); + assert.deepStrictEqual( + await crypto.subtle.exportKey("raw", nodePublicKey), + await liner.subtle.exportKey("raw", linerPublicKey) + ); + }); */ it("deriveBits", async () => { const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); From fc134e005ee19183b33ffaab99aa20da9b67165d Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 17:07:33 -0400 Subject: [PATCH 11/13] refactor generateEllipticKeys --- src/mechs/ed/helper.ts | 54 +++++++++++++++++++++++++++++++++++++ src/mechs/ed/private_key.ts | 48 ++------------------------------- src/mechs/ed/public_key.ts | 38 ++------------------------ test/ed.ts | 28 +++++-------------- 4 files changed, 64 insertions(+), 104 deletions(-) diff --git a/src/mechs/ed/helper.ts b/src/mechs/ed/helper.ts index e9482ab..6ef0a14 100644 --- a/src/mechs/ed/helper.ts +++ b/src/mechs/ed/helper.ts @@ -1,4 +1,6 @@ import * as core from "webcrypto-core"; +import { generateKeyPair } from 'curve25519-js'; +import { Convert } from "pvtsutils"; const edOIDs: { [key: string]: string } = { // Ed448 @@ -30,3 +32,55 @@ export function getOidByNamedCurve(namedCurve: string) { } return oid; } + +export function generateEllipticKeys(seed?: any, keys?: any) { + if (seed) { + keys = generateKeyPair(seed); + } + + const pubBigNum: EllipticJS.BN = { + toBytes: () => { return keys.public }, + toArray: () => { return Array.from(keys.public) } + } + pubBigNum.toBytes = function () { + return keys.public + }; + + type Point = any; + + const blankBN = { + toBytes: () => { return new Uint8Array() }, + toArray: () => { return [] } + }; + + const pF = (enc: any) => { + if (enc === "hex") { + return Convert.ToHex(keys.private); + } else if (enc === "der") { + return Uint8Array.from(keys.private); + } else { + return keys.private; + } + }; + return { + getSecret: pF, + getPrivate: pF, + getPublic: (enc?: "hex" | "der"): number[] | string | Point => { + if (enc === "hex") { + return Convert.ToHex(keys.public); + } else if (enc === "der") { + return Uint8Array.from(keys.public); + } else { + return keys.public; + } + }, + priv: keys.private, + pub: { + x: pubBigNum, y: blankBN + }, + sign: (data: number[]) => { return false }, + verify: (data: number[], signature: string | object): boolean => { return false }, + derive: (point: any) => { return blankBN } + + }; +} \ No newline at end of file diff --git a/src/mechs/ed/private_key.ts b/src/mechs/ed/private_key.ts index f2cf751..ef23af4 100644 --- a/src/mechs/ed/private_key.ts +++ b/src/mechs/ed/private_key.ts @@ -4,6 +4,7 @@ import { CryptoKey } from "../../key"; import * as elliptic from "elliptic"; import { generateKeyPair } from 'curve25519-js'; import { Convert } from "pvtsutils"; +import { generateEllipticKeys } from "./helper"; export class EdPrivateKey extends CryptoKey implements IJsonConvertible { public algorithm!: EcKeyAlgorithm; @@ -38,52 +39,7 @@ export class EdPrivateKey extends CryptoKey implements IJsonConvertible { const eddsa = new elliptic.eddsa(json.crv.toLowerCase()); this.data = eddsa.keyFromSecret(hexPrivateKey); } else { - const keys = generateKeyPair(new Uint8Array(Convert.FromBase64Url(json.d))); - const pubBigNum: EllipticJS.BN = { - toBytes: () => { return keys.public }, - toArray: () => { return Array.from(keys.public) } - } - pubBigNum.toBytes = function () { - return keys.public - }; - - type Point = any; - - const blankBN = { - toBytes: () => { return new Uint8Array() }, - toArray: () => { return [] } - }; - - const pF = (enc: any) => { - if (enc === "hex") { - return Convert.ToHex(keys.private); - } else if (enc === "der") { - return Uint8Array.from(keys.private); - } else { - return keys.private; - } - }; - this.data = { - getSecret: pF, - getPrivate: pF, - getPublic: (enc?: "hex" | "der"): number[] | string | Point => { - if (enc === "hex") { - return Convert.ToHex(keys.public); - } else if (enc === "der") { - return Uint8Array.from(keys.public); - } else { - return keys.public; - } - }, - priv: keys.private, - pub: { - x: pubBigNum, y: blankBN - }, - sign: (data: number[]) => { return false }, - verify: (data: number[], signature: string | object): boolean => { return false }, - derive: (point: any) => { return blankBN } - - }; + this.data = generateEllipticKeys(new Uint8Array(Convert.FromBase64Url(json.d))); } return this; diff --git a/src/mechs/ed/public_key.ts b/src/mechs/ed/public_key.ts index f4483d1..baecefa 100644 --- a/src/mechs/ed/public_key.ts +++ b/src/mechs/ed/public_key.ts @@ -3,6 +3,7 @@ import * as elliptic from "elliptic"; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; import { CryptoKey } from "../../key"; +import { generateEllipticKeys } from "./helper"; export class EdPublicKey extends CryptoKey implements IJsonConvertible { @@ -38,43 +39,8 @@ export class EdPublicKey extends CryptoKey implements IJsonConvertible { const eddsa = new elliptic.eddsa(json.crv.toLowerCase()); this.data = eddsa.keyFromPublic(hexPublicKey, "hex"); } else { - const keys = { public: new Uint8Array(Convert.FromBase64Url(json.x)), private: null }; - const pubBigNum: EllipticJS.BN = { - toBytes: () => { return keys.public }, - toArray: () => { return Array.from(keys.public) } - } - pubBigNum.toBytes = function () { - return keys.public - }; - type Point = any; - - const blankBN = { - toBytes: () => { return new Uint8Array() }, - toArray: () => { return [] } - }; - - this.data = { - getSecret: () => { return keys.private }, - getPrivate: () => { return keys.private }, - getPublic: (enc?: "hex" | "der"): number[] | string | Point => { - if (enc === "hex") { - return Convert.ToHex(keys.public); - } else if (enc === "der") { - return Uint8Array.from(keys.public); - } else { - return keys.public; - } - }, - priv: keys.private, - pub: { - x: pubBigNum, y: blankBN - }, - sign: (data: number[]) => { return false }, - verify: (data: number[], signature: string | object): boolean => { return false }, - derive: (point: any) => { return blankBN } - - }; + this.data = generateEllipticKeys(null, { public: new Uint8Array(Convert.FromBase64Url(json.x)), private: null }); } return this; diff --git a/test/ed.ts b/test/ed.ts index 438732f..d13b4c2 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -150,24 +150,8 @@ context("ECDH_ES", () => { */ it("deriveBits", async () => { const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); - - const privateJwk = { - kty: "OKP", - crv: "X25519", - key_ops: ["deriveBits"], - ext: true, - d: "YP_Dbf6rotbZd-2gBwSIdr_MM8ZKiAG33CPvOHo97WI" - // d(hex): 60ffc36dfeaba2d6d977eda007048876bfcc33c64a8801b7dc23ef387a3ded62 - }; - - const publicJwk = { - kty: "OKP", - crv: "X25519", - key_ops: [], - ext: true, - x: "4fMe1l0XMe8q8pf3V8Eyz8GSChoLfULmrr0dAHK0uVA" - // x(hex): e1f31ed65d1731ef2af297f757c132cfc1920a1a0b7d42e6aebd1d0072b4b950 - }; + const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey); + const publicJwk = await liner.subtle.exportKey("jwk", linerKeys.publicKey); const nodePrivateKey = await crypto.subtle.importKey("jwk", privateJwk, alg, true, ["deriveBits"]); const nodePublicKey = await crypto.subtle.importKey("jwk", publicJwk, alg, true, ["deriveKey"]); @@ -176,16 +160,16 @@ context("ECDH_ES", () => { let pKNode = await crypto.subtle.exportKey("jwk", nodePublicKey); let pKLiner = await liner.subtle.exportKey("jwk", linerPublicKey); - /* console.log(pKLiner); - / assert.deepStrictEqual(JSON.stringify(pKLiner), false); - assert.deepStrictEqual(Convert.FromBase64Url(publicJwk.x), false);*/ + assert.deepStrictEqual( Buffer.from(Convert.FromBase64Url(pKNode.x)).toString("hex"), Buffer.from(Convert.FromBase64Url(pKLiner.x)).toString("hex")); + assert.deepStrictEqual( Buffer.from(await crypto.subtle.deriveBits({ name: "ECDH-ES", public: nodePublicKey }, nodePrivateKey, 256)).toString("hex"), Buffer.from(await liner.subtle.deriveBits({ name: "ECDH-ES", public: linerPublicKey }, linerPrivateKey, 256)).toString("hex") - ) + ); + }); }); From e6c9ee1eb2151b0f6224142650352c262484542d Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 17:11:17 -0400 Subject: [PATCH 12/13] update keygen --- src/mechs/ed/crypto.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mechs/ed/crypto.ts b/src/mechs/ed/crypto.ts index 5c04155..197d35a 100644 --- a/src/mechs/ed/crypto.ts +++ b/src/mechs/ed/crypto.ts @@ -9,6 +9,7 @@ import { b2a } from "../ec"; import { getOidByNamedCurve } from "./helper"; import { EdPrivateKey } from "./private_key"; import { EdPublicKey } from "./public_key"; +import { generateEllipticKeys } from "./helper"; export class EdCrypto { @@ -38,13 +39,12 @@ export class EdCrypto { const curve = algorithm.namedCurve.toLowerCase() === "x25519" ? "curve25519" : "ed25519"; // "x25519" | "ed25519" let edKey: EllipticJS.EllipticKeyPair; + const raw = nativeCrypto.getRandomValues(new Uint8Array(32)); if (curve === "ed25519") { - const raw = nativeCrypto.getRandomValues(new Uint8Array(32)); const eddsa = new elliptic.eddsa(curve); edKey = eddsa.keyFromSecret(raw); } else if (curve === "curve25519") { - edKey = elliptic.ec(curve).genKeyPair(); - edKey.getPublic(); // Fills internal `pub` field + edKey = generateEllipticKeys(raw); } // set key params From d5fe2964c803f40468d778e989c95356556c9c73 Mon Sep 17 00:00:00 2001 From: tj Date: Thu, 22 Jul 2021 17:12:14 -0400 Subject: [PATCH 13/13] tests passing --- test/ed.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ed.ts b/test/ed.ts index d13b4c2..cadba19 100644 --- a/test/ed.ts +++ b/test/ed.ts @@ -87,7 +87,7 @@ context("ECDH_ES", () => { context("generate/export/import/sign/verify", () => { const alg = { name: "ECDH-ES", namedCurve: "x25519" }; const data = Buffer.from("Some message to sign"); - /* + /* */ it("pkcs8/spki", async () => { const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); const pkcs8 = await liner.subtle.exportKey("pkcs8", linerKeys.privateKey); @@ -147,7 +147,7 @@ context("ECDH_ES", () => { await liner.subtle.exportKey("raw", linerPublicKey) ); }); - */ + it("deriveBits", async () => { const linerKeys = await liner.subtle.generateKey(alg, true, ["deriveBits", "deriveKey"]); const privateJwk = await liner.subtle.exportKey("jwk", linerKeys.privateKey);