Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

feistel-cipher

Package Overview
Dependencies
Maintainers
2
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

feistel-cipher - npm Package Compare versions

Comparing version 1.3.14 to 1.4.0

dist/lib/src/typescript/utils/bytes.d.ts

32

dist/lib/src/typescript/fpe.d.ts

@@ -18,9 +18,23 @@ import { Readable } from './utils/base256';

/**
* Obfuscate the passed data
*
* @param {string} data - The data to obfuscate
* @returns {Readable} The byte array of the obfuscated result.
*/
* Obfuscate the passed data
*
* @param {string} data - The data to obfuscate
* @returns {Readable} The readable string of the obfuscated result.
*/
encrypt(data: string): Readable;
/**
* Obfuscate numbers
*
* @param {number} n - The data to obfuscate
* @returns {number} The obfuscated number.
*/
encryptNumber(n: number): number;
/**
*Obfuscate strings
*
* @param {string} str - The data to obfuscate
* @returns {Readable} The readable string of the obfuscated result.
*/
encryptString(str: string): Readable;
/**
* Deobfuscate the passed data

@@ -32,4 +46,12 @@ *

decrypt(obfuscated: Readable): string;
/**
* Deobfuscate the passed number
*
* @param {number} obfuscated - The number to use
* @returns {number} The deobfuscated number.
*/
decryptNumber(obfuscated: number): number;
private round;
private roundBytes;
}
//# sourceMappingURL=fpe.d.ts.map

@@ -27,2 +27,3 @@ "use strict";

const base256_1 = require("./utils/base256");
const bytes_1 = require("./utils/bytes");
const hash_1 = require("./utils/hash");

@@ -50,7 +51,7 @@ const strings_1 = require("./utils/strings");

/**
* Obfuscate the passed data
*
* @param {string} data - The data to obfuscate
* @returns {Readable} The byte array of the obfuscated result.
*/
* Obfuscate the passed data
*
* @param {string} data - The data to obfuscate
* @returns {Readable} The readable string of the obfuscated result.
*/
encrypt(data) {

@@ -80,2 +81,51 @@ let parts = (0, strings_1.split)(data);

/**
* Obfuscate numbers
*
* @param {number} n - The data to obfuscate
* @returns {number} The obfuscated number.
*/
encryptNumber(n) {
if (n < 256) {
if (n === 0) {
return 0;
}
const buf = Buffer.alloc(2);
buf.writeUInt16BE(n);
return (0, base256_1.readable2Buffer)(this.encrypt(buf.toString())).readUInt16BE();
}
let buf = Buffer.alloc(4);
buf.writeUInt32BE(n);
let parts = (0, bytes_1.splitBytes)(buf);
// Apply the FPE Feistel cipher
for (let i = 0; i < this.rounds; ++i) { // eslint-disable-line no-loops/no-loops
const left = parts[1];
if (parts[1].length < parts[0].length) {
parts[1] = Buffer.concat([parts[1], xor_1.NEUTRAL]);
}
const rnd = this.roundBytes(parts[1], i);
let tmp = parts[0];
let crop = false;
if (tmp.length + 1 === rnd.length) {
tmp = Buffer.concat([tmp, xor_1.NEUTRAL]);
crop = true;
}
let right = (0, xor_1.xorBytes)(tmp, rnd);
if (crop) {
right = right.fill(right, 0, right.length - 1, 'binary');
}
parts = [left, right];
}
buf = Buffer.concat([parts[0], parts[1]]);
return buf.readUInt32BE();
}
/**
*Obfuscate strings
*
* @param {string} str - The data to obfuscate
* @returns {Readable} The readable string of the obfuscated result.
*/
encryptString(str) {
return this.encrypt(str);
}
/**
* Deobfuscate the passed data

@@ -119,2 +169,52 @@ *

}
/**
* Deobfuscate the passed number
*
* @param {number} obfuscated - The number to use
* @returns {number} The deobfuscated number.
*/
decryptNumber(obfuscated) {
if (obfuscated === 0) {
return 0;
}
let buf = Buffer.alloc(2);
let short = true;
try {
buf.writeUInt16BE(obfuscated);
}
catch (e) {
buf = Buffer.alloc(4);
buf.writeUInt32BE(obfuscated);
short = false;
}
// Apply the FPE Feistel cipher
const parts = (0, bytes_1.splitBytes)(buf);
let [left, right] = parts;
// Compensating the way Split() works by moving the first byte at right to the end of left if using an odd number of rounds
if (this.rounds % 2 !== 0 && left.length !== right.length) {
left = Buffer.concat([left, Buffer.from([right[0]])]);
right = Buffer.alloc(0).fill(right, 1, undefined, 'binary');
}
for (let i = 0; i < this.rounds; ++i) { // eslint-disable-line no-loops/no-loops
let leftRound = left;
if (left.length < right.length) {
leftRound = Buffer.concat([leftRound, xor_1.NEUTRAL]);
}
const rnd = this.roundBytes(leftRound, this.rounds - i - 1);
let rightRound = right;
let extended = false;
if (rightRound.length + 1 === rnd.length) {
rightRound = Buffer.concat([rightRound, Buffer.alloc(0).fill(left, left.length - 1, undefined, 'binary')]);
extended = true;
}
let tmp = (0, xor_1.xorBytes)(rightRound, rnd);
right = left;
if (extended) {
tmp = Buffer.alloc(0).fill(tmp, 0, tmp.length - 1, 'binary');
}
left = tmp;
}
buf = Buffer.concat([left, right]);
return short ? buf.readUInt16BE() : buf.readUInt32BE();
}
// Feistel implementation

@@ -127,3 +227,10 @@ // Round is the function applied at each round of the obfuscation process to the right side of the Feistel cipher

}
// RoundBytes operates like round() on byte arrays
roundBytes(item, index) {
const addition = (0, bytes_1.addBytes)(item, (0, bytes_1.extractBytes)(Buffer.from(this.key), index, item.length));
const hashed = (0, hash_1.H)(addition, this.engine);
const extracted = (0, strings_1.extract)(hashed.toString('hex'), index, item.length);
return Buffer.from([...extracted].map(c => Buffer.from(c).readInt8()));
}
}
exports.FPECipher = FPECipher;

