diff --git a/argon2.js b/argon2.js new file mode 100644 index 0000000..be40552 --- /dev/null +++ b/argon2.js @@ -0,0 +1 @@ +var Module=typeof self!=="undefined"&&typeof self.Module!=="undefined"?self.Module:{};var jsModule=Module;var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var ALLOC_NORMAL=0;var ALLOC_STACK=1;function allocate(slab,allocator){var ret;if(allocator==ALLOC_STACK){ret=stackAlloc(slab.length)}else{ret=_malloc(slab.length)}if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;__ATINIT__.push({func:function(){___wasm_call_ctors()}});function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function preMain(){callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);throw e}function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="argon2.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}else{if(readAsync){return new Promise(function(resolve,reject){readAsync(wasmBinaryFile,function(response){resolve(new Uint8Array(response))},reject)})}}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["c"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["k"];removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){Module=jsModule;if(typeof self!=="undefined")self.Module=Module;receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){wasmTable.get(func)()}else{wasmTable.get(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var maxHeapSize=2147418112;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),65536));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var asmLibraryArg={"a":_emscripten_memcpy_big,"b":_emscripten_resize_heap};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["d"]).apply(null,arguments)};var _argon2_hash=Module["_argon2_hash"]=function(){return(_argon2_hash=Module["_argon2_hash"]=Module["asm"]["e"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["f"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["g"]).apply(null,arguments)};var _argon2_verify=Module["_argon2_verify"]=function(){return(_argon2_verify=Module["_argon2_verify"]=Module["asm"]["h"]).apply(null,arguments)};var _argon2_error_message=Module["_argon2_error_message"]=function(){return(_argon2_error_message=Module["_argon2_error_message"]=Module["asm"]["i"]).apply(null,arguments)};var _argon2_encodedlen=Module["_argon2_encodedlen"]=function(){return(_argon2_encodedlen=Module["_argon2_encodedlen"]=Module["asm"]["j"]).apply(null,arguments)};var _argon2_hash_ext=Module["_argon2_hash_ext"]=function(){return(_argon2_hash_ext=Module["_argon2_hash_ext"]=Module["asm"]["l"]).apply(null,arguments)};var _argon2_verify_ext=Module["_argon2_verify_ext"]=function(){return(_argon2_verify_ext=Module["_argon2_verify_ext"]=Module["asm"]["m"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["n"]).apply(null,arguments)};Module["allocate"]=allocate;Module["UTF8ToString"]=UTF8ToString;Module["ALLOC_NORMAL"]=ALLOC_NORMAL;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();if(typeof module!=="undefined")module.exports=Module;Module.unloadRuntime=function(){if(typeof self!=="undefined"){delete self.Module}Module=jsModule=wasmMemory=wasmTable=asm=buffer=HEAP8=HEAPU8=HEAP16=HEAPU16=HEAP32=HEAPU32=HEAPF32=HEAPF64=undefined;if(typeof module!=="undefined"){delete module.exports}}; diff --git a/argon2.wasm b/argon2.wasm new file mode 100644 index 0000000..fdf06c8 Binary files /dev/null and b/argon2.wasm differ diff --git a/compile-wasm.sh b/compile-wasm.sh new file mode 100755 index 0000000..14dfd2d --- /dev/null +++ b/compile-wasm.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Clone and set up Emscripten SDK +git clone https://github.com/emscripten-core/emsdk.git +cd emsdk +./emsdk install latest +./emsdk activate latest +source ./emsdk_env.sh +cd .. + +# Clone the Argon2 repository +git clone https://github.com/P-H-C/phc-winner-argon2.git +cd phc-winner-argon2 + +# Compile Argon2 to WebAssembly +emcc -Iinclude -O3 -s WASM=1 -s MODULARIZE=1 \ +-s 'EXTRA_EXPORTED_RUNTIME_METHODS=["cwrap", "UTF8ToString"]' \ +-s 'EXPORTED_FUNCTIONS=["_argon2_hash", "_argon2_error_message", "_malloc", "_free"]' \ +-o argon2.js src/argon2.c src/core.c src/blake2/blake2b.c src/thread.c src/encoding.c src/ref.c + +# Move the generated files to the parent directory +mv argon2.js ../ +mv argon2.wasm ../ + +# Go back to the parent directory +cd .. + +# Clean up +rm -rf emsdk phc-winner-argon2 + +echo "WASM files compiled and moved to the project root successfully." diff --git a/download-wasm.sh b/download-wasm.sh new file mode 100644 index 0000000..e640bad --- /dev/null +++ b/download-wasm.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# URLs for the WASM files +ARGON2_JS_URL="https://raw.githubusercontent.com/antelle/argon2-browser/master/docs/dist/argon2.js" +ARGON2_WASM_URL="https://raw.githubusercontent.com/antelle/argon2-browser/master/docs/dist/argon2.wasm" + +# Download the files +curl -o argon2.js $ARGON2_JS_URL +curl -o argon2.wasm $ARGON2_WASM_URL + +echo "WASM files downloaded successfully." diff --git a/index.html b/index.html index 7287427..7d66fcd 100644 --- a/index.html +++ b/index.html @@ -1,32 +1,57 @@ - - Argon2id-JS - - - - - - - - -

