@yoursunny/webcrypto-ed25519
Advanced tools
Comparing version 0.0.20220530 to 0.0.20220623
@@ -5,2 +5,6 @@ import * as ed from "@noble/ed25519"; | ||
import { toBase64Url as b64encode, toBuffer as b64decode } from "b64u-lite"; | ||
import { C, isEd25519Algorithm } from "./common.js"; | ||
export const Ed25519Algorithm = { | ||
name: C.wicgAlgorithm, | ||
}; | ||
function asUint8Array(b) { | ||
@@ -21,9 +25,2 @@ if (b instanceof Uint8Array) { | ||
} | ||
const C = { | ||
algorithm: "NODE-ED25519", | ||
namedCurve: "NODE-ED25519", | ||
kty: "OKP", | ||
crv: "Ed25519", | ||
oid: "2B6570".toLowerCase(), | ||
}; | ||
const slot = "8d9df0f7-1363-4d2c-8152-ce4ed78f27d8"; | ||
@@ -44,3 +41,3 @@ class Ponyfill { | ||
async generateKey(algorithm, extractable, keyUsages) { | ||
if (algorithm.name === C.algorithm && algorithm.namedCurve === C.namedCurve) { | ||
if (isEd25519Algorithm(algorithm)) { | ||
const pvt = ed.utils.randomPrivateKey(); | ||
@@ -68,3 +65,3 @@ const pub = await ed.getPublicKey(pvt); | ||
async exportKey(format, key) { | ||
if (key.algorithm.name === C.algorithm && key.extractable) { | ||
if (isEd25519Algorithm(key.algorithm) && key.extractable) { | ||
const raw = key[slot]; | ||
@@ -100,3 +97,3 @@ switch (format) { | ||
async importKey(format, keyData, algorithm, extractable, keyUsages) { | ||
if (algorithm.name === C.algorithm && algorithm.namedCurve === C.namedCurve) { | ||
if (isEd25519Algorithm(algorithm)) { | ||
const usages = Array.from(keyUsages); | ||
@@ -139,3 +136,3 @@ switch (format) { | ||
async sign(algorithm, key, data) { | ||
if (algorithm === C.algorithm && key.algorithm.name === C.algorithm && key.type === "private" && key.usages.includes("sign")) { | ||
if (isEd25519Algorithm(algorithm) && isEd25519Algorithm(key.algorithm) && key.type === "private" && key.usages.includes("sign")) { | ||
return asArrayBuffer(await ed.sign(asUint8Array(data), key[slot])); | ||
@@ -146,3 +143,3 @@ } | ||
async verify(algorithm, key, signature, data) { | ||
if (algorithm === C.algorithm && key.algorithm.name === C.algorithm && key.type === "public" && key.usages.includes("verify")) { | ||
if (isEd25519Algorithm(algorithm) && isEd25519Algorithm(key.algorithm) && key.type === "public" && key.usages.includes("verify")) { | ||
return ed.verify(asUint8Array(signature), asUint8Array(data), key[slot]); | ||
@@ -149,0 +146,0 @@ } |
@@ -6,2 +6,8 @@ import * as ed from "@noble/ed25519"; | ||
import { C, isEd25519Algorithm } from "./common.js"; | ||
export const Ed25519Algorithm: KeyAlgorithm = { | ||
name: C.wicgAlgorithm, | ||
}; | ||
function asUint8Array(b: BufferSource): Uint8Array { | ||
@@ -24,10 +30,2 @@ if (b instanceof Uint8Array) { | ||
const C = { | ||
algorithm: "NODE-ED25519", | ||
namedCurve: "NODE-ED25519", | ||
kty: "OKP", | ||
crv: "Ed25519", | ||
oid: "2B6570".toLowerCase(), | ||
}; | ||
const slot = "8d9df0f7-1363-4d2c-8152-ce4ed78f27d8"; | ||
@@ -53,4 +51,4 @@ | ||
public async generateKey(algorithm: EcKeyGenParams, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKeyPair> { | ||
if (algorithm.name === C.algorithm && algorithm.namedCurve === C.namedCurve) { | ||
public async generateKey(algorithm: KeyAlgorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKeyPair> { | ||
if (isEd25519Algorithm(algorithm)) { | ||
const pvt = ed.utils.randomPrivateKey(); | ||
@@ -80,3 +78,3 @@ const pub = await ed.getPublicKey(pvt); | ||
public async exportKey(format: KeyFormat, key: CryptoKey): Promise<JsonWebKey | ArrayBuffer> { | ||
if (key.algorithm.name === C.algorithm && key.extractable) { | ||
if (isEd25519Algorithm(key.algorithm) && key.extractable) { | ||
const raw = (key as Ed25519CryptoKey)[slot]; | ||
@@ -111,4 +109,4 @@ switch (format) { | ||
public async importKey(format: KeyFormat, keyData: JsonWebKey | BufferSource, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey> { | ||
if (algorithm.name === C.algorithm && algorithm.namedCurve === C.namedCurve) { | ||
public async importKey(format: KeyFormat, keyData: JsonWebKey | BufferSource, algorithm: Algorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey> { | ||
if (isEd25519Algorithm(algorithm)) { | ||
const usages = Array.from(keyUsages); | ||
@@ -153,3 +151,3 @@ switch (format) { | ||
public async sign(algorithm: AlgorithmIdentifier, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer> { | ||
if (algorithm === C.algorithm && key.algorithm.name === C.algorithm && key.type === "private" && key.usages.includes("sign")) { | ||
if (isEd25519Algorithm(algorithm) && isEd25519Algorithm(key.algorithm) && key.type === "private" && key.usages.includes("sign")) { | ||
return asArrayBuffer(await ed.sign(asUint8Array(data), (key as Ed25519CryptoKey)[slot])); | ||
@@ -161,3 +159,3 @@ } | ||
public async verify(algorithm: AlgorithmIdentifier, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean> { | ||
if (algorithm === C.algorithm && key.algorithm.name === C.algorithm && key.type === "public" && key.usages.includes("verify")) { | ||
if (isEd25519Algorithm(algorithm) && isEd25519Algorithm(key.algorithm) && key.type === "public" && key.usages.includes("verify")) { | ||
return ed.verify(asUint8Array(signature), asUint8Array(data), (key as Ed25519CryptoKey)[slot]); | ||
@@ -164,0 +162,0 @@ } |
11
index.js
@@ -0,1 +1,12 @@ | ||
import { version as nodeVersion } from "node:process"; | ||
import compareVersions from 'compare-versions'; | ||
import { C } from "./common.js"; | ||
const wicgKeyAlgorithm = { | ||
name: C.wicgAlgorithm, | ||
}; | ||
const nodeKeyAlgorithm = { | ||
name: C.nodeAlgorithm, | ||
namedCurve: C.nodeNamedCurve | ||
}; | ||
export const Ed25519Algorithm = compareVersions(nodeVersion, "18.4.0") >= 0 ? wicgKeyAlgorithm : nodeKeyAlgorithm; | ||
export function ponyfillEd25519(subtle = crypto.subtle) { | ||
@@ -2,0 +13,0 @@ return subtle; |
16
index.ts
@@ -0,1 +1,17 @@ | ||
import compareVersions from "compare-versions"; | ||
import { version as nodeVersion } from "node:process"; | ||
import { C } from "./common.js"; | ||
const wicgKeyAlgorithm: KeyAlgorithm = { | ||
name: C.wicgAlgorithm, | ||
}; | ||
const nodeKeyAlgorithm: EcKeyAlgorithm = { | ||
name: C.nodeAlgorithm, | ||
namedCurve: C.nodeNamedCurve, | ||
}; | ||
export const Ed25519Algorithm: KeyAlgorithm = compareVersions(nodeVersion, "18.4.0") >= 0 ? wicgKeyAlgorithm : nodeKeyAlgorithm; | ||
export function ponyfillEd25519(subtle = crypto.subtle): SubtleCrypto { | ||
@@ -2,0 +18,0 @@ return subtle; |
{ | ||
"name": "@yoursunny/webcrypto-ed25519", | ||
"version": "0.0.20220530", | ||
"version": "0.0.20220623", | ||
"description": "Ed25519 Ponyfill & Polyfill for WebCrypto", | ||
@@ -11,2 +11,3 @@ "keywords": [ | ||
"Ed25519", | ||
"NODE-ED25519", | ||
"RFC8032", | ||
@@ -18,2 +19,3 @@ "RFC8037" | ||
"files": [ | ||
"common.*", | ||
"index.*", | ||
@@ -26,16 +28,17 @@ "browser.*" | ||
"types": "index.d.ts", | ||
"packageManager": "pnpm@7.1.7", | ||
"packageManager": "pnpm@7.3.0", | ||
"dependencies": { | ||
"@noble/ed25519": "^1.6.0", | ||
"@yoursunny/asn1": "^0.0.20200718", | ||
"b64u-lite": "^1.1.0" | ||
"@yoursunny/asn1": "0.0.20200718", | ||
"b64u-lite": "^1.1.0", | ||
"compare-versions": "^4.1.3" | ||
}, | ||
"devDependencies": { | ||
"@types/minimalistic-assert": "^1.0.1", | ||
"@types/node": "^17.0.36", | ||
"@types/node": "^18.0.0", | ||
"@yoursunny/xo-config": "^0.49.0", | ||
"minimalistic-assert": "^1.0.1", | ||
"typescript": "^4.7.2", | ||
"webpack": "^5.72.1", | ||
"webpack-cli": "^4.9.2" | ||
"typescript": "^4.7.4", | ||
"webpack": "^5.73.0", | ||
"webpack-cli": "^4.10.0" | ||
}, | ||
@@ -42,0 +45,0 @@ "scripts": { |
@@ -14,28 +14,33 @@ # Ed25519 Ponyfill & Polyfill for WebCrypto | ||
```js | ||
import { polyfillEd25519, ponyfillEd25519 } from "@yoursunny/webcrypto-ed25519"; | ||
import { Ed25519Algorithm, polyfillEd25519, ponyfillEd25519 } from "@yoursunny/webcrypto-ed25519"; | ||
// ponyfill: crypto.subtle remains unchanged; call methods on the returned SubtleCrypto instance. | ||
const subtlePonyfill = ponyfillEd25519(); | ||
subtlePonyfill.generateKey({ name: "NODE-ED25519", namedCurve: "NODE-ED25519" }, | ||
true, ["sign", "verify"]); | ||
subtlePonyfill.generateKey(Ed25519Algorithm, true, ["sign", "verify"]); | ||
// polyfill: crypto.subtle is patched to support NODE-ED25519 algorithm. | ||
// polyfill: crypto.subtle is patched to support Ed25519 and NODE-ED25519 algorithms. | ||
polyfillEd25519(); | ||
crypto.subtle.generateKey({ name: "NODE-ED25519", namedCurve: "NODE-ED25519" }, | ||
true, ["sign", "verify"]); | ||
crypto.subtle.generateKey(Ed25519Algorithm, true, ["sign", "verify"]); | ||
``` | ||
## Algorithm Identifier | ||
The ponyfill and polyfill for browser recognize two forms of algorithm identifier: | ||
* `{ name: "Ed25519" }`, as specified in [Secure Curves in the Web Cryptography API](https://wicg.github.io/webcrypto-secure-curves/) draft and implemented in Node.js 18.4.0 and later. | ||
* `{ name: "NODE-ED25519", namedCurve: "NODE-ED25519" }`, as implemented in Node.js 18.3.0 and earlier. | ||
This package does not provide any ponyfill or polyfill for Node.js. | ||
The exported `Ed25519Algorithm` variable gives a suitable algorithm identifier for the current Node.js version, which helps you writing code to support Node.js before and after 18.4.0. | ||
## Features | ||
* `subtle.generateKey`: | ||
* algorithm: `{ name: "NODE-ED25519", namedCurve: "NODE-ED25519" }` | ||
* `subtle.exportKey`: | ||
* `subtle.generateKey` | ||
* `subtle.exportKey` | ||
* format: `"jwk"` or `"spki"` | ||
* `subtle.importKey`: | ||
* `subtle.importKey` | ||
* format: `"jwk"` or `"spki"` | ||
* `subtle.sign`: | ||
* algorithm: `"NODE-ED25519"` | ||
* `subtle.verify`: | ||
* algorithm: `"NODE-ED25519"` | ||
* `subtle.sign` | ||
* `subtle.verify` | ||
All other methods and non-Ed25519 keys are passed to the original `SubtleCrypto` implementation. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
23897
12
364
46
4
+ Addedcompare-versions@^4.1.3
+ Addedcompare-versions@4.1.4(transitive)
Updated@yoursunny/asn1@0.0.20200718