1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#!/usr/bin/env -S uv run --script
#
# /// script
# requires-python = ">=3.14"
# dependencies = [
# "blake3>=1.0.9",
# ]
# ///
# The output of this script is checked in as "test_vectors.json" in this
# directory: `./generate.py > test_vectors.json`. If you change this script,
# rerun that. We test for mismatches in CI.
=
= |
# Some interfaces, like `dirhash_path`, can handle both filepaths and directory
# paths. Other interfaces, like `DirhashTree`, expect to represent a directory.
# Most archive formats work similarly, where the assumption is that their root
# is a directory and not the recursive base case of "just the bytes of a
# nameless file". (Apparently the NAR format from Nix is a rare exception, but
# certainly Tar and Zip work this way.) To avoid overcomplicating the tests
# that read this list of vectors, don't include any cases that are "just the
# bytes of a nameless file". The dirhash of a file is its ordinary BLAKE3 hash,
# so there's not a lot of dirhash-specific code that needs testing in these
# cases anyway.
: =
# The dirhash of a file is the regular BLAKE3 hash of its bytes.
return
# The dirhash of a directory is the `blake3::derive_key` of its sorted
# items, with the context string "directory". The name of each item is
# encoded in UTF-8 with a 0xff terminator, and the value of each item is
# its 32-byte dirhash (recursive).
assert
=
=
# Recurse!
return
=