spd-lib 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- const fs=require("fs"),zlib=require("zlib"),sodium=require("libsodium-wrappers"),crypto=require("crypto"),argon2=require("argon2");class SPD{constructor(){this.data=[],this.keyPair,this.userKey,this.salt,this.init()}async init(){await sodium.ready,this.keyPair=sodium.crypto_kx_keypair()}async setPassKey(a){await sodium.ready,this.init();const{pqcKey:t,salt:r}=await(new SPD).convertPasscodeToPQCKey(a),e=t.publicKey;this.userKey=e,this.salt=r}async migrateFromFile(a,t){const r=await SPD.loadFromFile(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);i.saveToFile(a)}async migrateFromString(a,t){const r=await SPD.loadFromString(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);return i.saveData()}async addData(a,t){const r=await this.CITS(t);await sodium.ready;const e=Buffer.from(r[0]),i=zlib.deflateSync(e,{level:9}),s=sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES),n=sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(i,null,null,s,this.userKey),o=crypto.createHash("sha3-512").update(n).digest("hex");this.data.push({dataName:a,nonce:Array.from(s),data:Array.from(n),hash:o,dataType:r[1]})}saveToFile(a){if(!(a&&"string"==typeof a&&a.trim()&&this.salt&&this.salt instanceof Uint8Array&&16===this.salt.length))throw new Error("Invalid output path or salt.");const t=JSON.stringify({data:this.data,salt:Array.from(this.salt)}),r=zlib.deflateSync(t,{level:9});fs.writeFileSync(a,r,{mode:384})}static async loadFromFile(a,t){return new Promise((async(r,e)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||e(new Error("Invalid SPD path or passcode.")),await sodium.ready;const i=fs.readFileSync(a),s=zlib.inflateSync(i,{level:9}).toString("utf8"),{data:n,salt:o}=JSON.parse(s),{pqcKey:y}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(o)),c=y.publicKey,d=new SPD;d.userKey=c,d.keyPair={publicKey:c.publicKey},d.data=n.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),d.data.forEach((a=>{crypto.createHash("sha3-512").update(Buffer.from(a.data)).digest("hex")!==a.hash&&e(new Error(`Data integrity check failed for ${a.dataName}`))})),r(d)}catch{e()}}))}async extractData(){return new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(null,a.data,null,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}))}static async derivePBK(a,t){if(!(a&&"string"==typeof a&&a.trim()&&t&&t instanceof Uint8Array&&16===t.length))throw new Error("Invalid passcode or salt.");return new Promise((async(r,e)=>{argon2.hash(a,{salt:Buffer.from(t),type:argon2.argon2id}).then((a=>{r({pbk:a,salt:t})})).catch((a=>{e(a)}))}))}saveData(){const a=JSON.stringify({data:this.data,salt:Array.from(this.salt)});return zlib.deflateSync(a,{level:9})}static async loadFromString(a,t){return new Promise((async(r,e)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||e(new Error("Invalid SPD path or passcode.")),await sodium.ready;const i=Buffer.from(a,"base64"),s=zlib.inflateSync(i,{level:9}).toString("utf8"),{data:n,salt:o}=JSON.parse(s),{pqcKey:y}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(o)),c=y.publicKey,d=new SPD;d.userKey=c,d.keyPair={publicKey:c.publicKey},d.data=n.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),d.data.forEach((a=>{crypto.createHash("sha3-512").update(Buffer.from(a.data)).digest("hex")!==a.hash&&e(new Error(`Data integrity check failed for ${a.dataName}`))})),r(d)}catch{e()}}))}async convertPasscodeToPQCKeySalted(a,t){if(!a||"string"!=typeof a||!a.trim()||a.length<8||!t||!(t instanceof Uint8Array)||16!==t.length)throw new Error("Invalid passcode or salt.");const{pbk:r}=await SPD.derivePBK(a,t);await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(r.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:t}}async convertPasscodeToPQCKey(a){if(!a||"string"!=typeof a||!a.trim()||a.length<8)throw new Error("Invalid passcode.");const{pbk:t,salt:r}=await SPD.derivePBK(a,crypto.getRandomValues(new Uint8Array(16)));await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(t.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:r}}async TDT(a){return{"[object Array]":"Array","[object Uint8Array]":"Uint8Array","[object Uint16Array]":"Uint16Array","[object Uint32Array]":"Uint32Array","[object BigInt64Array]":"BigInt64Array","[object BigUint64Array]":"BigUint64Array","[object Float32Array]":"Float32Array","[object Float64Array]":"Float64Array","[object Map]":"Map","[object Set]":"Set","[object Date]":"Date","[object RegExp]":"RegExp","[object Error]":"Error"}[Object.prototype.toString.call(a)]}async isNumArr(a){if("Uint8Array"===a||"Uint16Array"===a||"Uint32Array"===a||"BigInt64Array"===a||"BigUint64Array"===a||"Float32Array"===a||"Float64Array"===a)return 1}async isSWM(a){if("Map"===a||"Set"===a||"WeakMap"===a||"WeakSet"===a)return 1}async isDRE(a){if("Date"===a||"RegExp"===a||"Error"===a)return 1}async CITS(a){const t=typeof a;if("string"===t||"number"===t||"boolean"===t)return[a.toString(),t];if("object"==typeof a){const t=await this.TDT(a);return"Array"===t?[JSON.stringify(a),"Array"]:await this.isNumArr(t)?[JSON.stringify(Array.from(a)),t]:await this.isSWM(t)?[JSON.stringify([...a]),t]:await this.isDRE(t)?[a.toString(),t]:[JSON.stringify(a),typeof a]}}async CSTI(a,t){return"string"===t?a:"number"===t?parseFloat(a):"boolean"===t?"true"===a&&"false"!==a:"object"===t||"Array"===t?JSON.parse(a):"Uint8Array"===t?new Uint8Array(JSON.parse(a)):"Uint16Array"===t?new Uint16Array(JSON.parse(a)):"Uint32Array"===t?new Uint32Array(JSON.parse(a)):"BigInt64Array"===t?new BigInt64Array(JSON.parse(a)):"BigUint64Array"===t?new BigUint64Array(JSON.parse(a)):"Float32Array"===t?new Float32Array(JSON.parse(a)):"Float64Array"===t?new Float64Array(JSON.parse(a)):"Map"===t?new Map(JSON.parse(a)):"Set"===t?new Set(JSON.parse(a)):"WeakMap"===t?new WeakMap(JSON.parse(a)):"WeakSet"===t?new WeakSet(JSON.parse(a)):"Date"===t?new Date(a):"RegExp"===t?new RegExp(a):"Error"===t?new Error(a):void 0}}module.exports={SPD};
1
+ const fs=require("fs"),zlib=require("zlib"),sodium=require("libsodium-wrappers"),crypto=require("crypto"),argon2=require("argon2");class SPD{constructor(){this.data=[],this.keyPair,this.userKey,this.salt,this.hash="sha3-512",this.init()}async init(){await sodium.ready,this.keyPair=sodium.crypto_kx_keypair()}async setPassKey(a){await sodium.ready,this.init();const{pqcKey:t,salt:r}=await(new SPD).convertPasscodeToPQCKey(a),e=t.publicKey;this.userKey=e,this.salt=r}setHash(a){this.hash=a}async migrateFromFile(a,t){const r=await SPD.loadFromFile(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);i.saveToFile(a)}async migrateFromString(a,t){const r=await SPD.loadFromString(a,t);r.extractData_OLD=async()=>new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_secretbox_open_easy(a.data,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}));const e=await r.extractData_OLD(),i=new SPD;await i.setPassKey(t);for(let a in e)await i.addData(a,e[a]);return i.saveData()}async addData(a,t){const r=await this.CITS(t);await sodium.ready;const e=Buffer.from(r[0]),i=zlib.deflateSync(e,{level:9}),s=sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES),n=sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(i,null,null,s,this.userKey),o=crypto.createHash(this.hash).update(n).digest("hex");this.data.push({dataName:a,nonce:Array.from(s),data:Array.from(n),hash:o,dataType:r[1]})}saveToFile(a){if(!(a&&"string"==typeof a&&a.trim()&&this.salt&&this.salt instanceof Uint8Array&&16===this.salt.length))throw new Error("Invalid output path or salt.");const t=JSON.stringify({data:this.data,salt:Array.from(this.salt)}),r=zlib.deflateSync(t,{level:9});fs.writeFileSync(a,r,{mode:384})}static async loadFromFile(a,t,r="sha3-512"){return new Promise((async(e,i)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||i(new Error("Invalid SPD path or passcode.")),await sodium.ready;const s=fs.readFileSync(a),n=zlib.inflateSync(s,{level:9}).toString("utf8"),{data:o,salt:y}=JSON.parse(n),{pqcKey:c}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(y)),d=c.publicKey,l=new SPD;l.userKey=d,l.keyPair={publicKey:d.publicKey},l.data=o.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),l.data.forEach((a=>{crypto.createHash(r).update(Buffer.from(a.data)).digest("hex")!==a.hash&&i(new Error(`Data integrity check failed for ${a.dataName}`))})),e(l)}catch{i()}}))}async extractData(){return new Promise((async(a,t)=>{try{await sodium.ready;let r={};this.data.forEach((async a=>{try{const t=sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(null,a.data,null,a.nonce,this.userKey),e=zlib.inflateSync(t,{level:9}).toString("utf8");r[a.dataName]=await this.CSTI(e,a.dataType)}catch{t()}})),a(r)}catch{t()}}))}static async derivePBK(a,t){if(!(a&&"string"==typeof a&&a.trim()&&t&&t instanceof Uint8Array&&16===t.length))throw new Error("Invalid passcode or salt.");return new Promise((async(r,e)=>{argon2.hash(a,{salt:Buffer.from(t),type:argon2.argon2id}).then((a=>{r({pbk:a,salt:t})})).catch((a=>{e(a)}))}))}saveData(){const a=JSON.stringify({data:this.data,salt:Array.from(this.salt)});return zlib.deflateSync(a,{level:9})}static async loadFromString(a,t,r="sha3-512"){return new Promise((async(e,i)=>{try{a&&"string"==typeof a&&a.trim()&&t&&"string"==typeof t&&t.trim()||i(new Error("Invalid SPD path or passcode.")),await sodium.ready;const s=Buffer.from(a,"base64"),n=zlib.inflateSync(s,{level:9}).toString("utf8"),{data:o,salt:y}=JSON.parse(n),{pqcKey:c}=await(new SPD).convertPasscodeToPQCKeySalted(t,new Uint8Array(y)),d=c.publicKey,l=new SPD;l.userKey=d,l.keyPair={publicKey:d.publicKey},l.data=o.map((a=>({dataName:a.dataName,nonce:Buffer.from(a.nonce),data:Buffer.from(a.data),hash:a.hash,dataType:a.dataType}))),l.data.forEach((a=>{crypto.createHash(r).update(Buffer.from(a.data)).digest("hex")!==a.hash&&i(new Error(`Data integrity check failed for ${a.dataName}`))})),e(l)}catch{i()}}))}async convertPasscodeToPQCKeySalted(a,t){if(!a||"string"!=typeof a||!a.trim()||a.length<8||!t||!(t instanceof Uint8Array)||16!==t.length)throw new Error("Invalid passcode or salt.");const{pbk:r}=await SPD.derivePBK(a,t);await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(r.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:t}}async convertPasscodeToPQCKey(a){if(!a||"string"!=typeof a||!a.trim()||a.length<8)throw new Error("Invalid passcode.");const{pbk:t,salt:r}=await SPD.derivePBK(a,crypto.getRandomValues(new Uint8Array(16)));await sodium.ready;return{pqcKey:{publicKey:sodium.crypto_kx_seed_keypair(t.slice(0,sodium.crypto_kx_SEEDBYTES)).publicKey},salt:r}}async TDT(a){return{"[object Array]":"Array","[object Uint8Array]":"Uint8Array","[object Uint16Array]":"Uint16Array","[object Uint32Array]":"Uint32Array","[object BigInt64Array]":"BigInt64Array","[object BigUint64Array]":"BigUint64Array","[object Float32Array]":"Float32Array","[object Float64Array]":"Float64Array","[object Map]":"Map","[object Set]":"Set","[object Date]":"Date","[object RegExp]":"RegExp","[object Error]":"Error"}[Object.prototype.toString.call(a)]}async isNumArr(a){if("Uint8Array"===a||"Uint16Array"===a||"Uint32Array"===a||"BigInt64Array"===a||"BigUint64Array"===a||"Float32Array"===a||"Float64Array"===a)return 1}async isSWM(a){if("Map"===a||"Set"===a||"WeakMap"===a||"WeakSet"===a)return 1}async isDRE(a){if("Date"===a||"RegExp"===a||"Error"===a)return 1}async CITS(a){const t=typeof a;if("string"===t||"number"===t||"boolean"===t)return[a.toString(),t];if("object"==typeof a){const t=await this.TDT(a);return"Array"===t?[JSON.stringify(a),"Array"]:await this.isNumArr(t)?[JSON.stringify(Array.from(a)),t]:await this.isSWM(t)?[JSON.stringify([...a]),t]:await this.isDRE(t)?[a.toString(),t]:[JSON.stringify(a),typeof a]}}async CSTI(a,t){return"string"===t?a:"number"===t?parseFloat(a):"boolean"===t?"true"===a&&"false"!==a:"object"===t||"Array"===t?JSON.parse(a):"Uint8Array"===t?new Uint8Array(JSON.parse(a)):"Uint16Array"===t?new Uint16Array(JSON.parse(a)):"Uint32Array"===t?new Uint32Array(JSON.parse(a)):"BigInt64Array"===t?new BigInt64Array(JSON.parse(a)):"BigUint64Array"===t?new BigUint64Array(JSON.parse(a)):"Float32Array"===t?new Float32Array(JSON.parse(a)):"Float64Array"===t?new Float64Array(JSON.parse(a)):"Map"===t?new Map(JSON.parse(a)):"Set"===t?new Set(JSON.parse(a)):"WeakMap"===t?new WeakMap(JSON.parse(a)):"WeakSet"===t?new WeakSet(JSON.parse(a)):"Date"===t?new Date(a):"RegExp"===t?new RegExp(a):"Error"===t?new Error(a):void 0}}module.exports={SPD};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spd-lib",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "SPD or Secure Packaged Data is a compress PQC protected file format to store sensitive data localy",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {