Skip to content

Commit 70276a3

Browse files
committed
Move argon2 to JS-style scoring.
1 parent 0260caf commit 70276a3

File tree

7 files changed

+981
-38
lines changed

7 files changed

+981
-38
lines changed

JetStreamDriver.js

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ class Driver {
454454
this.isReady = true;
455455
if (isInBrowser) {
456456
globalThis.dispatchEvent(new Event("JetStreamReady"));
457-
if (shouldReport) {
457+
if (typeof(globalThis.startDelay) !== "undefined") {
458458
setTimeout(() => this.start(), globalThis.startDelay);
459459
}
460460
}
@@ -2054,29 +2054,18 @@ const BENCHMARKS = [
20542054
deterministicRandom: true,
20552055
testGroup: WasmGroup
20562056
}),
2057-
new WasmLegacyBenchmark({
2057+
new WasmEMCCBenchmark({
20582058
name: "argon2-wasm",
20592059
files: [
2060-
"./wasm/argon2-bundle.js",
2061-
"./wasm/argon2.js",
2062-
"./wasm/argon2-benchmark.js"
2063-
],
2064-
preload: {
2065-
argon2WasmBlob: "./wasm/argon2.wasm",
2066-
},
2067-
testGroup: WasmGroup
2068-
}),
2069-
new WasmLegacyBenchmark({
2070-
name: "argon2-wasm-simd",
2071-
files: [
2072-
"./wasm/argon2-bundle.js",
2073-
"./wasm/argon2.js",
2074-
"./wasm/argon2-benchmark.js"
2060+
"./wasm/argon2/build/argon2.js",
2061+
"./wasm/argon2/benchmark.js",
20752062
],
20762063
preload: {
2077-
argon2WasmSimdBlob: "./wasm/argon2-simd.wasm",
2064+
wasmBinary: "./wasm/argon2/build/argon2.wasm"
20782065
},
2079-
testGroup: WasmGroup
2066+
iterations: 50,
2067+
testGroup: WasmGroup,
2068+
deterministicRandom: true,
20802069
}),
20812070
// WorkerTests
20822071
new AsyncBenchmark({

wasm/argon2/benchmark.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright (C) 2025 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
let passwordStrings = [
27+
'123456',
28+
'p@assw0rd',
29+
'qwerty',
30+
'汉字漢字',
31+
'كلمة المرور',
32+
'Z7ihQxGE93',
33+
'0pjTjkrnsM',
34+
'6Kg3AmWnVc',
35+
];
36+
37+
// Emscripten doesn't have a way to manage your pointers for you so these will free them when the wrapper dies.
38+
const mallocRegistry = new FinalizationRegistry((ptr) => Module._free(ptr));
39+
40+
class CString {
41+
constructor(string) {
42+
this.ptr = Module.stringToNewUTF8(string);
43+
this.length = Module._strlen(this.ptr);
44+
mallocRegistry.register(this, this.ptr);
45+
}
46+
}
47+
48+
class MallocPtr {
49+
constructor(size) {
50+
this.ptr = Module._malloc(size);
51+
this.size = size;
52+
mallocRegistry.register(this, this.ptr);
53+
}
54+
}
55+
56+
const tCost = 2;
57+
const mCost = 1024;
58+
const parallelism = 1;
59+
const argon2NumberOfTypes = 2;
60+
const version = 0x13;
61+
const saltLength = 12;
62+
63+
class Benchmark {
64+
async runIteration() {
65+
// Instantiate the Wasm module before the first run.
66+
if (!Module._argon2_hash) {
67+
await setupModule(Module);
68+
}
69+
70+
for (let i = 0; i < passwordStrings.length; ++i)
71+
this.hashAndVerify(passwordStrings[i], i % argon2NumberOfTypes);
72+
}
73+
74+
randomSalt() {
75+
let result = new MallocPtr(saltLength);
76+
const numWords = saltLength / 4;
77+
for (let i = 0; i < numWords; ++i)
78+
Module.HEAPU32[result.ptr + i] = Math.floor(Math.random() * (2 ** 32));
79+
return result;
80+
}
81+
82+
hashAndVerify(password, argon2Type) {
83+
password = new CString(password);
84+
let salt = this.randomSalt();
85+
this.hashBuffer = new MallocPtr(24);
86+
this.encodedBuffer = new MallocPtr(Module._argon2_encodedlen(tCost, mCost, parallelism, saltLength, this.hashBuffer.size, argon2Type) + 1);
87+
88+
let status = Module._argon2_hash(tCost, mCost, parallelism, password.ptr, password.length, salt.ptr, salt.size, this.hashBuffer.ptr, this.hashBuffer.size, this.encodedBuffer.ptr, this.encodedBuffer.size, argon2Type, version);
89+
if (status !== 0)
90+
throw new Error(`argon2_hash exited with status: ${status} (${Module.UTF8ToString(Module._argon2_error_message(status))})`);
91+
92+
status = Module._argon2_verify(this.encodedBuffer.ptr, password.ptr, password.length, argon2Type);
93+
if (status !== 0)
94+
throw new Error(`argon2_verify exited with status: ${status} (${Module.UTF8ToString(Module._argon2_error_message(status))})`);
95+
}
96+
}

wasm/argon2/build.log

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Built on 2025-02-11T15:51:03Z
2+
Toolchain versions
3+
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.0-git
4+
Building...
5+
Building done

wasm/argon2/build.sh

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,72 @@
11
#!/usr/bin/env bash
22

3-
set -e
4-
set -o pipefail
53

6-
# Log emcc version
7-
EMCC_SDK_PATH="/path/to/emsdk"
8-
EMCC_PATH="$EMCC_SDK_PATH/upstream/emscripten/emcc"
9-
$EMCC_PATH --version > emcc_version.txt
4+
#!/bin/bash
105

11-
# Build start
12-
rm -rf dist
13-
mkdir dist
6+
set -euo pipefail
147

15-
./clean-cmake.sh
16-
EMCC_SDK_PATH=$EMCC_SDK_PATH ARGON_JS_BUILD_BUILD_WITH_SIMD=1 ./build-wasm.sh
17-
mv dist/argon2.wasm ../argon2-simd.wasm
8+
rm -rf build/
189

19-
./clean-cmake.sh
20-
EMCC_SDK_PATH=$EMCC_SDK_PATH ARGON_JS_BUILD_BUILD_WITH_SIMD=0 ./build-wasm.sh
21-
mv dist/argon2.wasm ../argon2.wasm
10+
touch build.log
11+
BUILD_LOG="$(realpath build.log)"
12+
echo "Built on $(date -u '+%Y-%m-%dT%H:%M:%SZ')" | tee "$BUILD_LOG"
2213

23-
./clean-cmake.sh
24-
rm -rf dist
25-
# Build end
14+
echo "Toolchain versions" | tee -a "$BUILD_LOG"
15+
emcc --version | head -n1 | tee -a "$BUILD_LOG"
2616

27-
echo Done
17+
# FIXME: Redownload the source if argon2 ever has source updates. At the time of writing it was last changed 5 years ago so this is probably not a high priority.
18+
SOURCES=(
19+
argon2/src/blake2/blake2b.c
20+
21+
argon2/src/argon2.c
22+
argon2/src/core.c
23+
argon2/src/encoding.c
24+
argon2/src/thread.c
25+
26+
argon2/src/opt.c
27+
)
28+
29+
SIMD_FLAGS=(
30+
-msimd128
31+
-msse2
32+
)
33+
34+
echo "Building..." | tee -a "$BUILD_LOG"
35+
mkdir build/
36+
emcc -o build/argon2.js \
37+
-s WASM=1 -O2 \
38+
${SIMD_FLAGS[@]} \
39+
-g1 --emit-symbol-map \
40+
-DARGON2_NO_THREADS \
41+
-s MODULARIZE=1 -s EXPORT_NAME=setupModule -s EXPORTED_RUNTIME_METHODS=stringToNewUTF8,UTF8ToString -s EXPORTED_FUNCTIONS=_argon2_hash,_argon2_verify,_argon2_encodedlen,_argon2_error_message,_malloc,_free,_strlen \
42+
-Iargon2/include \
43+
${SOURCES[@]} | tee -a "$BUILD_LOG"
44+
45+
echo "Building done" | tee -a "$BUILD_LOG"
46+
ls -lth build/
47+
48+
# set -e
49+
# set -o pipefail
50+
51+
# # Log emcc version
52+
# EMCC_SDK_PATH="/path/to/emsdk"
53+
# EMCC_PATH="$EMCC_SDK_PATH/upstream/emscripten/emcc"
54+
# $EMCC_PATH --version > emcc_version.txt
55+
56+
# # Build start
57+
# rm -rf dist
58+
# mkdir dist
59+
60+
# ./clean-cmake.sh
61+
# EMCC_SDK_PATH=$EMCC_SDK_PATH ARGON_JS_BUILD_BUILD_WITH_SIMD=1 ./build-wasm.sh
62+
# mv dist/argon2.wasm ../argon2-simd.wasm
63+
64+
# ./clean-cmake.sh
65+
# EMCC_SDK_PATH=$EMCC_SDK_PATH ARGON_JS_BUILD_BUILD_WITH_SIMD=0 ./build-wasm.sh
66+
# mv dist/argon2.wasm ../argon2.wasm
67+
68+
# ./clean-cmake.sh
69+
# rm -rf dist
70+
# # Build end
71+
72+
# echo Done

0 commit comments

Comments
 (0)