@@ -39,2 +39,6 @@ "use strict";

exports.SHA_3 = exports.SHA_256 = exports.KECCAK = exports.BLAKE2b = void 0;
if (typeof window !== 'undefined') {
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-var-requires
window.Buffer = window.Buffer || require('buffer').Buffer;
}
__exportStar(require("./feistel"), exports);

@@ -41,0 +45,0 @@ __exportStar(require("./fpe"), exports);

@@ -0,3 +1,6 @@

/// <reference types="node" />
export declare const xor: (str1: string, str2: string) => string;
export declare const xorBytes: (bytes1: Buffer, bytes2: Buffer) => Buffer;
export declare const NEUTRAL_BYTE: string;
export declare const NEUTRAL: Buffer;
//# sourceMappingURL=xor.d.ts.map

@@ -24,3 +24,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.NEUTRAL_BYTE = exports.xor = void 0;
exports.NEUTRAL = exports.NEUTRAL_BYTE = exports.xorBytes = exports.xor = void 0;
// xor applies XOR operation on two strings in the sense that each charCode are xored

@@ -31,2 +31,8 @@ const xor = (str1, str2) => {

exports.xor = xor;
// xorBytes applies XOR operation on thow byte arrays in the sense that each bit value are xored
const xorBytes = (bytes1, bytes2) => {
return Buffer.from(bytes1).reduce((xored, c, idx) => Buffer.concat([xored, Buffer.from([c ^ bytes2[idx]])]), Buffer.alloc(0));
};
exports.xorBytes = xorBytes;
exports.NEUTRAL_BYTE = Buffer.from([0]).toString();
exports.NEUTRAL = Buffer.from([0]);

14

package.json
{
"name": "feistel-cipher",
"version": "1.3.14",
"version": "1.4.0",
"description": "Feistel cipher implementation for format-preserving encryption",

@@ -39,10 +39,10 @@ "main": "dist/lib/src/typescript/index.js",

"@types/keccak": "^3.0.1",
"@types/mocha": "^9.1.1",
"@types/node": "^18.7.15",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"@types/mocha": "^10.0.0",
"@types/node": "^18.8.5",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"blakejs": "^1.2.1",
"browserify": "17.0.0",
"chai": "^4.3.6",
"eslint": "^8.23.0",
"eslint": "^8.25.0",
"eslint-plugin-no-loops": "~0.3.0",

@@ -53,3 +53,3 @@ "keccak": "^3.0.2",

"ts-node": "^10.9.1",
"typescript": "^4.8.2"
"typescript": "^4.8.4"
},

@@ -56,0 +56,0 @@ "resolutions": {

@@ -84,2 +84,11 @@ # feistel-cipher

If you want to use FPE for numbers, you might want to use the `encryptNumber()` method on the `FPECipher` which will return a number that you may pad if need be to match your requirements:
```typescript
const obfuscatedNumber = cipher.encryptNumber(sourceNumber)
const deobfuscatedNumber = cipher.decryptNumber(obfuscatedNumber)
assert(sourceNumber == deobfuscatedNumber)
```
_NB: For stability and security purposes, the number `0` always returns itself._
### Dependencies

@@ -86,0 +95,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc