Add comprehensive installation and setup documentation

- Add GETTING_STARTED.md with quick start guide and development modes
- Add INSTALL.sh automated installation script
- Add INSTALLATION_CHECKLIST.md, INSTALLATION_SUCCESS.md, and INSTALLATION_SUMMARY.md
- Add QUICK_REFERENCE.md for common commands
- Add SETUP_GUIDE.md with detailed setup instructions
- Update README.md with improved project overview
- Add did-wallet app dependencies and node_modules
This commit is contained in:
Dorian
2026-01-27 17:18:21 +00:00
parent a81f655133
commit 0d073fa89e
22658 changed files with 4494151 additions and 6 deletions
+18
View File
@@ -0,0 +1,18 @@
export type EllipticCurve = "secp256k1" | "x25519" | "ed25519";
export type SymmetricAlgorithm = "aes-256-gcm" | "xchacha20";
export type NonceLength = 12 | 16;
declare class Config {
ellipticCurve: EllipticCurve;
isEphemeralKeyCompressed: boolean;
isHkdfKeyCompressed: boolean;
symmetricAlgorithm: SymmetricAlgorithm;
symmetricNonceLength: NonceLength;
}
export declare const ECIES_CONFIG: Config;
export declare const ellipticCurve: () => EllipticCurve;
export declare const isEphemeralKeyCompressed: () => boolean;
export declare const isHkdfKeyCompressed: () => boolean;
export declare const symmetricAlgorithm: () => SymmetricAlgorithm;
export declare const symmetricNonceLength: () => NonceLength;
export declare const ephemeralKeySize: () => number;
export {};
+41
View File
@@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ephemeralKeySize = exports.symmetricNonceLength = exports.symmetricAlgorithm = exports.isHkdfKeyCompressed = exports.isEphemeralKeyCompressed = exports.ellipticCurve = exports.ECIES_CONFIG = void 0;
var consts_1 = require("./consts");
var Config = /** @class */ (function () {
function Config() {
this.ellipticCurve = "secp256k1";
this.isEphemeralKeyCompressed = false; // secp256k1 only
this.isHkdfKeyCompressed = false; // secp256k1 only
this.symmetricAlgorithm = "aes-256-gcm";
this.symmetricNonceLength = 16; // aes-256-gcm only
}
return Config;
}());
exports.ECIES_CONFIG = new Config();
var ellipticCurve = function () { return exports.ECIES_CONFIG.ellipticCurve; };
exports.ellipticCurve = ellipticCurve;
var isEphemeralKeyCompressed = function () { return exports.ECIES_CONFIG.isEphemeralKeyCompressed; };
exports.isEphemeralKeyCompressed = isEphemeralKeyCompressed;
var isHkdfKeyCompressed = function () { return exports.ECIES_CONFIG.isHkdfKeyCompressed; };
exports.isHkdfKeyCompressed = isHkdfKeyCompressed;
var symmetricAlgorithm = function () { return exports.ECIES_CONFIG.symmetricAlgorithm; };
exports.symmetricAlgorithm = symmetricAlgorithm;
var symmetricNonceLength = function () { return exports.ECIES_CONFIG.symmetricNonceLength; };
exports.symmetricNonceLength = symmetricNonceLength;
var ephemeralKeySize = function () {
var mapping = {
secp256k1: exports.ECIES_CONFIG.isEphemeralKeyCompressed
? consts_1.COMPRESSED_PUBLIC_KEY_SIZE
: consts_1.UNCOMPRESSED_PUBLIC_KEY_SIZE,
x25519: consts_1.CURVE25519_PUBLIC_KEY_SIZE,
ed25519: consts_1.CURVE25519_PUBLIC_KEY_SIZE,
};
if (exports.ECIES_CONFIG.ellipticCurve in mapping) {
return mapping[exports.ECIES_CONFIG.ellipticCurve];
}
else {
throw new Error("Not implemented");
}
};
exports.ephemeralKeySize = ephemeralKeySize;
+7
View File
@@ -0,0 +1,7 @@
export declare const SECRET_KEY_LENGTH = 32;
export declare const COMPRESSED_PUBLIC_KEY_SIZE = 33;
export declare const UNCOMPRESSED_PUBLIC_KEY_SIZE = 65;
export declare const ETH_PUBLIC_KEY_SIZE = 64;
export declare const CURVE25519_PUBLIC_KEY_SIZE = 32;
export declare const XCHACHA20_NONCE_LENGTH = 24;
export declare const AEAD_TAG_LENGTH = 16;
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AEAD_TAG_LENGTH = exports.XCHACHA20_NONCE_LENGTH = exports.CURVE25519_PUBLIC_KEY_SIZE = exports.ETH_PUBLIC_KEY_SIZE = exports.UNCOMPRESSED_PUBLIC_KEY_SIZE = exports.COMPRESSED_PUBLIC_KEY_SIZE = exports.SECRET_KEY_LENGTH = void 0;
// elliptic
exports.SECRET_KEY_LENGTH = 32;
exports.COMPRESSED_PUBLIC_KEY_SIZE = 33;
exports.UNCOMPRESSED_PUBLIC_KEY_SIZE = 65;
exports.ETH_PUBLIC_KEY_SIZE = 64;
exports.CURVE25519_PUBLIC_KEY_SIZE = 32;
// symmetric
exports.XCHACHA20_NONCE_LENGTH = 24;
exports.AEAD_TAG_LENGTH = 16;
+13
View File
@@ -0,0 +1,13 @@
/// <reference types="node" />
import { aesDecrypt, aesEncrypt, decodeHex, getValidSecret, remove0x } from "./utils";
export declare function encrypt(receiverRawPK: string | Uint8Array, msg: Uint8Array): Buffer;
export declare function decrypt(receiverRawSK: string | Uint8Array, msg: Uint8Array): Buffer;
export { ECIES_CONFIG } from "./config";
export { PrivateKey, PublicKey } from "./keys";
export declare const utils: {
aesDecrypt: typeof aesDecrypt;
aesEncrypt: typeof aesEncrypt;
decodeHex: typeof decodeHex;
getValidSecret: typeof getValidSecret;
remove0x: typeof remove0x;
};
+48
View File
@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.utils = exports.PublicKey = exports.PrivateKey = exports.ECIES_CONFIG = exports.decrypt = exports.encrypt = void 0;
var utils_1 = require("@noble/ciphers/utils");
var config_1 = require("./config");
var keys_1 = require("./keys");
var utils_2 = require("./utils");
function encrypt(receiverRawPK, msg) {
var ephemeralKey = 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.aesEncrypt)(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));
}
exports.encrypt = encrypt;
function decrypt(receiverRawSK, msg) {
var receiverSK = receiverRawSK instanceof Uint8Array
? new keys_1.PrivateKey(receiverRawSK)
: keys_1.PrivateKey.fromHex(receiverRawSK);
var keySize = (0, config_1.ephemeralKeySize)();
var senderPK = new keys_1.PublicKey(msg.subarray(0, keySize));
var encrypted = msg.subarray(keySize);
var symKey = senderPK.decapsulate(receiverSK);
return Buffer.from((0, utils_2.aesDecrypt)(symKey, encrypted));
}
exports.decrypt = decrypt;
var config_2 = require("./config");
Object.defineProperty(exports, "ECIES_CONFIG", { enumerable: true, get: function () { return config_2.ECIES_CONFIG; } });
var keys_2 = require("./keys");
Object.defineProperty(exports, "PrivateKey", { enumerable: true, get: function () { return keys_2.PrivateKey; } });
Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return keys_2.PublicKey; } });
exports.utils = {
// TODO: review these before 0.5.0
aesDecrypt: utils_2.aesDecrypt,
aesEncrypt: utils_2.aesEncrypt,
decodeHex: utils_2.decodeHex,
getValidSecret: utils_2.getValidSecret,
remove0x: utils_2.remove0x,
};
+13
View File
@@ -0,0 +1,13 @@
/// <reference types="node" />
import { PublicKey } from "./PublicKey";
export declare class PrivateKey {
static fromHex(hex: string): PrivateKey;
private readonly data;
readonly publicKey: PublicKey;
get secret(): Buffer;
constructor(secret?: Uint8Array);
toHex(): string;
encapsulate(pk: PublicKey): Uint8Array;
multiply(pk: PublicKey, compressed?: boolean): Uint8Array;
equals(other: PrivateKey): boolean;
}
+53
View File
@@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrivateKey = void 0;
var utils_1 = require("@noble/ciphers/utils");
var config_1 = require("../config");
var utils_2 = require("../utils");
var PublicKey_1 = require("./PublicKey");
var PrivateKey = /** @class */ (function () {
function PrivateKey(secret) {
var sk = secret === undefined ? (0, utils_2.getValidSecret)() : secret;
if (!(0, utils_2.isValidPrivateKey)(sk)) {
throw new Error("Invalid private key");
}
this.data = sk;
this.publicKey = new PublicKey_1.PublicKey((0, utils_2.getPublicKey)(sk));
}
PrivateKey.fromHex = function (hex) {
return new PrivateKey((0, utils_2.decodeHex)(hex));
};
Object.defineProperty(PrivateKey.prototype, "secret", {
get: function () {
// TODO: Uint8Array
return Buffer.from(this.data);
},
enumerable: false,
configurable: true
});
PrivateKey.prototype.toHex = function () {
return (0, utils_1.bytesToHex)(this.data);
};
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);
}
return (0, utils_2.getSharedKey)(senderPoint, sharedPoint);
};
PrivateKey.prototype.multiply = function (pk, compressed) {
if (compressed === void 0) { compressed = false; }
return (0, utils_2.getSharedPoint)(this.data, pk.compressed, compressed);
};
PrivateKey.prototype.equals = function (other) {
return (0, utils_1.equalBytes)(this.data, other.data);
};
return PrivateKey;
}());
exports.PrivateKey = PrivateKey;
+12
View File
@@ -0,0 +1,12 @@
/// <reference types="node" />
import { PrivateKey } from "./PrivateKey";
export declare class PublicKey {
static fromHex(hex: string): PublicKey;
private readonly data;
get uncompressed(): Buffer;
get compressed(): Buffer;
constructor(data: Uint8Array);
toHex(compressed?: boolean): string;
decapsulate(sk: PrivateKey): Uint8Array;
equals(other: PublicKey): boolean;
}
+57
View File
@@ -0,0 +1,57 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublicKey = void 0;
var utils_1 = require("@noble/ciphers/utils");
var config_1 = require("../config");
var utils_2 = require("../utils");
var PublicKey = /** @class */ (function () {
function PublicKey(data) {
this.data = (0, utils_2.convertPublicKeyFormat)(data, true);
}
PublicKey.fromHex = function (hex) {
return new PublicKey((0, utils_2.hexToPublicKey)(hex));
};
Object.defineProperty(PublicKey.prototype, "uncompressed", {
get: function () {
// TODO: Uint8Array
return Buffer.from((0, utils_2.convertPublicKeyFormat)(this.data, false));
},
enumerable: false,
configurable: true
});
Object.defineProperty(PublicKey.prototype, "compressed", {
get: function () {
// TODO: Uint8Array
return Buffer.from(this.data);
},
enumerable: false,
configurable: true
});
PublicKey.prototype.toHex = function (compressed) {
if (compressed === void 0) { compressed = true; }
if (compressed) {
return (0, utils_1.bytesToHex)(this.data);
}
else {
return (0, utils_1.bytesToHex)(this.uncompressed);
}
};
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);
}
return (0, utils_2.getSharedKey)(senderPoint, sharedPoint);
};
PublicKey.prototype.equals = function (other) {
return (0, utils_1.equalBytes)(this.data, other.data);
};
return PublicKey;
}());
exports.PublicKey = PublicKey;
+2
View File
@@ -0,0 +1,2 @@
export { PrivateKey } from "./PrivateKey";
export { PublicKey } from "./PublicKey";
+9
View File
@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PublicKey = exports.PrivateKey = void 0;
// treat Buffer as Uint8array, i.e. no call of Buffer specific functions
// finally Uint8Array only
var PrivateKey_1 = require("./PrivateKey");
Object.defineProperty(exports, "PrivateKey", { enumerable: true, get: function () { return PrivateKey_1.PrivateKey; } });
var PublicKey_1 = require("./PublicKey");
Object.defineProperty(exports, "PublicKey", { enumerable: true, get: function () { return PublicKey_1.PublicKey; } });
+2
View File
@@ -0,0 +1,2 @@
import { Cipher } from "@noble/ciphers/utils";
export declare function aes256gcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher;
+36
View File
@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.aes256gcm = void 0;
var utils_1 = require("@noble/ciphers/utils");
var crypto_1 = require("crypto");
var consts_1 = require("../consts");
// make `node:crypto`'s aes compatible with `@noble/ciphers`
function aes256gcm(key, nonce, AAD) {
var encrypt = function (plainText) {
var cipher = (0, crypto_1.createCipheriv)("aes-256-gcm", key, nonce);
if (AAD) {
cipher.setAAD(AAD);
}
var updated = cipher.update(plainText);
var finalized = cipher.final();
return (0, utils_1.concatBytes)(updated, finalized, cipher.getAuthTag());
};
var decrypt = function (cipherText) {
var encrypted = cipherText.subarray(0, cipherText.length - consts_1.AEAD_TAG_LENGTH);
var tag = cipherText.subarray(-consts_1.AEAD_TAG_LENGTH);
var decipher = (0, crypto_1.createDecipheriv)("aes-256-gcm", key, nonce);
if (AAD) {
decipher.setAAD(AAD);
}
decipher.setAuthTag(tag);
var updated = decipher.update(encrypted);
var finalized = decipher.final();
return (0, utils_1.concatBytes)(updated, finalized);
};
return {
tagLength: consts_1.AEAD_TAG_LENGTH,
encrypt: encrypt,
decrypt: decrypt,
};
}
exports.aes256gcm = aes256gcm;
+7
View File
@@ -0,0 +1,7 @@
export declare function getValidSecret(): Uint8Array;
export declare function isValidPrivateKey(secret: Uint8Array): boolean;
export declare function getPublicKey(secret: Uint8Array): Uint8Array;
export declare function getSharedKey(ephemeralPoint: Uint8Array, sharedPoint: Uint8Array): Uint8Array;
export declare function getSharedPoint(sk: Uint8Array, pk: Uint8Array, compressed?: boolean): Uint8Array;
export declare function convertPublicKeyFormat(pk: Uint8Array, compressed: boolean): Uint8Array;
export declare function hexToPublicKey(hex: string): Uint8Array;
+74
View File
@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hexToPublicKey = exports.convertPublicKeyFormat = exports.getSharedPoint = exports.getSharedKey = exports.getPublicKey = exports.isValidPrivateKey = exports.getValidSecret = void 0;
var utils_1 = require("@noble/ciphers/utils");
var utils_2 = require("@noble/ciphers/webcrypto/utils");
var ed25519_1 = require("@noble/curves/ed25519");
var secp256k1_1 = require("@noble/curves/secp256k1");
var config_1 = require("../config");
var consts_1 = require("../consts");
var hex_1 = require("./hex");
var symmetric_1 = require("./symmetric");
function getValidSecret() {
var key;
do {
key = (0, utils_2.randomBytes)(consts_1.SECRET_KEY_LENGTH);
} while (!isValidPrivateKey(key));
return key;
}
exports.getValidSecret = getValidSecret;
function isValidPrivateKey(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;
function getPublicKey(secret) {
return _exec(function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); }, function (curve) { return curve.getPublicKey(secret); });
}
exports.getPublicKey = getPublicKey;
function getSharedKey(ephemeralPoint, sharedPoint) {
return (0, symmetric_1.deriveKey)((0, utils_1.concatBytes)(ephemeralPoint, sharedPoint));
}
exports.getSharedKey = getSharedKey;
function getSharedPoint(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();
});
}
exports.getSharedPoint = getSharedPoint;
function convertPublicKeyFormat(pk, compressed) {
// only for secp256k1
return _exec(function (curve) { return curve.getSharedSecret(BigInt(1), pk, compressed); }, function () { return pk; }, function () { return pk; });
}
exports.convertPublicKeyFormat = convertPublicKeyFormat;
function hexToPublicKey(hex) {
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; });
}
exports.hexToPublicKey = hexToPublicKey;
function _exec(secp256k1Callback, x25519Callback, ed25519Callback) {
if ((0, config_1.ellipticCurve)() === "secp256k1") {
return secp256k1Callback(secp256k1_1.secp256k1);
}
else if ((0, config_1.ellipticCurve)() === "x25519") {
return x25519Callback(ed25519_1.x25519);
}
else if ((0, config_1.ellipticCurve)() === "ed25519") {
return ed25519Callback(ed25519_1.ed25519);
}
else {
throw new Error("Not implemented");
}
}
+2
View File
@@ -0,0 +1,2 @@
export declare function remove0x(hex: string): string;
export declare function decodeHex(hex: string): Uint8Array;
+15
View File
@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decodeHex = exports.remove0x = void 0;
var utils_1 = require("@noble/ciphers/utils");
function remove0x(hex) {
if (hex.startsWith("0x") || hex.startsWith("0X")) {
return hex.slice(2);
}
return hex;
}
exports.remove0x = remove0x;
function decodeHex(hex) {
return (0, utils_1.hexToBytes)(remove0x(hex));
}
exports.decodeHex = decodeHex;
+3
View File
@@ -0,0 +1,3 @@
export * from "./elliptic";
export * from "./hex";
export * from "./symmetric";
+20
View File
@@ -0,0 +1,20 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
// under this folder no `Buffer`
__exportStar(require("./elliptic"), exports);
__exportStar(require("./hex"), exports);
__exportStar(require("./symmetric"), exports);
+3
View File
@@ -0,0 +1,3 @@
export declare function aesEncrypt(key: Uint8Array, plainText: Uint8Array): Uint8Array;
export declare function aesDecrypt(key: Uint8Array, cipherText: Uint8Array): Uint8Array;
export declare function deriveKey(master: Uint8Array): Uint8Array;
+56
View File
@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.deriveKey = exports.aesDecrypt = exports.aesEncrypt = void 0;
var chacha_1 = require("@noble/ciphers/chacha");
var utils_1 = require("@noble/ciphers/utils");
var utils_2 = require("@noble/ciphers/webcrypto/utils");
var hkdf_1 = require("@noble/hashes/hkdf");
var sha256_1 = require("@noble/hashes/sha256");
var config_1 = require("../config");
var consts_1 = require("../consts");
var compat_1 = require("./compat");
function aesEncrypt(key, plainText) {
// TODO: Rename to symEncrypt
return _exec(true, key, plainText);
}
exports.aesEncrypt = aesEncrypt;
function aesDecrypt(key, cipherText) {
// TODO: Rename to symDecrypt
return _exec(false, key, cipherText);
}
exports.aesDecrypt = aesDecrypt;
function deriveKey(master) {
// 32 bytes shared secret for aes and xchacha20
return (0, hkdf_1.hkdf)(sha256_1.sha256, master, undefined, undefined, 32);
}
exports.deriveKey = deriveKey;
function _exec(is_encryption, key, data) {
var algorithm = (0, config_1.symmetricAlgorithm)();
var callback = is_encryption ? _encrypt : _decrypt;
if (algorithm === "aes-256-gcm") {
return callback(compat_1.aes256gcm, key, data, (0, config_1.symmetricNonceLength)());
}
else if (algorithm === "xchacha20") {
return callback(chacha_1.xchacha20poly1305, key, data, consts_1.XCHACHA20_NONCE_LENGTH);
}
else {
throw new Error("Not implemented");
}
}
function _encrypt(func, key, plainText, nonceLength) {
var nonce = (0, utils_2.randomBytes)(nonceLength);
var cipher = func(key, nonce);
var ciphered = cipher.encrypt(plainText); // TAG + encrypted
var encrypted = ciphered.subarray(0, ciphered.length - consts_1.AEAD_TAG_LENGTH);
var tag = ciphered.subarray(-consts_1.AEAD_TAG_LENGTH);
return (0, utils_1.concatBytes)(nonce, tag, encrypted);
}
function _decrypt(func, key, cipherText, nonceLength) {
var nonceTagLength = nonceLength + consts_1.AEAD_TAG_LENGTH;
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);
}