Argon BWG

- - - - - - - - - - - - - - - -

Border Wallet Generator

Entropy generated

Performance

12/24 word Mnemonic Wallet

- - - \ No newline at end of file + + Argon2id-JS + + + + + + + + +

Argon BWG

+ + + + + + + + + + + + + + + +

Border Wallet Generator

Entropy generated

Performance

12/24 word Mnemonic Wallet

+ + + diff --git a/index.js b/index.js index a44dc8d..3da6c31 100644 --- a/index.js +++ b/index.js @@ -1,95 +1,212 @@ +console.log('Script loaded'); + +function ensureArgon2Loaded() { + return new Promise((resolve, reject) => { + if (window.argon2Ready) { + console.log('Argon2 already ready'); + resolve(); + } else { + console.log('Waiting for Argon2 to be ready...'); + const checkReady = setInterval(() => { + if (window.argon2Ready) { + clearInterval(checkReady); + console.log('Argon2 became ready'); + resolve(); + } + }, 100); + + // Add a timeout + setTimeout(() => { + clearInterval(checkReady); + console.error('Timeout waiting for Argon2 to be ready'); + console.log('Module status:', window.Module); + console.log('argon2Ready status:', window.argon2Ready); + reject(new Error('Argon2 initialization timeout')); + }, 20000); // 20 second timeout + } + }); +} + document.getElementById('entropy').value = ''; -document.getElementById('p').value = '2'; // Threads -document.getElementById('m').value = '1024'; // Memory KiB -document.getElementById('i').value = '3600'; // Iterations -document.getElementById('l').value = '32'; // Hash length -document.getElementById('size').value = '64'; // Hexadecimal digits +document.getElementById('p').value = '2'; // Threads +document.getElementById('m').value = '1024'; // Memory KiB +document.getElementById('i').value = '3600'; // Iterations +document.getElementById('l').value = '32'; // Hash length +document.getElementById('size').value = '64'; // Hexadecimal digits document.getElementById('file').addEventListener('change', hashfile); document.getElementById('entropy').addEventListener('change', updateMnemonic); document.getElementById('size').addEventListener('change', updateMnemonic); -document.getElementById('start').addEventListener('click', () => { - let message = document.getElementById('message').value; - let salt = document.getElementById('salt').value; - let p = document.getElementById('p').value; - let m = document.getElementById('m').value; - let i = document.getElementById('i').value; - let l = document.getElementById('l').value; - let secret = ''; - let associatedData = ''; - - message = bytesToHex(hexToBytes(message)); - document.getElementById('message').value = message; - document.getElementById('entropy').value = ''; - document.getElementById('mnemonic').innerHTML = ''; - document.getElementById('perf').innerHTML = "Generating..."; - - let timerStart = Date.now(); - Argon2id.hashEncoded(message, salt, i, m, p, l, secret, associatedData).then(hashEncoded => { - let hashHex = Argon2id.hashDecode(hashEncoded); - let timerEnd = calcT(timerStart); - - let entropy = document.getElementById('entropy'); - entropy.value = hashHex; - entropy.dispatchEvent(new Event('change')); - - document.getElementById('perf').innerHTML = "Generating the mnemonic took " + timerEnd + "ms."; - }); +async function hashPassword(message, salt, iterations, memory, parallelism, hashLength) { + console.log('hashPassword called with:', { message, salt, iterations, memory, parallelism, hashLength }); + await ensureArgon2Loaded(); + console.log('Argon2 confirmed loaded in hashPassword'); + try { + const argon2 = window.argon2; + + // Convert inputs to Uint8Array + const messageArray = new TextEncoder().encode(message); + const saltArray = new TextEncoder().encode(salt); + + console.log('Encoded messageArray:', messageArray); + console.log('Encoded saltArray:', saltArray); + + // Allocate memory + const messagePtr = argon2._malloc(messageArray.length); + const saltPtr = argon2._malloc(saltArray.length); + const hashPtr = argon2._malloc(hashLength); + + // Write data to memory + argon2.HEAPU8.set(messageArray, messagePtr); + argon2.HEAPU8.set(saltArray, saltPtr); + + console.log('Calling _argon2_hash with:', { + iterations, + memory, + parallelism, + messageLength: messageArray.length, + saltLength: saltArray.length, + hashLength + }); + + // Call the _argon2_hash function + const result = argon2._argon2_hash( + iterations, + memory, // Memory should be in KiB + parallelism, + messagePtr, + messageArray.length, + saltPtr, + saltArray.length, + hashPtr, + hashLength, + 0, // no encoded output + 2 // Argon2_id + ); + + console.log('Argon2 result code:', result); + + if (result !== 0) { + const errorMessage = argon2.UTF8ToString(argon2._argon2_error_message(result)); + throw new Error(`Argon2 error: ${errorMessage} (code ${result})`); + } + + // Read the result + const hashArray = argon2.HEAPU8.slice(hashPtr, hashPtr + hashLength); + console.log('Hash array:', hashArray); + + const hashHex = Array.from(hashArray, b => b.toString(16).padStart(2, '0')).join(''); + console.log('Hash hex:', hashHex); + + // Free allocated memory + argon2._free(messagePtr); + argon2._free(saltPtr); + argon2._free(hashPtr); + + console.log('Argon2 hash result:', hashHex); + return hashHex; + } catch (e) { + console.error('Error during Argon2 hashing:', e); + throw e; + } +} + +document.getElementById('start').addEventListener('click', async () => { + console.log('Generate button clicked'); + try { + await ensureArgon2Loaded(); + console.log('Argon2 confirmed loaded'); + + let message = document.getElementById('message').value; + let salt = document.getElementById('salt').value; + let p = parseInt(document.getElementById('p').value); + let m = parseInt(document.getElementById('m').value); + let i = parseInt(document.getElementById('i').value); + let l = parseInt(document.getElementById('l').value); + + console.log('Inputs:', { message, salt, p, m, i, l }); + + document.getElementById('entropy').value = ''; + document.getElementById('mnemonic').innerHTML = ''; + document.getElementById('perf').innerHTML = "Generating..."; + + let timerStart = Date.now(); + console.log('Starting hash generation'); + const hashHex = await hashPassword(message, salt, i, m, p, l); + console.log('Hash generated:', hashHex); + let timerEnd = Date.now() - timerStart; + + let entropy = document.getElementById('entropy'); + entropy.value = hashHex; + entropy.dispatchEvent(new Event('change')); + + document.getElementById('perf').innerHTML = `Generating the mnemonic took ${timerEnd}ms.`; + } catch (error) { + console.error('Error during hash generation:', error); + document.getElementById('perf').innerHTML = `Error: ${error.message}`; + } }); function updateMnemonic() { - let hashHex = document.getElementById('entropy').value; - let mnemonicSize = document.getElementById('size').value; - let mnemonics = { "english": new Mnemonic("english") }; - let mnemonic = mnemonics["english"]; - let entropy = hexToBytes(hashHex.substr(0, mnemonicSize)); - let words = mnemonic.toMnemonic(entropy); - - document.getElementById('mnemonic').innerHTML = words; -} + let hashHex = document.getElementById('entropy').value; + let mnemonicSize = parseInt(document.getElementById('size').value); + let mnemonics = { "english": new Mnemonic("english") }; + let mnemonic = mnemonics["english"]; + let entropy = hexToBytes(hashHex.substr(0, mnemonicSize)); + let words = mnemonic.toMnemonic(entropy); -function calcT(timer){ - return Date.now() - timer; + document.getElementById('mnemonic').innerHTML = words; } -// Convert a hex string to a byte array function hexToBytes(hex) { - for (var bytes = [], c = 0; c < hex.length; c += 2) + let bytes = []; + for (let c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)); return bytes; } -// Convert a byte array to a hex string function bytesToHex(bytes) { - for (var hex = [], i = 0; i < bytes.length; i++) { - var current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i]; - hex.push((current >>> 4).toString(16)); - hex.push((current & 0xF).toString(16)); - } - return hex.join(""); + return bytes.map(b => b.toString(16).padStart(2, '0')).join(''); } -// Calculate SHA256 of a file selected function hashfile() { - let fileselector = document.getElementById('file'); - readbinaryfile(fileselector.files[0]) - .then(function (result) { - result = new Uint8Array(result); - return window.crypto.subtle.digest('SHA-256', result); - }).then(function (result) { - result = new Uint8Array(result); - var resulthex = bytesToHex(result); - document.getElementById('message').value = resulthex; - }); + let fileselector = document.getElementById('file'); + if (fileselector.files.length === 0) { + console.error('No file selected'); + return; + } + + const file = fileselector.files[0]; + const reader = new FileReader(); + + reader.onload = function(event) { + const arrayBuffer = event.target.result; + crypto.subtle.digest('SHA-256', arrayBuffer) + .then(function(hash) { + const hashArray = Array.from(new Uint8Array(hash)); + const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); + console.log('File SHA256:', hashHex); + document.getElementById('message').value = hashHex; + }) + .catch(function(error) { + console.error('Error calculating SHA256:', error); + }); + }; + + reader.onerror = function(event) { + console.error('File reading error:', event.target.error); + }; + + reader.readAsArrayBuffer(file); } function readbinaryfile(file) { - return new Promise((resolve, reject) => { - var fr = new FileReader(); - fr.onload = () => { - resolve(fr.result) - }; - fr.readAsArrayBuffer(file); - }); -} \ No newline at end of file + return new Promise((resolve, reject) => { + var fr = new FileReader(); + fr.onload = () => { + resolve(fr.result) + }; + fr.readAsArrayBuffer(file); + }); +}