git-remote-ops 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +177 -0
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/esm/_dnt.shims.js +72 -0
- package/esm/cli.js +217 -0
- package/esm/client.js +439 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_errors.js +133 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_spread.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.js +1 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/_utils.js +141 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/command.js +1861 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.js +357 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/mod.js +13 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/type.js +27 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.js +16 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.js +13 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.js +14 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/command.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/enum.js +24 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/file.js +12 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/integer.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/number.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/secret.js +7 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types/string.js +9 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/types.js +2 -0
- package/esm/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.js +26 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_errors.js +129 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_utils.js +100 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.js +166 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/flags.js +750 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/mod.js +55 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.js +11 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.js +9 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/number.js +11 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types/string.js +4 -0
- package/esm/deps/jsr.io/@cliffy/flags/1.1.0/types.js +1 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.js +16 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.js +11 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.js +25 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.js +18 -0
- package/esm/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.js +11 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_layout.js +616 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/_utils.js +79 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/border.js +18 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/cell.js +190 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/column.js +117 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/consume_words.js +64 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/mod.js +42 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/row.js +82 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/table.js +341 -0
- package/esm/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.js +101 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_types.js +2 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.js +237 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.js +2277 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.js +46 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.js +132 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/crypto.js +270 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/mod.js +23 -0
- package/esm/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.js +61 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common16.js +51 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_common_detach.js +13 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/_types.js +2 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.10/hex.js +87 -0
- package/esm/deps/jsr.io/@std/fmt/1.0.10/colors.js +903 -0
- package/esm/deps/jsr.io/@std/text/1.0.18/closest_string.js +46 -0
- package/esm/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.js +127 -0
- package/esm/errors.js +38 -0
- package/esm/index.js +10 -0
- package/esm/logger.js +216 -0
- package/esm/objects/commit.js +47 -0
- package/esm/objects/index.js +2 -0
- package/esm/objects/tree.js +149 -0
- package/esm/pack/delta.js +179 -0
- package/esm/pack/index.js +3 -0
- package/esm/pack/objects.js +72 -0
- package/esm/pack/parser.js +304 -0
- package/esm/package.json +3 -0
- package/esm/protocol/index.js +3 -0
- package/esm/protocol/pkt_line.js +103 -0
- package/esm/protocol/refs.js +100 -0
- package/esm/protocol/upload_pack.js +259 -0
- package/esm/transport.js +128 -0
- package/esm/types.js +8 -0
- package/package.json +50 -0
- package/types/_dnt.shims.d.ts +16 -0
- package/types/_dnt.shims.d.ts.map +1 -0
- package/types/cli.d.ts +3 -0
- package/types/cli.d.ts.map +1 -0
- package/types/client.d.ts +108 -0
- package/types/client.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts +163 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_argument_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts +71 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_errors.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts +16 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_spread.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts +15 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_type_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts +38 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts +1086 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts +33 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/help/_help_generator.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts +78 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts +51 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/type.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/action_list.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/boolean.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts +10 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/child_command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/command.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts +11 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/enum.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts +6 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/file.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/integer.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/number.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts +6 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/secret.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types/string.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts +161 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/command/1.1.0/upgrade/_check_version.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts +67 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_errors.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts +17 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts +11 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/_validate_flags.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts +154 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/flags.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts +57 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/boolean.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/integer.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/number.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts +4 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types/string.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts +170 -0
- package/types/deps/jsr.io/@cliffy/flags/1.1.0/types.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/exit.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_args.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_columns.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts +8 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/get_env.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts +7 -0
- package/types/deps/jsr.io/@cliffy/internal/1.1.0/runtime/inspect.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts +108 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_layout.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts +26 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/_utils.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts +21 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/border.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts +155 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/cell.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts +97 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/column.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts +30 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/consume_words.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts +43 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts +67 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/row.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts +235 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/table.d.ts.map +1 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts +40 -0
- package/types/deps/jsr.io/@cliffy/table/1.1.0/unicode_width.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts +9 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts +2 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts +69 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/lib/deno_std_wasm_crypto.internal.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts +13 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/_wasm/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts +76 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/aes_gcm.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts +149 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/crypto.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts +22 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/mod.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts +40 -0
- package/types/deps/jsr.io/@std/crypto/1.1.0/timing_safe_equal.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts +23 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common16.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts +4 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_common_detach.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts +9 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/_types.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts +39 -0
- package/types/deps/jsr.io/@std/encoding/1.0.10/hex.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts +700 -0
- package/types/deps/jsr.io/@std/fmt/1.0.10/colors.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts +42 -0
- package/types/deps/jsr.io/@std/text/1.0.18/closest_string.d.ts.map +1 -0
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts +23 -0
- package/types/deps/jsr.io/@std/text/1.0.18/levenshtein_distance.d.ts.map +1 -0
- package/types/errors.d.ts +73 -0
- package/types/errors.d.ts.map +1 -0
- package/types/index.d.ts +14 -0
- package/types/index.d.ts.map +1 -0
- package/types/logger.d.ts +70 -0
- package/types/logger.d.ts.map +1 -0
- package/types/objects/commit.d.ts +23 -0
- package/types/objects/commit.d.ts.map +1 -0
- package/types/objects/index.d.ts +3 -0
- package/types/objects/index.d.ts.map +1 -0
- package/types/objects/tree.d.ts +49 -0
- package/types/objects/tree.d.ts.map +1 -0
- package/types/pack/delta.d.ts +47 -0
- package/types/pack/delta.d.ts.map +1 -0
- package/types/pack/index.d.ts +4 -0
- package/types/pack/index.d.ts.map +1 -0
- package/types/pack/objects.d.ts +53 -0
- package/types/pack/objects.d.ts.map +1 -0
- package/types/pack/parser.d.ts +61 -0
- package/types/pack/parser.d.ts.map +1 -0
- package/types/protocol/index.d.ts +4 -0
- package/types/protocol/index.d.ts.map +1 -0
- package/types/protocol/pkt_line.d.ts +44 -0
- package/types/protocol/pkt_line.d.ts.map +1 -0
- package/types/protocol/refs.d.ts +40 -0
- package/types/protocol/refs.d.ts.map +1 -0
- package/types/protocol/upload_pack.d.ts +45 -0
- package/types/protocol/upload_pack.d.ts.map +1 -0
- package/types/transport.d.ts +24 -0
- package/types/transport.d.ts.map +1 -0
- package/types/types.d.ts +121 -0
- package/types/types.d.ts.map +1 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
export { digest, DigestContext } from "./lib/deno_std_wasm_crypto.js";
|
|
3
|
+
/**
|
|
4
|
+
* All cryptographic hash/digest algorithms supported by std/crypto.
|
|
5
|
+
*
|
|
6
|
+
* For algorithms that are supported by WebCrypto, the name here will match the
|
|
7
|
+
* one used by WebCrypto. Otherwise we prefer the formatting used in the
|
|
8
|
+
* algorithm's official specification. All names are uppercase to facilitate
|
|
9
|
+
* case-insensitive comparisons required by the WebCrypto spec.
|
|
10
|
+
*/
|
|
11
|
+
export const DIGEST_ALGORITHM_NAMES = [
|
|
12
|
+
"BLAKE2B",
|
|
13
|
+
"BLAKE2B-128",
|
|
14
|
+
"BLAKE2B-160",
|
|
15
|
+
"BLAKE2B-224",
|
|
16
|
+
"BLAKE2B-256",
|
|
17
|
+
"BLAKE2B-384",
|
|
18
|
+
"BLAKE2S",
|
|
19
|
+
"BLAKE3",
|
|
20
|
+
"KECCAK-224",
|
|
21
|
+
"KECCAK-256",
|
|
22
|
+
"KECCAK-384",
|
|
23
|
+
"KECCAK-512",
|
|
24
|
+
"SHA-384",
|
|
25
|
+
"SHA3-224",
|
|
26
|
+
"SHA3-256",
|
|
27
|
+
"SHA3-384",
|
|
28
|
+
"SHA3-512",
|
|
29
|
+
"SHAKE128",
|
|
30
|
+
"SHAKE256",
|
|
31
|
+
"TIGER",
|
|
32
|
+
// insecure (length-extendable):
|
|
33
|
+
"RIPEMD-160",
|
|
34
|
+
"SHA-224",
|
|
35
|
+
"SHA-256",
|
|
36
|
+
"SHA-512",
|
|
37
|
+
// insecure (length-extendable and collidable):
|
|
38
|
+
"MD4",
|
|
39
|
+
"MD5",
|
|
40
|
+
"SHA-1",
|
|
41
|
+
// insecure (non-cryptographic)
|
|
42
|
+
"FNV32",
|
|
43
|
+
"FNV32A",
|
|
44
|
+
"FNV64",
|
|
45
|
+
"FNV64A",
|
|
46
|
+
];
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import * as dntShim from "../../../../../_dnt.shims.js";
|
|
4
|
+
/**
|
|
5
|
+
* High-level AES-GCM authenticated encryption with automatic nonce generation.
|
|
6
|
+
*
|
|
7
|
+
* With random nonces, do not encrypt more than ~2^32 messages under the same
|
|
8
|
+
* key. Beyond this limit, nonce collision probability becomes non-negligible.
|
|
9
|
+
*
|
|
10
|
+
* @example Usage
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { encryptAesGcm, decryptAesGcm } from "@std/crypto/aes-gcm";
|
|
13
|
+
* import { assertEquals } from "@std/assert";
|
|
14
|
+
*
|
|
15
|
+
* const key = await crypto.subtle.generateKey(
|
|
16
|
+
* { name: "AES-GCM", length: 256 },
|
|
17
|
+
* false,
|
|
18
|
+
* ["encrypt", "decrypt"],
|
|
19
|
+
* );
|
|
20
|
+
*
|
|
21
|
+
* const plaintext = new TextEncoder().encode("hello world");
|
|
22
|
+
* const encrypted = await encryptAesGcm(key, plaintext);
|
|
23
|
+
* const decrypted = await decryptAesGcm(key, encrypted);
|
|
24
|
+
*
|
|
25
|
+
* assertEquals(decrypted, plaintext);
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
const NONCE_LENGTH = 12;
|
|
31
|
+
const TAG_LENGTH = 16;
|
|
32
|
+
const OVERHEAD = NONCE_LENGTH + TAG_LENGTH;
|
|
33
|
+
/**
|
|
34
|
+
* Encrypts plaintext using AES-GCM with a random 96-bit nonce.
|
|
35
|
+
*
|
|
36
|
+
* Returns `nonce (12 bytes) || ciphertext || tag (16 bytes)`.
|
|
37
|
+
*
|
|
38
|
+
* @example Usage
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { encryptAesGcm } from "@std/crypto/aes-gcm";
|
|
41
|
+
* import { assertNotEquals } from "@std/assert";
|
|
42
|
+
*
|
|
43
|
+
* const key = await crypto.subtle.generateKey(
|
|
44
|
+
* { name: "AES-GCM", length: 256 },
|
|
45
|
+
* false,
|
|
46
|
+
* ["encrypt", "decrypt"],
|
|
47
|
+
* );
|
|
48
|
+
*
|
|
49
|
+
* const encrypted = await encryptAesGcm(
|
|
50
|
+
* key,
|
|
51
|
+
* new TextEncoder().encode("hello world"),
|
|
52
|
+
* );
|
|
53
|
+
*
|
|
54
|
+
* assertNotEquals(encrypted.length, 0);
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @param key The AES-GCM `CryptoKey` to encrypt with.
|
|
58
|
+
* @param plaintext The data to encrypt.
|
|
59
|
+
* @param options Optional additional authenticated data.
|
|
60
|
+
* @returns The concatenated nonce, ciphertext, and authentication tag.
|
|
61
|
+
*
|
|
62
|
+
* @remarks With random nonces, do not encrypt more than ~2^32 messages
|
|
63
|
+
* under the same key. Beyond this limit, nonce collision probability
|
|
64
|
+
* becomes non-negligible.
|
|
65
|
+
*
|
|
66
|
+
* @see {@link https://csrc.nist.gov/pubs/sp/800/38/d/final | NIST SP 800-38D} Section 8.3
|
|
67
|
+
*/
|
|
68
|
+
export async function encryptAesGcm(key, plaintext, options) {
|
|
69
|
+
const nonce = dntShim.crypto.getRandomValues(new Uint8Array(NONCE_LENGTH));
|
|
70
|
+
const params = {
|
|
71
|
+
name: "AES-GCM",
|
|
72
|
+
iv: nonce,
|
|
73
|
+
tagLength: TAG_LENGTH * 8,
|
|
74
|
+
};
|
|
75
|
+
if (options?.additionalData !== undefined) {
|
|
76
|
+
params.additionalData = options.additionalData;
|
|
77
|
+
}
|
|
78
|
+
const ciphertextAndTag = new Uint8Array(await dntShim.crypto.subtle.encrypt(params, key, plaintext));
|
|
79
|
+
const result = new Uint8Array(NONCE_LENGTH + ciphertextAndTag.byteLength);
|
|
80
|
+
result.set(nonce);
|
|
81
|
+
result.set(ciphertextAndTag, NONCE_LENGTH);
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Decrypts data produced by {@linkcode encryptAesGcm}.
|
|
86
|
+
*
|
|
87
|
+
* Expects input in the format `nonce (12 bytes) || ciphertext || tag (16 bytes)`.
|
|
88
|
+
*
|
|
89
|
+
* @example Usage
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { decryptAesGcm, encryptAesGcm } from "@std/crypto/aes-gcm";
|
|
92
|
+
* import { assertEquals } from "@std/assert";
|
|
93
|
+
*
|
|
94
|
+
* const key = await crypto.subtle.generateKey(
|
|
95
|
+
* { name: "AES-GCM", length: 256 },
|
|
96
|
+
* false,
|
|
97
|
+
* ["encrypt", "decrypt"],
|
|
98
|
+
* );
|
|
99
|
+
*
|
|
100
|
+
* const plaintext = new TextEncoder().encode("hello world");
|
|
101
|
+
* const encrypted = await encryptAesGcm(key, plaintext);
|
|
102
|
+
*
|
|
103
|
+
* assertEquals(await decryptAesGcm(key, encrypted), plaintext);
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @param key The AES-GCM `CryptoKey` to decrypt with.
|
|
107
|
+
* @param data The wire-format output from {@linkcode encryptAesGcm}: nonce (12 B) || ciphertext || tag (16 B).
|
|
108
|
+
* @param options Optional additional authenticated data (must match what was used during encryption).
|
|
109
|
+
* @returns The decrypted plaintext.
|
|
110
|
+
* @throws {RangeError} If `data` is shorter than 28 bytes (12 nonce + 16 tag).
|
|
111
|
+
* @throws {DOMException} If authentication fails (wrong key, tampered data, or
|
|
112
|
+
* mismatched additional data).
|
|
113
|
+
*/
|
|
114
|
+
export async function decryptAesGcm(key, data, options) {
|
|
115
|
+
const bytes = ArrayBuffer.isView(data)
|
|
116
|
+
? new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
|
|
117
|
+
: new Uint8Array(data);
|
|
118
|
+
if (bytes.byteLength < OVERHEAD) {
|
|
119
|
+
throw new RangeError(`Data is too short: expected at least ${OVERHEAD} bytes, got ${bytes.byteLength}`);
|
|
120
|
+
}
|
|
121
|
+
const nonce = bytes.subarray(0, NONCE_LENGTH);
|
|
122
|
+
const ciphertextAndTag = bytes.subarray(NONCE_LENGTH);
|
|
123
|
+
const params = {
|
|
124
|
+
name: "AES-GCM",
|
|
125
|
+
iv: nonce,
|
|
126
|
+
tagLength: TAG_LENGTH * 8,
|
|
127
|
+
};
|
|
128
|
+
if (options?.additionalData !== undefined) {
|
|
129
|
+
params.additionalData = options.additionalData;
|
|
130
|
+
}
|
|
131
|
+
return new Uint8Array(await dntShim.crypto.subtle.decrypt(params, key, ciphertextAndTag));
|
|
132
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
/**
|
|
4
|
+
* Extensions to the
|
|
5
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API | Web Crypto API}
|
|
6
|
+
* supporting additional encryption APIs, but also delegating to the built-in
|
|
7
|
+
* APIs when possible.
|
|
8
|
+
*
|
|
9
|
+
* Provides additional digest algorithms that are not part of the WebCrypto
|
|
10
|
+
* standard as well as a `subtle.digest` and `subtle.digestSync` methods.
|
|
11
|
+
*
|
|
12
|
+
* The {@linkcode KeyStack} export implements the {@linkcode KeyRing} interface
|
|
13
|
+
* for managing rotatable keys for signing data to prevent tampering, like with
|
|
14
|
+
* HTTP cookies.
|
|
15
|
+
*
|
|
16
|
+
* ## Supported algorithms
|
|
17
|
+
*
|
|
18
|
+
* Here is a list of supported algorithms. If the algorithm name in WebCrypto
|
|
19
|
+
* and Wasm/Rust is the same, this library prefers to use the implementation
|
|
20
|
+
* provided by WebCrypto.
|
|
21
|
+
*
|
|
22
|
+
* Length-adjustable algorithms support the
|
|
23
|
+
* {@linkcode DigestAlgorithmObject.length} option.
|
|
24
|
+
*
|
|
25
|
+
* WebCrypto:
|
|
26
|
+
* - `SHA-384`
|
|
27
|
+
* - `SHA-256` (length-extendable)
|
|
28
|
+
* - `SHA-512` (length-extendable)
|
|
29
|
+
*
|
|
30
|
+
* Wasm/Rust:
|
|
31
|
+
* - `BLAKE2B`
|
|
32
|
+
* - `BLAKE2B-128`
|
|
33
|
+
* - `BLAKE2B-160`
|
|
34
|
+
* - `BLAKE2B-224`
|
|
35
|
+
* - `BLAKE2B-256`
|
|
36
|
+
* - `BLAKE2B-384`
|
|
37
|
+
* - `BLAKE2S`
|
|
38
|
+
* - `BLAKE3` (length-adjustable)
|
|
39
|
+
* - `KECCAK-224`
|
|
40
|
+
* - `KECCAK-256`
|
|
41
|
+
* - `KECCAK-384`
|
|
42
|
+
* - `KECCAK-512`
|
|
43
|
+
* - `SHA-384`
|
|
44
|
+
* - `SHA3-224`
|
|
45
|
+
* - `SHA3-256`
|
|
46
|
+
* - `SHA3-384`
|
|
47
|
+
* - `SHA3-512`
|
|
48
|
+
* - `SHAKE128` (length-adjustable)
|
|
49
|
+
* - `SHAKE256` (length-adjustable)
|
|
50
|
+
* - `TIGER`
|
|
51
|
+
* - `RIPEMD-160` (length-extendable)
|
|
52
|
+
* - `SHA-224` (length-extendable)
|
|
53
|
+
* - `SHA-256` (length-extendable)
|
|
54
|
+
* - `SHA-512` (length-extendable)
|
|
55
|
+
* - `MD4` (length-extendable and collidable)
|
|
56
|
+
* - `MD5` (length-extendable and collidable)
|
|
57
|
+
* - `SHA-1` (length-extendable and collidable)
|
|
58
|
+
* - `FNV32` (non-cryptographic)
|
|
59
|
+
* - `FNV32A` (non-cryptographic)
|
|
60
|
+
* - `FNV64` (non-cryptographic)
|
|
61
|
+
* - `FNV64A` (non-cryptographic)
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { crypto } from "@std/crypto";
|
|
66
|
+
*
|
|
67
|
+
* // This will delegate to the runtime's WebCrypto implementation.
|
|
68
|
+
* console.log(
|
|
69
|
+
* new Uint8Array(
|
|
70
|
+
* await crypto.subtle.digest(
|
|
71
|
+
* "SHA-384",
|
|
72
|
+
* new TextEncoder().encode("hello world"),
|
|
73
|
+
* ),
|
|
74
|
+
* ),
|
|
75
|
+
* );
|
|
76
|
+
*
|
|
77
|
+
* // This will use a bundled Wasm/Rust implementation.
|
|
78
|
+
* console.log(
|
|
79
|
+
* new Uint8Array(
|
|
80
|
+
* await crypto.subtle.digest(
|
|
81
|
+
* "BLAKE3",
|
|
82
|
+
* new TextEncoder().encode("hello world"),
|
|
83
|
+
* ),
|
|
84
|
+
* ),
|
|
85
|
+
* );
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example Convert hash to a string
|
|
89
|
+
*
|
|
90
|
+
* ```ts
|
|
91
|
+
* import {
|
|
92
|
+
* crypto,
|
|
93
|
+
* } from "@std/crypto";
|
|
94
|
+
* import { encodeHex } from "@std/encoding/hex"
|
|
95
|
+
* import { encodeBase64 } from "@std/encoding/base64"
|
|
96
|
+
*
|
|
97
|
+
* const hash = await crypto.subtle.digest(
|
|
98
|
+
* "SHA-384",
|
|
99
|
+
* new TextEncoder().encode("You hear that Mr. Anderson?"),
|
|
100
|
+
* );
|
|
101
|
+
*
|
|
102
|
+
* // Hex encoding
|
|
103
|
+
* console.log(encodeHex(hash));
|
|
104
|
+
*
|
|
105
|
+
* // Or with base64 encoding
|
|
106
|
+
* console.log(encodeBase64(hash));
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @module
|
|
110
|
+
*/
|
|
111
|
+
import * as dntShim from "../../../../../_dnt.shims.js";
|
|
112
|
+
import { digest, DIGEST_ALGORITHM_NAMES, DigestContext, } from "./_wasm/mod.js";
|
|
113
|
+
export { DIGEST_ALGORITHM_NAMES };
|
|
114
|
+
/** Digest algorithms supported by WebCrypto. */
|
|
115
|
+
const WEB_CRYPTO_DIGEST_ALGORITHM_NAMES = [
|
|
116
|
+
"SHA-384",
|
|
117
|
+
"SHA-256",
|
|
118
|
+
"SHA-512",
|
|
119
|
+
// insecure (length-extendable and collidable):
|
|
120
|
+
"SHA-1",
|
|
121
|
+
];
|
|
122
|
+
/**
|
|
123
|
+
* A copy of the global WebCrypto interface, with methods bound so they're
|
|
124
|
+
* safe to re-export.
|
|
125
|
+
*/
|
|
126
|
+
const webCrypto = ((crypto) => ({
|
|
127
|
+
getRandomValues: crypto.getRandomValues?.bind(crypto),
|
|
128
|
+
randomUUID: crypto.randomUUID?.bind(crypto),
|
|
129
|
+
subtle: {
|
|
130
|
+
decrypt: crypto.subtle?.decrypt?.bind(crypto.subtle),
|
|
131
|
+
deriveBits: crypto.subtle?.deriveBits?.bind(crypto.subtle),
|
|
132
|
+
deriveKey: crypto.subtle?.deriveKey?.bind(crypto.subtle),
|
|
133
|
+
digest: crypto.subtle?.digest?.bind(crypto.subtle),
|
|
134
|
+
encrypt: crypto.subtle?.encrypt?.bind(crypto.subtle),
|
|
135
|
+
exportKey: crypto.subtle?.exportKey?.bind(crypto.subtle),
|
|
136
|
+
generateKey: crypto.subtle?.generateKey?.bind(crypto.subtle),
|
|
137
|
+
importKey: crypto.subtle?.importKey?.bind(crypto.subtle),
|
|
138
|
+
sign: crypto.subtle?.sign?.bind(crypto.subtle),
|
|
139
|
+
unwrapKey: crypto.subtle?.unwrapKey?.bind(crypto.subtle),
|
|
140
|
+
verify: crypto.subtle?.verify?.bind(crypto.subtle),
|
|
141
|
+
wrapKey: crypto.subtle?.wrapKey?.bind(crypto.subtle),
|
|
142
|
+
},
|
|
143
|
+
}))(dntShim.dntGlobalThis.crypto);
|
|
144
|
+
function toUint8Array(data) {
|
|
145
|
+
if (data instanceof Uint8Array) {
|
|
146
|
+
return data;
|
|
147
|
+
}
|
|
148
|
+
else if (ArrayBuffer.isView(data)) {
|
|
149
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
150
|
+
}
|
|
151
|
+
else if (data instanceof ArrayBuffer) {
|
|
152
|
+
return new Uint8Array(data);
|
|
153
|
+
}
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* A wrapper for WebCrypto which adds support for additional non-standard
|
|
158
|
+
* algorithms, but delegates to the runtime WebCrypto implementation whenever
|
|
159
|
+
* possible.
|
|
160
|
+
*/
|
|
161
|
+
const stdCrypto = ((x) => x)({
|
|
162
|
+
...webCrypto,
|
|
163
|
+
subtle: {
|
|
164
|
+
...webCrypto.subtle,
|
|
165
|
+
/**
|
|
166
|
+
* Polyfills stream support until the Web Crypto API does so:
|
|
167
|
+
* @see {@link https://github.com/wintercg/proposal-webcrypto-streams}
|
|
168
|
+
*/
|
|
169
|
+
async digest(algorithm, data) {
|
|
170
|
+
const { name, length } = normalizeAlgorithm(algorithm);
|
|
171
|
+
assertValidDigestLength(length);
|
|
172
|
+
// We delegate to WebCrypto whenever possible,
|
|
173
|
+
if (
|
|
174
|
+
// if the algorithm is supported by the WebCrypto standard,
|
|
175
|
+
WEB_CRYPTO_DIGEST_ALGORITHM_NAMES.includes(name) &&
|
|
176
|
+
// and the data is a single buffer,
|
|
177
|
+
isBufferSource(data)) {
|
|
178
|
+
return await webCrypto.subtle.digest(algorithm, data);
|
|
179
|
+
}
|
|
180
|
+
else if (DIGEST_ALGORITHM_NAMES.includes(name)) {
|
|
181
|
+
if (isBufferSource(data)) {
|
|
182
|
+
// Otherwise, we use our bundled Wasm implementation via digestSync
|
|
183
|
+
// if it supports the algorithm.
|
|
184
|
+
return stdCrypto.subtle.digestSync(algorithm, data);
|
|
185
|
+
}
|
|
186
|
+
else if (isIterable(data)) {
|
|
187
|
+
return stdCrypto.subtle.digestSync(algorithm, data);
|
|
188
|
+
}
|
|
189
|
+
else if (isAsyncIterable(data)) {
|
|
190
|
+
const context = new DigestContext(name);
|
|
191
|
+
for await (const chunk of data) {
|
|
192
|
+
const chunkBytes = toUint8Array(chunk);
|
|
193
|
+
if (!chunkBytes) {
|
|
194
|
+
throw new TypeError("Cannot digest the data: A chunk is not ArrayBuffer nor ArrayBufferView");
|
|
195
|
+
}
|
|
196
|
+
context.update(chunkBytes);
|
|
197
|
+
}
|
|
198
|
+
return context.digestAndDrop(length).buffer;
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
throw new TypeError(
|
|
202
|
+
// deno-lint-ignore deno-style-guide/error-message
|
|
203
|
+
"data must be a BufferSource or [Async]Iterable<BufferSource>");
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// (TypeScript type definitions prohibit this case.) If they're trying
|
|
207
|
+
// to call an algorithm we don't recognize, pass it along to WebCrypto
|
|
208
|
+
// in case it's a non-standard algorithm supported by the the runtime
|
|
209
|
+
// they're using.
|
|
210
|
+
return await webCrypto.subtle.digest(algorithm, data);
|
|
211
|
+
},
|
|
212
|
+
digestSync(algorithm, data) {
|
|
213
|
+
const { name, length } = normalizeAlgorithm(algorithm);
|
|
214
|
+
assertValidDigestLength(length);
|
|
215
|
+
if (isBufferSource(data)) {
|
|
216
|
+
const bytes = toUint8Array(data);
|
|
217
|
+
return digest(name, bytes, length).buffer;
|
|
218
|
+
}
|
|
219
|
+
if (isIterable(data)) {
|
|
220
|
+
const context = new DigestContext(name);
|
|
221
|
+
for (const chunk of data) {
|
|
222
|
+
const chunkBytes = toUint8Array(chunk);
|
|
223
|
+
if (!chunkBytes) {
|
|
224
|
+
throw new TypeError("Cannot digest the data: A chunk is not ArrayBuffer nor ArrayBufferView");
|
|
225
|
+
}
|
|
226
|
+
context.update(chunkBytes);
|
|
227
|
+
}
|
|
228
|
+
return context.digestAndDrop(length).buffer;
|
|
229
|
+
}
|
|
230
|
+
throw new TypeError(
|
|
231
|
+
// deno-lint-ignore deno-style-guide/error-message
|
|
232
|
+
"data must be a BufferSource or Iterable<BufferSource>");
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
/*
|
|
237
|
+
* The largest digest length the current Wasm implementation can support. This
|
|
238
|
+
* is the value of `isize::MAX` on 32-bit platforms like Wasm, which is the
|
|
239
|
+
* maximum allowed capacity of a Rust `Vec<u8>`.
|
|
240
|
+
*/
|
|
241
|
+
const MAX_DIGEST_LENGTH = 0x7FFF_FFFF;
|
|
242
|
+
/**
|
|
243
|
+
* Asserts that a number is a valid length for a digest, which must be an
|
|
244
|
+
* integer that fits in a Rust `Vec<u8>`, or be undefined.
|
|
245
|
+
*/
|
|
246
|
+
function assertValidDigestLength(value) {
|
|
247
|
+
if (value !== undefined &&
|
|
248
|
+
(value < 0 || value > MAX_DIGEST_LENGTH ||
|
|
249
|
+
!Number.isInteger(value))) {
|
|
250
|
+
throw new RangeError(`length must be an integer between 0 and ${MAX_DIGEST_LENGTH}, inclusive`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function normalizeAlgorithm(algorithm) {
|
|
254
|
+
return ((typeof algorithm === "string")
|
|
255
|
+
? { name: algorithm.toUpperCase() }
|
|
256
|
+
: {
|
|
257
|
+
...algorithm,
|
|
258
|
+
name: algorithm.name.toUpperCase(),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function isBufferSource(obj) {
|
|
262
|
+
return obj instanceof ArrayBuffer || ArrayBuffer.isView(obj);
|
|
263
|
+
}
|
|
264
|
+
function isIterable(obj) {
|
|
265
|
+
return typeof obj[Symbol.iterator] === "function";
|
|
266
|
+
}
|
|
267
|
+
function isAsyncIterable(obj) {
|
|
268
|
+
return typeof obj[Symbol.asyncIterator] === "function";
|
|
269
|
+
}
|
|
270
|
+
export { stdCrypto as crypto };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
/**
|
|
4
|
+
* Extensions to the
|
|
5
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API | Web Crypto}
|
|
6
|
+
* supporting additional encryption APIs, but also delegating to the built-in
|
|
7
|
+
* APIs when possible.
|
|
8
|
+
*
|
|
9
|
+
* ```ts no-assert
|
|
10
|
+
* import { crypto } from "@std/crypto/crypto";
|
|
11
|
+
*
|
|
12
|
+
* const message = "Hello, Deno!";
|
|
13
|
+
* const encoder = new TextEncoder();
|
|
14
|
+
* const data = encoder.encode(message);
|
|
15
|
+
*
|
|
16
|
+
* await crypto.subtle.digest("BLAKE3", data);
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
export * from "./aes_gcm.js";
|
|
22
|
+
export * from "./crypto.js";
|
|
23
|
+
export * from "./timing_safe_equal.js";
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Copyright 2018-2026 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
function toUint8Array(value) {
|
|
4
|
+
if (value instanceof Uint8Array) {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
return ArrayBuffer.isView(value)
|
|
8
|
+
? new Uint8Array(value.buffer, value.byteOffset, value.byteLength)
|
|
9
|
+
: new Uint8Array(value);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* When checking the values of cryptographic hashes are equal, default
|
|
13
|
+
* comparisons can be susceptible to timing based attacks, where attacker is
|
|
14
|
+
* able to find out information about the host system by repeatedly checking
|
|
15
|
+
* response times to equality comparisons of values.
|
|
16
|
+
*
|
|
17
|
+
* It is likely some form of timing safe equality will make its way to the
|
|
18
|
+
* WebCrypto standard (see:
|
|
19
|
+
* {@link https://github.com/w3c/webcrypto/issues/270 | w3c/webcrypto#270}), but until
|
|
20
|
+
* that time, `timingSafeEqual()` is provided.
|
|
21
|
+
*
|
|
22
|
+
* Note: This is a best-effort constant-time comparison implemented in
|
|
23
|
+
* JavaScript. The V8 JIT compiler does not provide formal constant-time
|
|
24
|
+
* guarantees, and inputs backed by `SharedArrayBuffer` are susceptible to
|
|
25
|
+
* concurrent modification during comparison.
|
|
26
|
+
*
|
|
27
|
+
* @example Usage
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { timingSafeEqual } from "@std/crypto/timing-safe-equal";
|
|
30
|
+
* import { assert } from "@std/assert";
|
|
31
|
+
*
|
|
32
|
+
* const a = await crypto.subtle.digest(
|
|
33
|
+
* "SHA-384",
|
|
34
|
+
* new TextEncoder().encode("hello world"),
|
|
35
|
+
* );
|
|
36
|
+
* const b = await crypto.subtle.digest(
|
|
37
|
+
* "SHA-384",
|
|
38
|
+
* new TextEncoder().encode("hello world"),
|
|
39
|
+
* );
|
|
40
|
+
*
|
|
41
|
+
* assert(timingSafeEqual(a, b));
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @param a The first value to compare.
|
|
45
|
+
* @param b The second value to compare.
|
|
46
|
+
* @returns `true` if the values are equal, otherwise `false`.
|
|
47
|
+
* @throws {TypeError} If the byte lengths of the two buffers are not equal.
|
|
48
|
+
*/
|
|
49
|
+
export function timingSafeEqual(a, b) {
|
|
50
|
+
if (a.byteLength !== b.byteLength) {
|
|
51
|
+
throw new TypeError(`Cannot compare buffers of different byte lengths (${a.byteLength} vs ${b.byteLength})`);
|
|
52
|
+
}
|
|
53
|
+
const ua = toUint8Array(a);
|
|
54
|
+
const ub = toUint8Array(b);
|
|
55
|
+
const length = ua.length;
|
|
56
|
+
let out = 0;
|
|
57
|
+
for (let i = 0; i < length; i++) {
|
|
58
|
+
out |= ua[i] ^ ub[i];
|
|
59
|
+
}
|
|
60
|
+
return out === 0;
|
|
61
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
2
|
+
export const alphabet = new TextEncoder().encode("0123456789abcdef");
|
|
3
|
+
export const rAlphabet = new Uint8Array(128).fill(16); // alphabet.Hex.length
|
|
4
|
+
alphabet.forEach((byte, i) => rAlphabet[byte] = i);
|
|
5
|
+
new TextEncoder()
|
|
6
|
+
.encode("ABCDEF")
|
|
7
|
+
.forEach((byte, i) => rAlphabet[byte] = i + 10);
|
|
8
|
+
/**
|
|
9
|
+
* Calculate the output size needed to encode a given input size for
|
|
10
|
+
* {@linkcode encodeIntoHex}.
|
|
11
|
+
*
|
|
12
|
+
* @param originalSize The size of the input buffer.
|
|
13
|
+
* @returns The size of the output buffer.
|
|
14
|
+
*
|
|
15
|
+
* @example Basic Usage
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { assertEquals } from "@std/assert";
|
|
18
|
+
* import { calcSizeHex } from "@std/encoding/unstable-hex";
|
|
19
|
+
*
|
|
20
|
+
* assertEquals(calcSizeHex(1), 2);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function calcSizeHex(originalSize) {
|
|
24
|
+
return originalSize * 2;
|
|
25
|
+
}
|
|
26
|
+
export function encode(buffer, i, o, alphabet) {
|
|
27
|
+
for (; i < buffer.length; ++i) {
|
|
28
|
+
const x = buffer[i];
|
|
29
|
+
buffer[o++] = alphabet[x >> 4];
|
|
30
|
+
buffer[o++] = alphabet[x & 0xF];
|
|
31
|
+
}
|
|
32
|
+
return o;
|
|
33
|
+
}
|
|
34
|
+
export function decode(buffer, i, o, alphabet) {
|
|
35
|
+
if ((buffer.length - o) % 2 === 1) {
|
|
36
|
+
throw new RangeError(`Cannot decode input as hex: Length (${buffer.length - o}) must be divisible by 2`);
|
|
37
|
+
}
|
|
38
|
+
i += 1;
|
|
39
|
+
for (; i < buffer.length; i += 2) {
|
|
40
|
+
buffer[o++] = (getByte(buffer[i - 1], alphabet) << 4) |
|
|
41
|
+
getByte(buffer[i], alphabet);
|
|
42
|
+
}
|
|
43
|
+
return o;
|
|
44
|
+
}
|
|
45
|
+
function getByte(char, alphabet) {
|
|
46
|
+
const byte = alphabet[char] ?? 16;
|
|
47
|
+
if (byte === 16) { // alphabet.Hex.length
|
|
48
|
+
throw new TypeError(`Cannot decode input as hex: Invalid character (${String.fromCharCode(char)})`);
|
|
49
|
+
}
|
|
50
|
+
return byte;
|
|
51
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
2
|
+
export function detach(buffer, maxSize) {
|
|
3
|
+
const originalSize = buffer.length;
|
|
4
|
+
if (buffer.byteOffset) {
|
|
5
|
+
const b = new Uint8Array(buffer.buffer);
|
|
6
|
+
b.set(buffer);
|
|
7
|
+
buffer = b.subarray(0, originalSize);
|
|
8
|
+
}
|
|
9
|
+
// deno-lint-ignore no-explicit-any
|
|
10
|
+
buffer = new Uint8Array(buffer.buffer.transfer(maxSize));
|
|
11
|
+
buffer.set(buffer.subarray(0, originalSize), maxSize - originalSize);
|
|
12
|
+
return [buffer, maxSize - originalSize];
|
|
13
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright 2009 The Go Authors. All rights reserved.
|
|
2
|
+
// https://github.com/golang/go/blob/master/LICENSE
|
|
3
|
+
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
4
|
+
// This module is browser compatible.
|
|
5
|
+
/**
|
|
6
|
+
* Port of the Go
|
|
7
|
+
* {@link https://github.com/golang/go/blob/go1.12.5/src/encoding/hex/hex.go | encoding/hex}
|
|
8
|
+
* library.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import {
|
|
12
|
+
* decodeHex,
|
|
13
|
+
* encodeHex,
|
|
14
|
+
* } from "@std/encoding/hex";
|
|
15
|
+
* import { assertEquals } from "@std/assert";
|
|
16
|
+
*
|
|
17
|
+
* assertEquals(encodeHex("abc"), "616263");
|
|
18
|
+
*
|
|
19
|
+
* assertEquals(
|
|
20
|
+
* decodeHex("616263"),
|
|
21
|
+
* new TextEncoder().encode("abc"),
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import { calcSizeHex, decode, encode } from "./_common16.js";
|
|
28
|
+
import { detach } from "./_common_detach.js";
|
|
29
|
+
const alphabet = new TextEncoder()
|
|
30
|
+
.encode("0123456789abcdef");
|
|
31
|
+
const rAlphabet = new Uint8Array(128).fill(16); // alphabet.length
|
|
32
|
+
alphabet.forEach((byte, i) => rAlphabet[byte] = i);
|
|
33
|
+
new TextEncoder()
|
|
34
|
+
.encode("ABCDEF")
|
|
35
|
+
.forEach((byte, i) => rAlphabet[byte] = i + 10);
|
|
36
|
+
/**
|
|
37
|
+
* Converts data into a hex-encoded string.
|
|
38
|
+
*
|
|
39
|
+
* @param src The data to encode.
|
|
40
|
+
*
|
|
41
|
+
* @returns The hex-encoded string.
|
|
42
|
+
*
|
|
43
|
+
* @example Usage
|
|
44
|
+
* ```ts
|
|
45
|
+
* import { encodeHex } from "@std/encoding/hex";
|
|
46
|
+
* import { assertEquals } from "@std/assert";
|
|
47
|
+
*
|
|
48
|
+
* assertEquals(encodeHex("abc"), "616263");
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function encodeHex(src) {
|
|
52
|
+
if (typeof src === "string") {
|
|
53
|
+
src = new TextEncoder().encode(src);
|
|
54
|
+
}
|
|
55
|
+
else if (src instanceof ArrayBuffer)
|
|
56
|
+
src = new Uint8Array(src).slice();
|
|
57
|
+
else
|
|
58
|
+
src = src.slice();
|
|
59
|
+
const [output, i] = detach(src, calcSizeHex(src.length));
|
|
60
|
+
encode(output, i, 0, alphabet);
|
|
61
|
+
return new TextDecoder().decode(output);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Decodes the given hex-encoded string. If the input is malformed, an error is
|
|
65
|
+
* thrown.
|
|
66
|
+
*
|
|
67
|
+
* @param src The hex-encoded string to decode.
|
|
68
|
+
*
|
|
69
|
+
* @returns The decoded data.
|
|
70
|
+
*
|
|
71
|
+
* @example Usage
|
|
72
|
+
* ```ts
|
|
73
|
+
* import { decodeHex } from "@std/encoding/hex";
|
|
74
|
+
* import { assertEquals } from "@std/assert";
|
|
75
|
+
*
|
|
76
|
+
* assertEquals(
|
|
77
|
+
* decodeHex("616263"),
|
|
78
|
+
* new TextEncoder().encode("abc"),
|
|
79
|
+
* );
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function decodeHex(src) {
|
|
83
|
+
const output = new TextEncoder().encode(src);
|
|
84
|
+
// deno-lint-ignore no-explicit-any
|
|
85
|
+
return new Uint8Array(output.buffer
|
|
86
|
+
.transfer(decode(output, 0, 0, rAlphabet)));
|
|
87
|
+
}
|