Skip to content

Commit 1a52547

Browse files
panvaGitHub Copilot
andcommitted
implement a subset of "Modern Algorithms in the Web Cryptography API"
Co-authored-by: GitHub Copilot <copilot@github.com>
1 parent 9039529 commit 1a52547

27 files changed

Lines changed: 2527 additions & 230 deletions

build/wpt_test.bzl

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ PORT_BINDINGS = [
2222
### (Invokes wpt_js_test_gen, wpt_wd_test_gen and wd_test to assemble a complete test suite.)
2323
### -----------------------------------------------------------------------------------------
2424

25-
def wpt_test(name, wpt_directory, config, compat_date = "", compat_flags = [], autogates = [], start_server = False, **kwargs):
25+
def wpt_test(name, wpt_directory, config, compat_date = "", compat_flags = [], autogates = [], start_server = False, include_tentative = False, **kwargs):
2626
"""
2727
Main entry point.
2828
@@ -51,6 +51,7 @@ def wpt_test(name, wpt_directory, config, compat_date = "", compat_flags = [], a
5151
wpt_directory = wpt_directory,
5252
test_config = test_config_as_js,
5353
wpt_tsproject = wpt_tsproject,
54+
include_tentative = include_tentative,
5455
)
5556

5657
wd_test_gen_rule = "{}@_wpt_wd_test_gen".format(name)
@@ -144,7 +145,7 @@ def _wpt_js_test_gen_impl(ctx):
144145
base = ctx.attr.wpt_directory[WPTModuleInfo].base
145146

146147
files = ctx.attr.wpt_directory.files.to_list()
147-
test_files = [file for file in files if is_test_file(file)]
148+
test_files = [file for file in files if is_test_file(file, ctx.attr.include_tentative)]
148149

149150
ctx.actions.write(
150151
output = src,
@@ -171,6 +172,8 @@ _wpt_js_test_gen = rule(
171172
"test_config": attr.label(allow_single_file = True),
172173
# Dependency: The ts_project rule that compiles the tests to JS
173174
"wpt_tsproject": attr.label(),
175+
# Whether to include tentative test files
176+
"include_tentative": attr.bool(default = False),
174177
},
175178
)
176179

@@ -187,7 +190,7 @@ const {{ run, printResults }} = createRunner(config, '{test_name}', allTestFiles
187190
export const zzz_results = printResults();
188191
"""
189192

190-
def is_test_file(file):
193+
def is_test_file(file, include_tentative = False):
191194
if not file.path.endswith(".js"):
192195
# Not JS code, not a test
193196
return False
@@ -198,7 +201,7 @@ def is_test_file(file):
198201
# into the main directory, and would need to manually be marked as skipAllTests
199202
return False
200203

201-
if ".tentative." in file.path or "/tentative/" in file.path:
204+
if not include_tentative and (".tentative." in file.path or "/tentative/" in file.path):
202205
# Tentative tests are for proposed features that are not yet standardized.
203206
# We skip these to avoid noise from unstable specifications.
204207
return False

deps/rust/Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deps/rust/cargo.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PACKAGES = WORKERD_CXX_PACKAGES | {
2929
# param_extractor depends on unbounded_depth feature
3030
"serde_json": crate.spec(version = "1", features = ["unbounded_depth"]),
3131
"serde": crate.spec(version = "1", features = ["derive"]),
32+
"sha3": crate.spec(version = "0", default_features = False),
3233
"thiserror": crate.spec(version = "2"),
3334
# tokio is huge, let's enable only features when we actually need them.
3435
"tokio": crate.spec(version = "1", default_features = False, features = ["net", "rt", "rt-multi-thread", "time"]),

deps/rust/crates/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,18 @@ alias(
337337
tags = ["manual"],
338338
)
339339

340+
alias(
341+
name = "sha3-0.10.8",
342+
actual = "@crates_vendor__sha3-0.10.8//:sha3",
343+
tags = ["manual"],
344+
)
345+
346+
alias(
347+
name = "sha3",
348+
actual = "@crates_vendor__sha3-0.10.8//:sha3",
349+
tags = ["manual"],
350+
)
351+
340352
alias(
341353
name = "static_assertions-1.1.0",
342354
actual = "@crates_vendor__static_assertions-1.1.0//:static_assertions",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
###############################################################################
2+
# @generated
3+
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
4+
# regenerate this file, run the following:
5+
#
6+
# bazel run @@//deps/rust:crates_vendor
7+
###############################################################################
8+
9+
load("@rules_rust//rust:defs.bzl", "rust_library")
10+
11+
package(default_visibility = ["//visibility:public"])
12+
13+
rust_library(
14+
name = "keccak",
15+
srcs = glob(
16+
include = ["**/*.rs"],
17+
allow_empty = True,
18+
),
19+
compile_data = glob(
20+
include = ["**"],
21+
allow_empty = True,
22+
exclude = [
23+
"**/* *",
24+
".tmp_git_root/**/*",
25+
"BUILD",
26+
"BUILD.bazel",
27+
"WORKSPACE",
28+
"WORKSPACE.bazel",
29+
],
30+
),
31+
crate_root = "src/lib.rs",
32+
edition = "2018",
33+
rustc_flags = [
34+
"--cap-lints=allow",
35+
],
36+
tags = [
37+
"cargo-bazel",
38+
"crate-name=keccak",
39+
"manual",
40+
"noclippy",
41+
"norustfmt",
42+
],
43+
version = "0.1.6",
44+
deps = select({
45+
"@rules_rust//rust/platform:aarch64-apple-darwin": [
46+
"@crates_vendor__cpufeatures-0.2.17//:cpufeatures", # cfg(target_arch = "aarch64")
47+
],
48+
"@rules_rust//rust/platform:aarch64-unknown-linux-gnu": [
49+
"@crates_vendor__cpufeatures-0.2.17//:cpufeatures", # cfg(target_arch = "aarch64")
50+
],
51+
"//conditions:default": [],
52+
}),
53+
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
###############################################################################
2+
# @generated
3+
# DO NOT MODIFY: This file is auto-generated by a crate_universe tool. To
4+
# regenerate this file, run the following:
5+
#
6+
# bazel run @@//deps/rust:crates_vendor
7+
###############################################################################
8+
9+
load("@rules_rust//rust:defs.bzl", "rust_library")
10+
11+
package(default_visibility = ["//visibility:public"])
12+
13+
rust_library(
14+
name = "sha3",
15+
srcs = glob(
16+
include = ["**/*.rs"],
17+
allow_empty = True,
18+
),
19+
compile_data = glob(
20+
include = ["**"],
21+
allow_empty = True,
22+
exclude = [
23+
"**/* *",
24+
".tmp_git_root/**/*",
25+
"BUILD",
26+
"BUILD.bazel",
27+
"WORKSPACE",
28+
"WORKSPACE.bazel",
29+
],
30+
),
31+
crate_root = "src/lib.rs",
32+
edition = "2018",
33+
rustc_flags = [
34+
"--cap-lints=allow",
35+
],
36+
tags = [
37+
"cargo-bazel",
38+
"crate-name=sha3",
39+
"manual",
40+
"noclippy",
41+
"norustfmt",
42+
],
43+
version = "0.10.8",
44+
deps = [
45+
"@crates_vendor__digest-0.10.7//:digest",
46+
"@crates_vendor__keccak-0.1.6//:keccak",
47+
],
48+
)

deps/rust/crates/defs.bzl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ _NORMAL_DEPENDENCIES = {
319319
"scratch": Label("@crates_vendor//:scratch-1.0.9"),
320320
"serde": Label("@crates_vendor//:serde-1.0.228"),
321321
"serde_json": Label("@crates_vendor//:serde_json-1.0.149"),
322+
"sha3": Label("@crates_vendor//:sha3-0.10.8"),
322323
"static_assertions": Label("@crates_vendor//:static_assertions-1.1.0"),
323324
"swc_common": Label("@crates_vendor//:swc_common-18.0.1"),
324325
"swc_ts_fast_strip": Label("@crates_vendor//:swc_ts_fast_strip-43.0.0"),
@@ -410,6 +411,7 @@ _CONDITIONS = {
410411
"cfg(any(unix, target_os = \"wasi\"))": ["@rules_rust//rust/platform:aarch64-apple-darwin", "@rules_rust//rust/platform:aarch64-unknown-linux-gnu", "@rules_rust//rust/platform:x86_64-apple-darwin", "@rules_rust//rust/platform:x86_64-unknown-linux-gnu"],
411412
"cfg(not(all(target_arch = \"arm\", target_os = \"none\")))": ["@rules_rust//rust/platform:aarch64-apple-darwin", "@rules_rust//rust/platform:aarch64-unknown-linux-gnu", "@rules_rust//rust/platform:x86_64-apple-darwin", "@rules_rust//rust/platform:x86_64-pc-windows-msvc", "@rules_rust//rust/platform:x86_64-unknown-linux-gnu"],
412413
"cfg(not(windows))": ["@rules_rust//rust/platform:aarch64-apple-darwin", "@rules_rust//rust/platform:aarch64-unknown-linux-gnu", "@rules_rust//rust/platform:x86_64-apple-darwin", "@rules_rust//rust/platform:x86_64-unknown-linux-gnu"],
414+
"cfg(target_arch = \"aarch64\")": ["@rules_rust//rust/platform:aarch64-apple-darwin", "@rules_rust//rust/platform:aarch64-unknown-linux-gnu"],
413415
"cfg(target_os = \"hermit\")": [],
414416
"cfg(target_os = \"netbsd\")": [],
415417
"cfg(target_os = \"solaris\")": [],
@@ -1390,6 +1392,16 @@ def crate_repositories():
13901392
build_file = Label("//deps/rust/crates:BUILD.js-sys-0.3.91.bazel"),
13911393
)
13921394

1395+
maybe(
1396+
http_archive,
1397+
name = "crates_vendor__keccak-0.1.6",
1398+
sha256 = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653",
1399+
type = "tar.gz",
1400+
urls = ["https://static.crates.io/crates/keccak/0.1.6/download"],
1401+
strip_prefix = "keccak-0.1.6",
1402+
build_file = Label("//deps/rust/crates:BUILD.keccak-0.1.6.bazel"),
1403+
)
1404+
13931405
maybe(
13941406
http_archive,
13951407
name = "crates_vendor__libc-0.2.183",
@@ -2039,6 +2051,16 @@ def crate_repositories():
20392051
build_file = Label("//deps/rust/crates:BUILD.sha1-0.10.6.bazel"),
20402052
)
20412053

2054+
maybe(
2055+
http_archive,
2056+
name = "crates_vendor__sha3-0.10.8",
2057+
sha256 = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60",
2058+
type = "tar.gz",
2059+
urls = ["https://static.crates.io/crates/sha3/0.10.8/download"],
2060+
strip_prefix = "sha3-0.10.8",
2061+
build_file = Label("//deps/rust/crates:BUILD.sha3-0.10.8.bazel"),
2062+
)
2063+
20422064
maybe(
20432065
http_archive,
20442066
name = "crates_vendor__shlex-1.3.0",
@@ -2855,6 +2877,7 @@ def crate_repositories():
28552877
struct(repo = "crates_vendor__scratch-1.0.9", is_dev_dep = False),
28562878
struct(repo = "crates_vendor__serde-1.0.228", is_dev_dep = False),
28572879
struct(repo = "crates_vendor__serde_json-1.0.149", is_dev_dep = False),
2880+
struct(repo = "crates_vendor__sha3-0.10.8", is_dev_dep = False),
28582881
struct(repo = "crates_vendor__static_assertions-1.1.0", is_dev_dep = False),
28592882
struct(repo = "crates_vendor__swc_common-18.0.1", is_dev_dep = False),
28602883
struct(repo = "crates_vendor__swc_ts_fast_strip-43.0.0", is_dev_dep = False),

src/rust/sha3/BUILD.bazel

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
load("//:build/wd_rust_crate.bzl", "wd_rust_crate")
2+
3+
wd_rust_crate(
4+
name = "sha3",
5+
cxx_bridge_src = "lib.rs",
6+
visibility = ["//visibility:public"],
7+
deps = [
8+
"@crates_vendor//:sha3",
9+
],
10+
)

src/rust/sha3/lib.rs

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//! SHA-3, TurboSHAKE, and cSHAKE digest functions via the `sha3` crate (RustCrypto).
2+
//!
3+
//! BoringSSL does not expose SHA-3 through the EVP_MD interface, so we use
4+
//! a pure-Rust implementation and expose it to C++ via CXX bridge.
5+
6+
use sha3::Digest;
7+
use sha3::digest::ExtendableOutput;
8+
use sha3::digest::Update;
9+
use sha3::digest::XofReader;
10+
use sha3::digest::core_api::CoreWrapper;
11+
12+
#[cxx::bridge(namespace = "workerd::rust::sha3")]
13+
mod ffi {
14+
extern "Rust" {
15+
fn sha3_256(data: &[u8]) -> Vec<u8>;
16+
fn sha3_384(data: &[u8]) -> Vec<u8>;
17+
fn sha3_512(data: &[u8]) -> Vec<u8>;
18+
fn turboshake128(data: &[u8], output_len: usize, domain_separation: u8) -> Vec<u8>;
19+
fn turboshake256(data: &[u8], output_len: usize, domain_separation: u8) -> Vec<u8>;
20+
fn cshake128(
21+
data: &[u8],
22+
output_len: usize,
23+
function_name: &[u8],
24+
customization: &[u8],
25+
) -> Vec<u8>;
26+
fn cshake256(
27+
data: &[u8],
28+
output_len: usize,
29+
function_name: &[u8],
30+
customization: &[u8],
31+
) -> Vec<u8>;
32+
}
33+
}
34+
35+
#[must_use]
36+
pub fn sha3_256(data: &[u8]) -> Vec<u8> {
37+
sha3::Sha3_256::digest(data).to_vec()
38+
}
39+
40+
#[must_use]
41+
pub fn sha3_384(data: &[u8]) -> Vec<u8> {
42+
sha3::Sha3_384::digest(data).to_vec()
43+
}
44+
45+
#[must_use]
46+
pub fn sha3_512(data: &[u8]) -> Vec<u8> {
47+
sha3::Sha3_512::digest(data).to_vec()
48+
}
49+
50+
#[must_use]
51+
pub fn turboshake128(data: &[u8], output_len: usize, domain_separation: u8) -> Vec<u8> {
52+
debug_assert!((0x01..=0x7F).contains(&domain_separation));
53+
let mut hasher = CoreWrapper::from_core(sha3::TurboShake128Core::new(domain_separation));
54+
hasher.update(data);
55+
let mut reader = hasher.finalize_xof();
56+
let mut output = vec![0u8; output_len];
57+
reader.read(&mut output);
58+
output
59+
}
60+
61+
#[must_use]
62+
pub fn turboshake256(data: &[u8], output_len: usize, domain_separation: u8) -> Vec<u8> {
63+
debug_assert!((0x01..=0x7F).contains(&domain_separation));
64+
let mut hasher = CoreWrapper::from_core(sha3::TurboShake256Core::new(domain_separation));
65+
hasher.update(data);
66+
let mut reader = hasher.finalize_xof();
67+
let mut output = vec![0u8; output_len];
68+
reader.read(&mut output);
69+
output
70+
}
71+
72+
#[must_use]
73+
pub fn cshake128(
74+
data: &[u8],
75+
output_len: usize,
76+
function_name: &[u8],
77+
customization: &[u8],
78+
) -> Vec<u8> {
79+
let mut hasher = CoreWrapper::from_core(sha3::CShake128Core::new_with_function_name(
80+
function_name,
81+
customization,
82+
));
83+
hasher.update(data);
84+
let mut reader = hasher.finalize_xof();
85+
let mut output = vec![0u8; output_len];
86+
reader.read(&mut output);
87+
output
88+
}
89+
90+
#[must_use]
91+
pub fn cshake256(
92+
data: &[u8],
93+
output_len: usize,
94+
function_name: &[u8],
95+
customization: &[u8],
96+
) -> Vec<u8> {
97+
let mut hasher = CoreWrapper::from_core(sha3::CShake256Core::new_with_function_name(
98+
function_name,
99+
customization,
100+
));
101+
hasher.update(data);
102+
let mut reader = hasher.finalize_xof();
103+
let mut output = vec![0u8; output_len];
104+
reader.read(&mut output);
105+
output
106+
}

0 commit comments

Comments
 (0)