diff --git a/src/aead.js b/src/public/aead.js similarity index 78% rename from src/aead.js rename to src/public/aead.js index 446c9c5..238c0a6 100644 --- a/src/aead.js +++ b/src/public/aead.js @@ -1,27 +1,17 @@ -const kdf = require('./kdf'); -const keccak = require('./keccak'); - -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; -} +import { concatUint8Arrays, splitIntoChunks } from './arrayutils.js'; +import { keccak } from './keccak.js'; class keccakAEAD { constructor(iv, key, nonce) { - const input = kdf.concatUint8Arrays(iv, key, nonce); + const input = concatUint8Arrays(iv, key, nonce); this.state = keccak.SHAKE256(input, 40); let r = this.state.slice(0, 16); 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++) { c[i] ^= key[i]; } - this.state = kdf.concatUint8Arrays(r, c); + this.state = concatUint8Arrays(r, c); } associated_data_processing(associated_data) { @@ -37,7 +27,7 @@ class keccakAEAD { for (let i = 0; i < chunk.length; i++) { r[i] = chunk[i] ^ to_xor[i]; } - input = kdf.concatUint8Arrays(r, c); + input = concatUint8Arrays(r, c); this.state = keccak.SHAKE256(input, 40); }); r = this.state.slice(0, 16); @@ -47,7 +37,7 @@ class keccakAEAD { for (let i = 0; i < c.length; i++) { c[i] ^= to_xor[i]; } - this.state = kdf.concatUint8Arrays(r, c); + this.state = concatUint8Arrays(r, c); } plaintext_processing(plaintext) { @@ -65,7 +55,7 @@ class keccakAEAD { r[i] = chunk[i] ^ to_xor[i]; } cipherchunks.push(r); - input = kdf.concatUint8Arrays(r, c); + input = concatUint8Arrays(r, c); this.state = keccak.SHAKE256(input, 40); }); return cipherchunks; @@ -86,7 +76,7 @@ class keccakAEAD { r[i] = chunk[i] ^ to_xor[i]; } plaintextchunks.push(r); - input = kdf.concatUint8Arrays(chunk, c); + input = concatUint8Arrays(chunk, c); this.state = keccak.SHAKE256(input, 40); }); return plaintextchunks; @@ -95,11 +85,11 @@ class keccakAEAD { finalize(key) { let r = this.state.slice(0, 16); 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++) { c[i] ^= padded_key[i]; } - this.state = kdf.concatUint8Arrays(r, c); + this.state = concatUint8Arrays(r, c); const output = keccak.SHAKE256(this.state, 40); let to_xor = output.slice(40-key.length, 40); let tag = new Uint8Array(key.length); @@ -113,7 +103,7 @@ class keccakAEAD { let sponge = new keccakAEAD(iv, key, nonce); sponge.associated_data_processing(associated_data); let cipherChunks = sponge.plaintext_processing(plaintext); - let ciphertext = kdf.concatUint8Arrays(...cipherChunks); + let ciphertext = concatUint8Arrays(...cipherChunks); let tag = sponge.finalize(key); return { cipher: ciphertext, @@ -125,7 +115,7 @@ class keccakAEAD { let sponge = new keccakAEAD(iv, key, nonce); sponge.associated_data_processing(associated_data); let plaintextChunks = sponge.ciphertext_processing(ciphertext); - let plaintext = kdf.concatUint8Arrays(...plaintextChunks); + let plaintext = concatUint8Arrays(...plaintextChunks); let tag = sponge.finalize(key); return { plaintext: plaintext, @@ -134,4 +124,4 @@ class keccakAEAD { } } -module.exports = { keccakAEAD }; +export { keccakAEAD }; diff --git a/src/public/arrayutils.js b/src/public/arrayutils.js new file mode 100644 index 0000000..574e18c --- /dev/null +++ b/src/public/arrayutils.js @@ -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 }; diff --git a/src/public/chat.js b/src/public/chat.js index 9f4b541..6c8db40 100644 --- a/src/public/chat.js +++ b/src/public/chat.js @@ -1,4 +1,6 @@ import { genKeys, sharedKey } from "./ecdh.js"; +import { keccakAEAD } from "./aead.js"; +import { keccakKDF } from "./kdf.js"; const socket = io(); let secret = null; @@ -47,7 +49,7 @@ export function create_listener(form, input) { } 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) => - bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), ''); + bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), ''); diff --git a/src/kdf.js b/src/public/kdf.js similarity index 69% rename from src/kdf.js rename to src/public/kdf.js index 24e381b..4a57272 100644 --- a/src/kdf.js +++ b/src/public/kdf.js @@ -1,16 +1,5 @@ -const keccak = require('./keccak'); - -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; -} - +import { concatUint8Arrays } from './arrayutils.js'; +import { keccak } from './keccak.js'; class keccakKDF { constructor(encryptionKeyLength = 32, privateKeyLength = 32) { @@ -36,5 +25,4 @@ class keccakKDF { } } - -module.exports = { keccakKDF, concatUint8Arrays }; +export { keccakKDF }; diff --git a/src/keccak.js b/src/public/keccak.js similarity index 99% rename from src/keccak.js rename to src/public/keccak.js index 42f6155..2c1ead9 100644 --- a/src/keccak.js +++ b/src/public/keccak.js @@ -168,4 +168,4 @@ const keccak = { } } -module.exports = keccak; +export { keccak }; diff --git a/src/views/index.pug b/src/views/index.pug index 3cd284f..69e1a9f 100644 --- a/src/views/index.pug +++ b/src/views/index.pug @@ -15,6 +15,9 @@ html(lang="en-US") script(type="module", src="/rooms.js", defer) script(type="module", src="/ecdh.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 script(type="module", src="/popups.js", defer) script(type="module", src="/register.js", defer) diff --git a/tests/aead.test.js b/tests/aead.test.js index 23c9f4b..8901631 100644 --- a/tests/aead.test.js +++ b/tests/aead.test.js @@ -1,4 +1,4 @@ -const aead = require('../src/aead'); +import { keccakAEAD } from '../src/public/aead'; const crypto = require('crypto'); const stringutils = require('../src/stringutils'); @@ -17,10 +17,10 @@ describe('aead.js functions', () => { let iv = generateRandomUint8Array(); let nonce = 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 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 decrypted_hex = stringutils.arrayToHex(result2.plaintext); expect(decrypted_hex).toBe(msg_hex); diff --git a/tests/keccak.test.js b/tests/keccak.test.js index 2e46024..fab388b 100644 --- a/tests/keccak.test.js +++ b/tests/keccak.test.js @@ -1,4 +1,4 @@ -const keccak = require('../src/keccak'); +import { keccak } from '../src/public/keccak'; const stringutils = require('../src/stringutils'); describe('keccak.js functions', () => {