move keccak related functions to front end
This commit is contained in:
parent
edeb1b7c73
commit
35ff9cb240
@ -1,27 +1,17 @@
|
|||||||
const kdf = require('./kdf');
|
import { concatUint8Arrays, splitIntoChunks } from './arrayutils.js';
|
||||||
const keccak = require('./keccak');
|
import { keccak } from './keccak.js';
|
||||||
|
|
||||||
function splitIntoChunks(data) {
|
|
||||||
const chunks = [];
|
|
||||||
const chunkSize = 16;
|
|
||||||
for (let i = 0; i < data.length; i += chunkSize) {
|
|
||||||
const chunk = data.slice(i, i + chunkSize);
|
|
||||||
chunks.push(chunk);
|
|
||||||
}
|
|
||||||
return chunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
class keccakAEAD {
|
class keccakAEAD {
|
||||||
constructor(iv, key, nonce) {
|
constructor(iv, key, nonce) {
|
||||||
const input = kdf.concatUint8Arrays(iv, key, nonce);
|
const input = concatUint8Arrays(iv, key, nonce);
|
||||||
this.state = keccak.SHAKE256(input, 40);
|
this.state = keccak.SHAKE256(input, 40);
|
||||||
let r = this.state.slice(0, 16);
|
let r = this.state.slice(0, 16);
|
||||||
let c = this.state.slice(16, 40);
|
let c = this.state.slice(16, 40);
|
||||||
let padded_key = kdf.concatUint8Arrays(new Uint8Array(24-key.length), key);
|
let padded_key = concatUint8Arrays(new Uint8Array(24-key.length), key);
|
||||||
for (let i = 0; i < padded_key.length; i++) {
|
for (let i = 0; i < padded_key.length; i++) {
|
||||||
c[i] ^= key[i];
|
c[i] ^= key[i];
|
||||||
}
|
}
|
||||||
this.state = kdf.concatUint8Arrays(r, c);
|
this.state = concatUint8Arrays(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
associated_data_processing(associated_data) {
|
associated_data_processing(associated_data) {
|
||||||
@ -37,7 +27,7 @@ class keccakAEAD {
|
|||||||
for (let i = 0; i < chunk.length; i++) {
|
for (let i = 0; i < chunk.length; i++) {
|
||||||
r[i] = chunk[i] ^ to_xor[i];
|
r[i] = chunk[i] ^ to_xor[i];
|
||||||
}
|
}
|
||||||
input = kdf.concatUint8Arrays(r, c);
|
input = concatUint8Arrays(r, c);
|
||||||
this.state = keccak.SHAKE256(input, 40);
|
this.state = keccak.SHAKE256(input, 40);
|
||||||
});
|
});
|
||||||
r = this.state.slice(0, 16);
|
r = this.state.slice(0, 16);
|
||||||
@ -47,7 +37,7 @@ class keccakAEAD {
|
|||||||
for (let i = 0; i < c.length; i++) {
|
for (let i = 0; i < c.length; i++) {
|
||||||
c[i] ^= to_xor[i];
|
c[i] ^= to_xor[i];
|
||||||
}
|
}
|
||||||
this.state = kdf.concatUint8Arrays(r, c);
|
this.state = concatUint8Arrays(r, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
plaintext_processing(plaintext) {
|
plaintext_processing(plaintext) {
|
||||||
@ -65,7 +55,7 @@ class keccakAEAD {
|
|||||||
r[i] = chunk[i] ^ to_xor[i];
|
r[i] = chunk[i] ^ to_xor[i];
|
||||||
}
|
}
|
||||||
cipherchunks.push(r);
|
cipherchunks.push(r);
|
||||||
input = kdf.concatUint8Arrays(r, c);
|
input = concatUint8Arrays(r, c);
|
||||||
this.state = keccak.SHAKE256(input, 40);
|
this.state = keccak.SHAKE256(input, 40);
|
||||||
});
|
});
|
||||||
return cipherchunks;
|
return cipherchunks;
|
||||||
@ -86,7 +76,7 @@ class keccakAEAD {
|
|||||||
r[i] = chunk[i] ^ to_xor[i];
|
r[i] = chunk[i] ^ to_xor[i];
|
||||||
}
|
}
|
||||||
plaintextchunks.push(r);
|
plaintextchunks.push(r);
|
||||||
input = kdf.concatUint8Arrays(chunk, c);
|
input = concatUint8Arrays(chunk, c);
|
||||||
this.state = keccak.SHAKE256(input, 40);
|
this.state = keccak.SHAKE256(input, 40);
|
||||||
});
|
});
|
||||||
return plaintextchunks;
|
return plaintextchunks;
|
||||||
@ -95,11 +85,11 @@ class keccakAEAD {
|
|||||||
finalize(key) {
|
finalize(key) {
|
||||||
let r = this.state.slice(0, 16);
|
let r = this.state.slice(0, 16);
|
||||||
let c = this.state.slice(16, 40);
|
let c = this.state.slice(16, 40);
|
||||||
let padded_key = kdf.concatUint8Arrays(new Uint8Array(24-key.length), key);
|
let padded_key = concatUint8Arrays(new Uint8Array(24-key.length), key);
|
||||||
for (let i = 0; i < padded_key.length; i++) {
|
for (let i = 0; i < padded_key.length; i++) {
|
||||||
c[i] ^= padded_key[i];
|
c[i] ^= padded_key[i];
|
||||||
}
|
}
|
||||||
this.state = kdf.concatUint8Arrays(r, c);
|
this.state = concatUint8Arrays(r, c);
|
||||||
const output = keccak.SHAKE256(this.state, 40);
|
const output = keccak.SHAKE256(this.state, 40);
|
||||||
let to_xor = output.slice(40-key.length, 40);
|
let to_xor = output.slice(40-key.length, 40);
|
||||||
let tag = new Uint8Array(key.length);
|
let tag = new Uint8Array(key.length);
|
||||||
@ -113,7 +103,7 @@ class keccakAEAD {
|
|||||||
let sponge = new keccakAEAD(iv, key, nonce);
|
let sponge = new keccakAEAD(iv, key, nonce);
|
||||||
sponge.associated_data_processing(associated_data);
|
sponge.associated_data_processing(associated_data);
|
||||||
let cipherChunks = sponge.plaintext_processing(plaintext);
|
let cipherChunks = sponge.plaintext_processing(plaintext);
|
||||||
let ciphertext = kdf.concatUint8Arrays(...cipherChunks);
|
let ciphertext = concatUint8Arrays(...cipherChunks);
|
||||||
let tag = sponge.finalize(key);
|
let tag = sponge.finalize(key);
|
||||||
return {
|
return {
|
||||||
cipher: ciphertext,
|
cipher: ciphertext,
|
||||||
@ -125,7 +115,7 @@ class keccakAEAD {
|
|||||||
let sponge = new keccakAEAD(iv, key, nonce);
|
let sponge = new keccakAEAD(iv, key, nonce);
|
||||||
sponge.associated_data_processing(associated_data);
|
sponge.associated_data_processing(associated_data);
|
||||||
let plaintextChunks = sponge.ciphertext_processing(ciphertext);
|
let plaintextChunks = sponge.ciphertext_processing(ciphertext);
|
||||||
let plaintext = kdf.concatUint8Arrays(...plaintextChunks);
|
let plaintext = concatUint8Arrays(...plaintextChunks);
|
||||||
let tag = sponge.finalize(key);
|
let tag = sponge.finalize(key);
|
||||||
return {
|
return {
|
||||||
plaintext: plaintext,
|
plaintext: plaintext,
|
||||||
@ -134,4 +124,4 @@ class keccakAEAD {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { keccakAEAD };
|
export { keccakAEAD };
|
22
src/public/arrayutils.js
Normal file
22
src/public/arrayutils.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
function concatUint8Arrays(...arrays) {
|
||||||
|
let totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
|
||||||
|
let result = new Uint8Array(totalLength);
|
||||||
|
let offset = 0;
|
||||||
|
for (const arr of arrays) {
|
||||||
|
result.set(arr, offset);
|
||||||
|
offset += arr.length;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitIntoChunks(data) {
|
||||||
|
const chunks = [];
|
||||||
|
const chunkSize = 16;
|
||||||
|
for (let i = 0; i < data.length; i += chunkSize) {
|
||||||
|
const chunk = data.slice(i, i + chunkSize);
|
||||||
|
chunks.push(chunk);
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { concatUint8Arrays, splitIntoChunks };
|
@ -1,4 +1,6 @@
|
|||||||
import { genKeys, sharedKey } from "./ecdh.js";
|
import { genKeys, sharedKey } from "./ecdh.js";
|
||||||
|
import { keccakAEAD } from "./aead.js";
|
||||||
|
import { keccakKDF } from "./kdf.js";
|
||||||
|
|
||||||
const socket = io();
|
const socket = io();
|
||||||
let secret = null;
|
let secret = null;
|
||||||
@ -47,7 +49,7 @@ export function create_listener(form, input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fromHexString = (hexString) =>
|
const fromHexString = (hexString) =>
|
||||||
Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
||||||
|
|
||||||
const toHexString = (bytes) =>
|
const toHexString = (bytes) =>
|
||||||
bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
|
bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
|
||||||
|
@ -1,16 +1,5 @@
|
|||||||
const keccak = require('./keccak');
|
import { concatUint8Arrays } from './arrayutils.js';
|
||||||
|
import { keccak } from './keccak.js';
|
||||||
function concatUint8Arrays(...arrays) {
|
|
||||||
let totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
|
|
||||||
let result = new Uint8Array(totalLength);
|
|
||||||
let offset = 0;
|
|
||||||
for (const arr of arrays) {
|
|
||||||
result.set(arr, offset);
|
|
||||||
offset += arr.length;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class keccakKDF {
|
class keccakKDF {
|
||||||
constructor(encryptionKeyLength = 32, privateKeyLength = 32) {
|
constructor(encryptionKeyLength = 32, privateKeyLength = 32) {
|
||||||
@ -36,5 +25,4 @@ class keccakKDF {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
export { keccakKDF };
|
||||||
module.exports = { keccakKDF, concatUint8Arrays };
|
|
@ -168,4 +168,4 @@ const keccak = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = keccak;
|
export { keccak };
|
@ -15,6 +15,9 @@ html(lang="en-US")
|
|||||||
script(type="module", src="/rooms.js", defer)
|
script(type="module", src="/rooms.js", defer)
|
||||||
script(type="module", src="/ecdh.js", defer)
|
script(type="module", src="/ecdh.js", defer)
|
||||||
script(type="module", src="/popups-logged.js", defer)
|
script(type="module", src="/popups-logged.js", defer)
|
||||||
|
script(type="module", src="/keccak.js", defer)
|
||||||
|
script(type="module", src="/aead.js", defer)
|
||||||
|
script(type="module", src="/kdf.js", defer)
|
||||||
else
|
else
|
||||||
script(type="module", src="/popups.js", defer)
|
script(type="module", src="/popups.js", defer)
|
||||||
script(type="module", src="/register.js", defer)
|
script(type="module", src="/register.js", defer)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const aead = require('../src/aead');
|
import { keccakAEAD } from '../src/public/aead';
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const stringutils = require('../src/stringutils');
|
const stringutils = require('../src/stringutils');
|
||||||
|
|
||||||
@ -17,10 +17,10 @@ describe('aead.js functions', () => {
|
|||||||
let iv = generateRandomUint8Array();
|
let iv = generateRandomUint8Array();
|
||||||
let nonce = generateRandomUint8Array();
|
let nonce = generateRandomUint8Array();
|
||||||
let key = generateRandomUint8Array();
|
let key = generateRandomUint8Array();
|
||||||
let result = aead.keccakAEAD.encrypt(key, msg, iv, ad, nonce);
|
let result = keccakAEAD.encrypt(key, msg, iv, ad, nonce);
|
||||||
let tag_encrypt_hex = stringutils.arrayToHex(result.tag);
|
let tag_encrypt_hex = stringutils.arrayToHex(result.tag);
|
||||||
let cipher_hex = stringutils.arrayToHex(result.cipher);
|
let cipher_hex = stringutils.arrayToHex(result.cipher);
|
||||||
let result2 = aead.keccakAEAD.decrypt(key, result.cipher, iv, ad, nonce);
|
let result2 = keccakAEAD.decrypt(key, result.cipher, iv, ad, nonce);
|
||||||
let tag_decrypt_hex = stringutils.arrayToHex(result2.tag);
|
let tag_decrypt_hex = stringutils.arrayToHex(result2.tag);
|
||||||
let decrypted_hex = stringutils.arrayToHex(result2.plaintext);
|
let decrypted_hex = stringutils.arrayToHex(result2.plaintext);
|
||||||
expect(decrypted_hex).toBe(msg_hex);
|
expect(decrypted_hex).toBe(msg_hex);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const keccak = require('../src/keccak');
|
import { keccak } from '../src/public/keccak';
|
||||||
const stringutils = require('../src/stringutils');
|
const stringutils = require('../src/stringutils');
|
||||||
|
|
||||||
describe('keccak.js functions', () => {
|
describe('keccak.js functions', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user