Giter Club home page Giter Club logo

Comments (2)

stanleyyzhu avatar stanleyyzhu commented on August 29, 2024 1

I got the exactly same error but turned out that I can use the "argon2-bundled.min.js" instead

import argon2 from 'argon2-browser/dist/argon2-bundled.min.js';

from argon2-browser.

peterhirn avatar peterhirn commented on August 29, 2024

@Techiton Did you figure out a way to make this work?

Update

I was able to make it work with Astro/Vite based on https://github.com/antelle/argon2-browser/blob/master/docs/js/calc.js

import argon2Wasm from "argon2-browser/dist/argon2-simd.wasm?url";
import argon2Js from "argon2-browser/dist/argon2.js?url";

interface Module {
  ALLOC_NORMAL: number;
  wasmBinary: ArrayBuffer;
  wasmJSMethod: string;
  wasmMemory: WebAssembly.Memory;
  buffer: ArrayBuffer;
  TOTAL_MEMORY: number;
  postRun: () => void;
  allocate: (array: Uint8Array, type: string, allocator: number) => Uint8Array;
  _free: (array: Uint8Array) => void;
  _argon2_hash_ext: (
    timeCost: number,
    memoryCost: number,
    parallelism: number,
    pass: Uint8Array,
    passLenght: number,
    salt: Uint8Array,
    saltLength: number,
    hash: Uint8Array,
    hashLength: number,
    encoded: Uint8Array,
    encodedLength: number,
    type: number,
    secret: Uint8Array | number,
    secretLength: number,
    ad: Uint8Array | number,
    adLenght: number,
    version: number,
  ) => number;
  _argon2_encodedlen: (
    timeCost: number,
    memoryCost: number,
    parallelism: number,
    saltLength: number,
    hashLength: number,
    type: number,
  ) => number;
  _argon2_error_message: (res: number) => Uint8Array;
  UTF8ToString: (array: Uint8Array) => string;
}

declare global {
  // eslint-disable-next-line
  var Module: Module;
}

const loadScript = (src: string) =>
  new Promise((resolve, reject) => {
    const element = document.createElement("script");
    element.src = src;
    element.onload = resolve;
    element.onerror = reject;
    document.body.appendChild(element);
  });

const encodeUtf8 = (str: string) => new TextEncoder().encode(str);

const allocate = (array: Uint8Array) =>
  globalThis.Module.allocate(array, "i8", globalThis.Module.ALLOC_NORMAL);

const initialize = async (memoryCost: number) => {
  if (globalThis.Module?._argon2_hash_ext !== undefined) {
    return;
  }

  const KB = 1024 * 1024;
  const MB = 1024 * KB;
  const GB = 1024 * MB;
  const WASM_PAGE_SIZE = 64 * 1024;

  const totalMemory = (2 * GB - 64 * KB) / 1024 / WASM_PAGE_SIZE;
  const initialMemory = Math.min(
    Math.max(Math.ceil((memoryCost * 1024) / WASM_PAGE_SIZE), 256) + 256,
    totalMemory,
  );

  const wasmMemory = new WebAssembly.Memory({
    initial: initialMemory,
    maximum: totalMemory,
  });

  const wasm = await fetch(argon2Wasm);
  const wasmBinary = await wasm.arrayBuffer();

  const moduleLoaded = new Promise((resolve) => {
    globalThis.Module = {
      wasmBinary,
      wasmJSMethod: "native-wasm",
      wasmMemory: wasmMemory,
      buffer: wasmMemory.buffer,
      TOTAL_MEMORY: initialMemory * WASM_PAGE_SIZE,
      postRun: resolve,
    } as Module;
  });

  await loadScript(argon2Js);
  await moduleLoaded;
};

const generateSalt = (length: number) => {
  const array = new Uint8Array(length);
  self.crypto.getRandomValues(array);
  return array;
};

export const hash = async (password: string) => {
  // NOTE: Using dovecot defaults with increased parallelism
  const type = 2;
  const timeCost = 3;
  const memoryCost = 65536;
  const parallelism = 4;
  const hashLength = 32;
  const saltLength = 16;

  await initialize(memoryCost);

  const passEncoded = encodeUtf8(password);
  const pwd = allocate(passEncoded);
  const salt = allocate(generateSalt(saltLength));

  const encodedLength = globalThis.Module._argon2_encodedlen(
    timeCost,
    memoryCost,
    parallelism,
    saltLength,
    hashLength,
    type,
  );

  const hash = allocate(new Uint8Array(hashLength));
  const encoded = allocate(new Uint8Array(encodedLength + 1));

  const result = globalThis.Module._argon2_hash_ext(
    timeCost,
    memoryCost,
    parallelism,
    pwd,
    passEncoded.length,
    salt,
    saltLength,
    hash,
    hashLength,
    encoded,
    encodedLength,
    type,
    0,
    0,
    0,
    0,
    0x13,
  );

  if (result !== 0) {
    throw Error(
      globalThis.Module.UTF8ToString(
        globalThis.Module._argon2_error_message(result),
      ),
    );
  }

  const output = globalThis.Module.UTF8ToString(encoded);

  globalThis.Module._free(pwd);
  globalThis.Module._free(salt);
  globalThis.Module._free(hash);
  globalThis.Module._free(encoded);

  return output;
};

from argon2-browser.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.