Comparing version 0.4.10 to 0.4.11
@@ -0,2 +1,20 @@ | ||
/** | ||
* Encrypts a message. | ||
* @description From version 0.5.0, `Uint8Array` will be returned instead of `Buffer`. | ||
* To keep the same behavior, use `Buffer.from(encrypt(...))`. | ||
* | ||
* @param receiverRawPK - Raw public key of the receiver, either as a hex string or a Uint8Array. | ||
* @param msg - Message to encrypt. | ||
* @returns Encrypted payload, format: `public key || encrypted`. | ||
*/ | ||
export declare function encrypt(receiverRawPK: string | Uint8Array, msg: Uint8Array): Buffer; | ||
/** | ||
* Decrypts a message. | ||
* @description From version 0.5.0, `Uint8Array` will be returned instead of `Buffer`. | ||
* To keep the same behavior, use `Buffer.from(decrypt(...))`. | ||
* | ||
* @param receiverRawSK - Raw private key of the receiver, either as a hex string or a Uint8Array. | ||
* @param msg - Message to decrypt. | ||
* @returns Decrypted plain text. | ||
*/ | ||
export declare function decrypt(receiverRawSK: string | Uint8Array, msg: Uint8Array): Buffer; | ||
@@ -7,6 +25,6 @@ export { ECIES_CONFIG } from "./config"; | ||
export declare const utils: { | ||
aesEncrypt: (key: Uint8Array, plainText: Uint8Array) => Uint8Array; | ||
aesDecrypt: (key: Uint8Array, cipherText: Uint8Array) => Uint8Array; | ||
symEncrypt: (key: Uint8Array, plainText: Uint8Array) => Uint8Array; | ||
symDecrypt: (key: Uint8Array, cipherText: Uint8Array) => Uint8Array; | ||
aesEncrypt: (key: Uint8Array, plainText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
aesDecrypt: (key: Uint8Array, cipherText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
symEncrypt: (key: Uint8Array, plainText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
symDecrypt: (key: Uint8Array, cipherText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
decodeHex: (hex: string) => Uint8Array; | ||
@@ -13,0 +31,0 @@ getValidSecret: () => Uint8Array; |
@@ -10,18 +10,32 @@ "use strict"; | ||
var utils_2 = require("./utils"); | ||
/** | ||
* Encrypts a message. | ||
* @description From version 0.5.0, `Uint8Array` will be returned instead of `Buffer`. | ||
* To keep the same behavior, use `Buffer.from(encrypt(...))`. | ||
* | ||
* @param receiverRawPK - Raw public key of the receiver, either as a hex string or a Uint8Array. | ||
* @param msg - Message to encrypt. | ||
* @returns Encrypted payload, format: `public key || encrypted`. | ||
*/ | ||
function encrypt(receiverRawPK, msg) { | ||
var ephemeralKey = new keys_1.PrivateKey(); | ||
var ephemeralSK = new keys_1.PrivateKey(); | ||
var receiverPK = receiverRawPK instanceof Uint8Array | ||
? new keys_1.PublicKey(receiverRawPK) | ||
: keys_1.PublicKey.fromHex(receiverRawPK); | ||
var symKey = ephemeralKey.encapsulate(receiverPK); | ||
var encrypted = (0, utils_2.symEncrypt)(symKey, msg); | ||
var pk; | ||
if ((0, config_1.isEphemeralKeyCompressed)()) { | ||
pk = ephemeralKey.publicKey.compressed; | ||
} | ||
else { | ||
pk = ephemeralKey.publicKey.uncompressed; | ||
} | ||
return Buffer.from((0, utils_1.concatBytes)(pk, encrypted)); | ||
var sharedKey = ephemeralSK.encapsulate(receiverPK, (0, config_1.isHkdfKeyCompressed)()); | ||
var ephemeralPK = (0, config_1.isEphemeralKeyCompressed)() | ||
? ephemeralSK.publicKey.compressed | ||
: ephemeralSK.publicKey.uncompressed; | ||
var encrypted = (0, utils_2.symEncrypt)(sharedKey, msg); | ||
return Buffer.from((0, utils_1.concatBytes)(ephemeralPK, encrypted)); | ||
} | ||
/** | ||
* Decrypts a message. | ||
* @description From version 0.5.0, `Uint8Array` will be returned instead of `Buffer`. | ||
* To keep the same behavior, use `Buffer.from(decrypt(...))`. | ||
* | ||
* @param receiverRawSK - Raw private key of the receiver, either as a hex string or a Uint8Array. | ||
* @param msg - Message to decrypt. | ||
* @returns Decrypted plain text. | ||
*/ | ||
function decrypt(receiverRawSK, msg) { | ||
@@ -32,6 +46,6 @@ var receiverSK = receiverRawSK instanceof Uint8Array | ||
var keySize = (0, config_1.ephemeralKeySize)(); | ||
var senderPK = new keys_1.PublicKey(msg.subarray(0, keySize)); | ||
var ephemeralPK = new keys_1.PublicKey(msg.subarray(0, keySize)); | ||
var encrypted = msg.subarray(keySize); | ||
var symKey = senderPK.decapsulate(receiverSK); | ||
return Buffer.from((0, utils_2.symDecrypt)(symKey, encrypted)); | ||
var sharedKey = ephemeralPK.decapsulate(receiverSK, (0, config_1.isHkdfKeyCompressed)()); | ||
return Buffer.from((0, utils_2.symDecrypt)(sharedKey, encrypted)); | ||
} | ||
@@ -45,3 +59,3 @@ var config_2 = require("./config"); | ||
exports.utils = { | ||
// TODO: review these before 0.5.0 | ||
// TODO: remove these after 0.5.0 | ||
aesEncrypt: utils_2.aesEncrypt, | ||
@@ -48,0 +62,0 @@ aesDecrypt: utils_2.aesDecrypt, |
@@ -9,5 +9,20 @@ import { PublicKey } from "./PublicKey"; | ||
toHex(): string; | ||
encapsulate(pk: PublicKey): Uint8Array; | ||
/** | ||
* Derives a shared secret from ephemeral private key (this) and receiver's public key (pk). | ||
* @description The shared key is 32 bytes, derived with `HKDF-SHA256(senderPoint || sharedPoint)`. See implementation for details. | ||
* | ||
* There are some variations in different ECIES implementations: | ||
* which key derivation function to use, compressed or uncompressed `senderPoint`/`sharedPoint`, whether to include `senderPoint`, etc. | ||
* | ||
* Because the entropy of `senderPoint`, `sharedPoint` is enough high[1], we don't need salt to derive keys. | ||
* | ||
* [1]: Two reasons: the public keys are "random" bytes (albeit secp256k1 public keys are **not uniformly** random), and ephemeral keys are generated in every encryption. | ||
* | ||
* @param pk - Receiver's public key. | ||
* @param compressed - Whether to use compressed or uncompressed public keys in the key derivation (secp256k1 only). | ||
* @returns Shared secret, derived with HKDF-SHA256. | ||
*/ | ||
encapsulate(pk: PublicKey, compressed?: boolean): Uint8Array; | ||
multiply(pk: PublicKey, compressed?: boolean): Uint8Array; | ||
equals(other: PrivateKey): boolean; | ||
} |
@@ -5,3 +5,2 @@ "use strict"; | ||
var utils_1 = require("@noble/ciphers/utils"); | ||
var config_1 = require("../config"); | ||
var utils_2 = require("../utils"); | ||
@@ -11,8 +10,12 @@ var PublicKey_1 = require("./PublicKey"); | ||
function PrivateKey(secret) { | ||
var sk = secret === undefined ? (0, utils_2.getValidSecret)() : secret; | ||
if (!(0, utils_2.isValidPrivateKey)(sk)) { | ||
if (secret === undefined) { | ||
this.data = (0, utils_2.getValidSecret)(); | ||
} | ||
else if ((0, utils_2.isValidPrivateKey)(secret)) { | ||
this.data = secret; | ||
} | ||
else { | ||
throw new Error("Invalid private key"); | ||
} | ||
this.data = sk; | ||
this.publicKey = new PublicKey_1.PublicKey((0, utils_2.getPublicKey)(sk)); | ||
this.publicKey = new PublicKey_1.PublicKey((0, utils_2.getPublicKey)(this.data)); | ||
} | ||
@@ -33,13 +36,23 @@ PrivateKey.fromHex = function (hex) { | ||
}; | ||
PrivateKey.prototype.encapsulate = function (pk) { | ||
var senderPoint; | ||
var sharedPoint; | ||
if ((0, config_1.isHkdfKeyCompressed)()) { | ||
senderPoint = this.publicKey.compressed; | ||
sharedPoint = this.multiply(pk, true); | ||
} | ||
else { | ||
senderPoint = this.publicKey.uncompressed; | ||
sharedPoint = this.multiply(pk, false); | ||
} | ||
/** | ||
* Derives a shared secret from ephemeral private key (this) and receiver's public key (pk). | ||
* @description The shared key is 32 bytes, derived with `HKDF-SHA256(senderPoint || sharedPoint)`. See implementation for details. | ||
* | ||
* There are some variations in different ECIES implementations: | ||
* which key derivation function to use, compressed or uncompressed `senderPoint`/`sharedPoint`, whether to include `senderPoint`, etc. | ||
* | ||
* Because the entropy of `senderPoint`, `sharedPoint` is enough high[1], we don't need salt to derive keys. | ||
* | ||
* [1]: Two reasons: the public keys are "random" bytes (albeit secp256k1 public keys are **not uniformly** random), and ephemeral keys are generated in every encryption. | ||
* | ||
* @param pk - Receiver's public key. | ||
* @param compressed - Whether to use compressed or uncompressed public keys in the key derivation (secp256k1 only). | ||
* @returns Shared secret, derived with HKDF-SHA256. | ||
*/ | ||
PrivateKey.prototype.encapsulate = function (pk, compressed) { | ||
if (compressed === void 0) { compressed = false; } | ||
var senderPoint = compressed | ||
? this.publicKey.compressed | ||
: this.publicKey.uncompressed; | ||
var sharedPoint = this.multiply(pk, compressed); | ||
return (0, utils_2.getSharedKey)(senderPoint, sharedPoint); | ||
@@ -46,0 +59,0 @@ }; |
@@ -1,2 +0,2 @@ | ||
import { PrivateKey } from "./PrivateKey"; | ||
import type { PrivateKey } from "./PrivateKey"; | ||
export declare class PublicKey { | ||
@@ -9,4 +9,13 @@ static fromHex(hex: string): PublicKey; | ||
toHex(compressed?: boolean): string; | ||
decapsulate(sk: PrivateKey): Uint8Array; | ||
/** | ||
* Derives a shared secret from receiver's private key (sk) and ephemeral public key (this). | ||
* Opposite of `encapsulate`. | ||
* @see PrivateKey.encapsulate | ||
* | ||
* @param sk - Receiver's private key. | ||
* @param compressed - Whether to use compressed or uncompressed public keys in the key derivation (secp256k1 only). | ||
* @returns Shared secret, derived with HKDF-SHA256. | ||
*/ | ||
decapsulate(sk: PrivateKey, compressed?: boolean): Uint8Array; | ||
equals(other: PublicKey): boolean; | ||
} |
@@ -5,3 +5,2 @@ "use strict"; | ||
var utils_1 = require("@noble/ciphers/utils"); | ||
var config_1 = require("../config"); | ||
var utils_2 = require("../utils"); | ||
@@ -40,13 +39,15 @@ var PublicKey = /** @class */ (function () { | ||
}; | ||
PublicKey.prototype.decapsulate = function (sk) { | ||
var senderPoint; | ||
var sharedPoint; | ||
if ((0, config_1.isHkdfKeyCompressed)()) { | ||
senderPoint = this.data; | ||
sharedPoint = sk.multiply(this, true); | ||
} | ||
else { | ||
senderPoint = this.uncompressed; | ||
sharedPoint = sk.multiply(this, false); | ||
} | ||
/** | ||
* Derives a shared secret from receiver's private key (sk) and ephemeral public key (this). | ||
* Opposite of `encapsulate`. | ||
* @see PrivateKey.encapsulate | ||
* | ||
* @param sk - Receiver's private key. | ||
* @param compressed - Whether to use compressed or uncompressed public keys in the key derivation (secp256k1 only). | ||
* @returns Shared secret, derived with HKDF-SHA256. | ||
*/ | ||
PublicKey.prototype.decapsulate = function (sk, compressed) { | ||
if (compressed === void 0) { compressed = false; } | ||
var senderPoint = compressed ? this.data : this.uncompressed; | ||
var sharedPoint = sk.multiply(this, compressed); | ||
return (0, utils_2.getSharedKey)(senderPoint, sharedPoint); | ||
@@ -53,0 +54,0 @@ }; |
@@ -0,7 +1,6 @@ | ||
export declare const getValidSecret: () => Uint8Array; | ||
export declare const isValidPrivateKey: (secret: Uint8Array) => boolean; | ||
export declare const getValidSecret: () => Uint8Array; | ||
export declare const getPublicKey: (secret: Uint8Array) => Uint8Array; | ||
export declare const getSharedKey: (ephemeralPoint: Uint8Array, sharedPoint: Uint8Array) => Uint8Array; | ||
export declare const getSharedPoint: (sk: Uint8Array, pk: Uint8Array, compressed?: boolean) => Uint8Array; | ||
export declare const convertPublicKeyFormat: (pk: Uint8Array, compressed: boolean) => Uint8Array; | ||
export declare const hexToPublicKey: (hex: string) => Uint8Array; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.hexToPublicKey = exports.convertPublicKeyFormat = exports.getSharedPoint = exports.getSharedKey = exports.getPublicKey = exports.getValidSecret = exports.isValidPrivateKey = void 0; | ||
var utils_1 = require("@noble/ciphers/utils"); | ||
exports.hexToPublicKey = exports.convertPublicKeyFormat = exports.getSharedPoint = exports.getPublicKey = exports.isValidPrivateKey = exports.getValidSecret = void 0; | ||
var webcrypto_1 = require("@noble/ciphers/webcrypto"); | ||
@@ -10,10 +9,3 @@ var ed25519_1 = require("@noble/curves/ed25519"); | ||
var consts_1 = require("../consts"); | ||
var hash_1 = require("./hash"); | ||
var hex_1 = require("./hex"); | ||
var isValidPrivateKey = function (secret) { | ||
// on secp256k1: only key ∈ (0, group order) is valid | ||
// on curve25519: any 32-byte key is valid | ||
return _exec(function (curve) { return curve.utils.isValidPrivateKey(secret); }, function () { return true; }, function () { return true; }); | ||
}; | ||
exports.isValidPrivateKey = isValidPrivateKey; | ||
var getValidSecret = function () { | ||
@@ -27,15 +19,14 @@ var key; | ||
exports.getValidSecret = getValidSecret; | ||
var isValidPrivateKey = function (secret) { | ||
// on secp256k1: only key ∈ (0, group order) is valid | ||
// on curve25519: any 32-byte key is valid | ||
return _exec((0, config_1.ellipticCurve)(), function (curve) { return curve.utils.isValidPrivateKey(secret); }, function () { return true; }, function () { return true; }); | ||
}; | ||
exports.isValidPrivateKey = isValidPrivateKey; | ||
var getPublicKey = function (secret) { | ||
return _exec(function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); }); | ||
return _exec((0, config_1.ellipticCurve)(), function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); }); | ||
}; | ||
exports.getPublicKey = getPublicKey; | ||
var getSharedKey = function (ephemeralPoint, sharedPoint) { return (0, hash_1.deriveKey)((0, utils_1.concatBytes)(ephemeralPoint, sharedPoint)); }; | ||
exports.getSharedKey = getSharedKey; | ||
var getSharedPoint = function (sk, pk, compressed) { | ||
return _exec(function (curve) { return curve.getSharedSecret(sk, pk, compressed); }, function (curve) { return curve.getSharedSecret(sk, pk); }, function (curve) { | ||
// Note: scalar is hashed from sk | ||
var scalar = curve.utils.getExtendedPublicKey(sk).scalar; | ||
var point = curve.ExtendedPoint.fromHex(pk).multiply(scalar); | ||
return point.toRawBytes(); | ||
}); | ||
return _exec((0, config_1.ellipticCurve)(), function (curve) { return curve.getSharedSecret(sk, pk, compressed); }, function (curve) { return curve.getSharedSecret(sk, pk); }, function (curve) { return getSharedPointOnEd25519(curve, sk, pk); }); | ||
}; | ||
@@ -45,3 +36,3 @@ exports.getSharedPoint = getSharedPoint; | ||
// only for secp256k1 | ||
return _exec(function (curve) { return curve.getSharedSecret(BigInt(1), pk, compressed); }, function () { return pk; }, function () { return pk; }); | ||
return _exec((0, config_1.ellipticCurve)(), function (curve) { return curve.getSharedSecret(BigInt(1), pk, compressed); }, function () { return pk; }, function () { return pk; }); | ||
}; | ||
@@ -51,15 +42,6 @@ exports.convertPublicKeyFormat = convertPublicKeyFormat; | ||
var decoded = (0, hex_1.decodeHex)(hex); | ||
return _exec(function () { | ||
if (decoded.length === consts_1.ETH_PUBLIC_KEY_SIZE) { | ||
var fixed = new Uint8Array(1 + decoded.length); | ||
fixed.set([0x04]); | ||
fixed.set(decoded, 1); | ||
return fixed; | ||
} | ||
return decoded; | ||
}, function () { return decoded; }, function () { return decoded; }); | ||
return _exec((0, config_1.ellipticCurve)(), function () { return compatEthPublicKey(decoded); }, function () { return decoded; }, function () { return decoded; }); | ||
}; | ||
exports.hexToPublicKey = hexToPublicKey; | ||
function _exec(secp256k1Callback, x25519Callback, ed25519Callback) { | ||
var curve = (0, config_1.ellipticCurve)(); | ||
function _exec(curve, secp256k1Callback, x25519Callback, ed25519Callback) { | ||
if (curve === "secp256k1") { | ||
@@ -78,1 +60,16 @@ return secp256k1Callback(secp256k1_1.secp256k1); | ||
} | ||
var compatEthPublicKey = function (pk) { | ||
if (pk.length === consts_1.ETH_PUBLIC_KEY_SIZE) { | ||
var fixed = new Uint8Array(1 + pk.length); | ||
fixed.set([0x04]); | ||
fixed.set(pk, 1); | ||
return fixed; | ||
} | ||
return pk; | ||
}; | ||
var getSharedPointOnEd25519 = function (curve, sk, pk) { | ||
// Note: scalar is hashed from sk | ||
var scalar = curve.utils.getExtendedPublicKey(sk).scalar; | ||
var point = curve.ExtendedPoint.fromHex(pk).multiply(scalar); | ||
return point.toRawBytes(); | ||
}; |
@@ -1,1 +0,2 @@ | ||
export declare const deriveKey: (master: Uint8Array) => Uint8Array; | ||
export declare const deriveKey: (master: Uint8Array, salt?: Uint8Array, info?: Uint8Array) => Uint8Array; | ||
export declare const getSharedKey: (...parts: Uint8Array[]) => Uint8Array; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.deriveKey = void 0; | ||
exports.getSharedKey = exports.deriveKey = void 0; | ||
var utils_1 = require("@noble/ciphers/utils"); | ||
var hkdf_1 = require("@noble/hashes/hkdf"); | ||
var sha256_1 = require("@noble/hashes/sha256"); | ||
var deriveKey = function (master) { | ||
var deriveKey = function (master, salt, info) { | ||
// 32 bytes shared secret for aes256 and xchacha20 derived from HKDF-SHA256 | ||
return (0, hkdf_1.hkdf)(sha256_1.sha256, master, undefined, undefined, 32); | ||
return (0, hkdf_1.hkdf)(sha256_1.sha256, master, salt, info, 32); | ||
}; | ||
exports.deriveKey = deriveKey; | ||
var getSharedKey = function () { | ||
var parts = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
parts[_i] = arguments[_i]; | ||
} | ||
return (0, exports.deriveKey)(utils_1.concatBytes.apply(void 0, parts)); | ||
}; | ||
exports.getSharedKey = getSharedKey; |
@@ -17,3 +17,2 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// under this folder no `Buffer` | ||
__exportStar(require("./elliptic"), exports); | ||
@@ -20,0 +19,0 @@ __exportStar(require("./hash"), exports); |
@@ -1,6 +0,6 @@ | ||
export declare const symEncrypt: (key: Uint8Array, plainText: Uint8Array) => Uint8Array; | ||
export declare const symDecrypt: (key: Uint8Array, cipherText: Uint8Array) => Uint8Array; | ||
export declare const symEncrypt: (key: Uint8Array, plainText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
export declare const symDecrypt: (key: Uint8Array, cipherText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
/** @deprecated - use `symEncrypt` instead. */ | ||
export declare const aesEncrypt: (key: Uint8Array, plainText: Uint8Array) => Uint8Array; | ||
export declare const aesEncrypt: (key: Uint8Array, plainText: Uint8Array, AAD?: Uint8Array) => Uint8Array; | ||
/** @deprecated - use `symDecrypt` instead. */ | ||
export declare const aesDecrypt: (key: Uint8Array, cipherText: Uint8Array) => Uint8Array; | ||
export declare const aesDecrypt: (key: Uint8Array, cipherText: Uint8Array, AAD?: Uint8Array) => Uint8Array; |
@@ -10,9 +10,5 @@ "use strict"; | ||
var consts_1 = require("../consts"); | ||
var symEncrypt = function (key, plainText) { | ||
return _exec(_encrypt, key, plainText); | ||
}; | ||
var symEncrypt = function (key, plainText, AAD) { return _exec(_encrypt, key, plainText, AAD); }; | ||
exports.symEncrypt = symEncrypt; | ||
var symDecrypt = function (key, cipherText) { | ||
return _exec(_decrypt, key, cipherText); | ||
}; | ||
var symDecrypt = function (key, cipherText, AAD) { return _exec(_decrypt, key, cipherText, AAD); }; | ||
exports.symDecrypt = symDecrypt; | ||
@@ -23,9 +19,9 @@ /** @deprecated - use `symEncrypt` instead. */ | ||
exports.aesDecrypt = exports.symDecrypt; // TODO: delete | ||
function _exec(callback, key, data) { | ||
function _exec(callback, key, data, AAD) { | ||
var algorithm = (0, config_1.symmetricAlgorithm)(); | ||
if (algorithm === "aes-256-gcm") { | ||
return callback(aes_1.aes256gcm, key, data, (0, config_1.symmetricNonceLength)(), consts_1.AEAD_TAG_LENGTH); | ||
return callback(aes_1.aes256gcm, key, data, (0, config_1.symmetricNonceLength)(), consts_1.AEAD_TAG_LENGTH, AAD); | ||
} | ||
else if (algorithm === "xchacha20") { | ||
return callback(chacha_1.xchacha20, key, data, consts_1.XCHACHA20_NONCE_LENGTH, consts_1.AEAD_TAG_LENGTH); | ||
return callback(chacha_1.xchacha20, key, data, consts_1.XCHACHA20_NONCE_LENGTH, consts_1.AEAD_TAG_LENGTH, AAD); | ||
} | ||
@@ -41,18 +37,26 @@ else if (algorithm === "aes-256-cbc") { | ||
} | ||
function _encrypt(func, key, plainText, nonceLength, tagLength) { | ||
function _encrypt(func, key, data, nonceLength, tagLength, AAD) { | ||
var nonce = (0, webcrypto_1.randomBytes)(nonceLength); | ||
var cipher = func(key, nonce); | ||
var ciphered = cipher.encrypt(plainText); // encrypted || tag | ||
var encrypted = ciphered.subarray(0, ciphered.length - tagLength); | ||
var tag = ciphered.subarray(ciphered.length - tagLength); | ||
return (0, utils_1.concatBytes)(nonce, tag, encrypted); | ||
var cipher = func(key, nonce, AAD); | ||
// @noble/ciphers format: cipherText || tag | ||
var encrypted = cipher.encrypt(data); | ||
if (tagLength === 0) { | ||
return (0, utils_1.concatBytes)(nonce, encrypted); | ||
} | ||
var cipherTextLength = encrypted.length - tagLength; | ||
var cipherText = encrypted.subarray(0, cipherTextLength); | ||
var tag = encrypted.subarray(cipherTextLength); | ||
// ecies payload format: pk || nonce || tag || cipherText | ||
return (0, utils_1.concatBytes)(nonce, tag, cipherText); | ||
} | ||
function _decrypt(func, key, cipherText, nonceLength, tagLength) { | ||
var nonceTagLength = nonceLength + tagLength; | ||
var nonce = cipherText.subarray(0, nonceLength); | ||
var tag = cipherText.subarray(nonceLength, nonceTagLength); | ||
var encrypted = cipherText.subarray(nonceTagLength); | ||
var decipher = func(key, Uint8Array.from(nonce)); // to reset byteOffset | ||
var ciphered = (0, utils_1.concatBytes)(encrypted, tag); | ||
return decipher.decrypt(ciphered); | ||
function _decrypt(func, key, data, nonceLength, tagLength, AAD) { | ||
var nonce = data.subarray(0, nonceLength); | ||
var cipher = func(key, Uint8Array.from(nonce), AAD); // to reset byteOffset | ||
var encrypted = data.subarray(nonceLength); | ||
if (tagLength === 0) { | ||
return cipher.decrypt(encrypted); | ||
} | ||
var tag = encrypted.subarray(0, tagLength); | ||
var cipherText = encrypted.subarray(tagLength); | ||
return cipher.decrypt((0, utils_1.concatBytes)(cipherText, tag)); | ||
} |
@@ -14,5 +14,7 @@ { | ||
}, | ||
"version": "0.4.10", | ||
"version": "0.4.11", | ||
"engines": { | ||
"node": ">=16.0.0" | ||
"node": ">=16", | ||
"bun": ">=1", | ||
"deno": ">=2" | ||
}, | ||
@@ -37,19 +39,15 @@ "keywords": [ | ||
"types": "./dist/index.d.ts", | ||
"require": "./dist/index.js", | ||
"import": "./dist/index.js" | ||
"default": "./dist/index.js" | ||
}, | ||
"./config": { | ||
"types": "./dist/config.d.ts", | ||
"import": "./dist/config.js", | ||
"require": "./dist/config.js" | ||
"default": "./dist/config.js" | ||
}, | ||
"./consts": { | ||
"types": "./dist/consts.d.ts", | ||
"import": "./dist/consts.js", | ||
"require": "./dist/consts.js" | ||
"default": "./dist/consts.js" | ||
}, | ||
"./utils": { | ||
"types": "./dist/utils/index.d.ts", | ||
"import": "./dist/utils/index.js", | ||
"require": "./dist/utils/index.js" | ||
"default": "./dist/utils/index.js" | ||
} | ||
@@ -59,6 +57,7 @@ }, | ||
"build": "npx tsc", | ||
"test": "vitest" | ||
"test": "vitest", | ||
"test:browser": "node ./scripts/gen-browser-tests.mjs && cd tests-browser && pnpm test" | ||
}, | ||
"dependencies": { | ||
"@ecies/ciphers": "^0.2.0", | ||
"@ecies/ciphers": "^0.2.1", | ||
"@noble/ciphers": "^1.0.0", | ||
@@ -69,9 +68,9 @@ "@noble/curves": "^1.6.0", | ||
"devDependencies": { | ||
"@types/node": "^22.7.9", | ||
"@vitest/coverage-v8": "^2.1.3", | ||
"@types/node": "^22.9.0", | ||
"@vitest/coverage-v8": "^2.1.4", | ||
"typescript": "^5.6.3", | ||
"undici": "^6.20.1", | ||
"vitest": "^2.1.3" | ||
"vitest": "^2.1.4" | ||
}, | ||
"packageManager": "pnpm@9.12.2+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228" | ||
"packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" | ||
} |
@@ -41,8 +41,21 @@ # eciesjs | ||
## Browser Support | ||
## Multi-platform Support | ||
### Browser | ||
This library is browser-friendly, check the [`example/browser`](./example/browser) directory for details. Currently it's necessary to polyfill `Buffer` for backward compatibility. From v0.5.0, it can run in browsers as is. | ||
If you want a WASM version to run directly in modern browsers or on some blockchains, check [`ecies-wasm`](https://github.com/ecies/rs-wasm). | ||
If you want a WASM version to run directly in modern browsers or on some blockchains, you can also try [`ecies-wasm`](https://github.com/ecies/rs-wasm). | ||
### Bun/Deno | ||
For bun/deno, see [`example/runtime`](./example/runtime). There are some limitations currently: | ||
- `xchacha20` does not work on bun | ||
- Only `aes-256-gcm` with 12 bytes nonce works on deno | ||
### React Native | ||
See the [React Native demo](https://github.com/ecies/js-rn-demo). | ||
## API | ||
@@ -144,2 +157,4 @@ | ||
> If you don't know how to choose between x25519 and ed25519, just use the dedicated key exchange function x25519 for efficiency. | ||
> | ||
> Because any 32-byte data is a valid curve25519 public key, the payload would seem random. This property is excellent for circumventing censorship by adversaries. | ||
@@ -158,2 +173,10 @@ ### Secp256k1-specific configuration | ||
### Which configuration should I choose? | ||
For compatibility with other [ecies libraries](https://github.com/orgs/ecies/repositories), start with the default (secp256k1 with AES-256-GCM). | ||
For speed and security, pick x25519 with XChaCha20-Poly1305. | ||
If you know exactly what you are doing, configure as you wish or build your own ecies logic with this library. | ||
## Security Audit | ||
@@ -160,0 +183,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
35191
555
189
Updated@ecies/ciphers@^0.2.1