Skip to content

Instantly share code, notes, and snippets.

@alenaksu
Last active September 9, 2019 10:41
Show Gist options
  • Save alenaksu/c75a4e12616815029554841e06f5e85c to your computer and use it in GitHub Desktop.
Save alenaksu/c75a4e12616815029554841e06f5e85c to your computer and use it in GitHub Desktop.
ES6 JavaScript implementation of TEA `Tiny Encryption Algorithm`
export default class TEA {
get DELTA() {
return 0x9e3779b9;
}
constructor(/* Uint32Array(4) */ _key) {
this._key = _key;
}
encrypt(/* Uint32Array(2) */ _value) {
let v0 = _value[0],
v1 = _value[1],
k0 = this._key[0],
k1 = this._key[1],
k2 = this._key[2],
k3 = this._key[3],
sum = 0;
for (let i = 0; i < 32; i++) {
sum += this.DELTA;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
}
return Uint32Array.from([v0, v1]);
}
decrypt(/* Uint32Array(2) */ _value) {
let v0 = _value[0],
v1 = _value[1],
k0 = this._key[0],
k1 = this._key[1],
k2 = this._key[2],
k3 = this._key[3],
sum = 0xC6EF3720;
for (let i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= this.DELTA;
}
return Uint32Array.from([v0, v1]);
}
}
const mx = (
key: Uint32Array,
i: number,
y: number,
z: number,
sum: number,
e: number
) =>
(((z >>> 5) ^ (y << 2)) + ((y >>> 3) ^ (z << 4))) ^
((sum ^ y) + key[(i & 3) ^ e]);
export const DELTA = 0x9e3779b9;
export const encrypt = (value: Uint32Array, key: Uint32Array): Uint32Array => {
const n = value.length;
const encryptedValue: Uint32Array = new Uint32Array(value);
let rounds = Math.floor(6 + 52 / n);
let sum = 0;
let z = value[n - 1];
while (rounds--) {
sum += DELTA;
const e = (sum >>> 2) & 3;
for (let i = 0; i < n; i++) {
const y = encryptedValue[(i + 1) % n];
z = encryptedValue[i] += mx(key, i, y, z, sum, e);
}
}
return encryptedValue;
};
export const decrypt = (value: Uint32Array, key: Uint32Array): Uint32Array => {
const n = value.length;
const decryptedValue: Uint32Array = new Uint32Array(value);
const rounds = Math.floor(6 + 52 / n);
let sum = rounds * DELTA;
let y = value[0];
while (sum) {
const e = (sum >>> 2) & 3;
for (let i = n - 1; i >= 0; i--) {
const z = decryptedValue[((i - 1) >>> 0) % n];
y = decryptedValue[i] -= mx(key, i, y, z, sum, e);
}
sum -= DELTA;
}
return decryptedValue;
};
@alenaksu
Copy link
Author

alenaksu commented May 8, 2018

Usage example

const KEY = Uint32Array.from([
    2426402854,
    2909831320,
    3329067919,
    1815287648
]);
let tea = new TEA(KEY);

for (let i  = 500; i < 600; i++) {
    let enc = tea.encrypt([i, 0]),
        dec = tea.decrypt([enc, 0]);

    console.log('%s ==> %s', i, enc[0].toString(32));
    //console.log('%s ==> %s', enc[0].toString(32), dec[0]);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment