All hashes in Pijul are
blake3
which is
a 32-byte hash. The default implementation of blake3 appears to be in Rust, but
there's a [C
implementation](https://github.com/BLAKE3-team/BLAKE3/tree/master/c) in the main
tree which serves our purposes nicely.
A blake3 hash could be represented like this:
$ echo foo | blake3sum | xxd -cols 32 -g 32 | awk '{print $2}'
49dc870df1de7fd60794cebce449f5ccdae575affaa67a24b62acb03e039db92
but instead the Pijul authors have decided to base32-encode the bytes (without
padding).
$ echo foo | blake3sum | base32 | tr -d '='
JHOIODPR3Z75MB4UZ26OISPVZTNOK5NP7KTHUJFWFLFQHYBZ3OJA
An additional feature is that hashed that are base32-encoded include a marker to
indicate the hashing algorithm. At the moment the possible hashes are limited to
two:
enum Hash {
None, // The hash of the "null change"
Blake3([u8; BLAKE3_BYTES]),
}
The "null change" is essentially a "root commit" that kind of bootstraps the
dependency graph. All other changes are hashed with blake3. To distinguish
between the two in change files, the base32 encoding of hashes to the change
file name appends a single byte to indicate the hash variant used. For the null
change this is a zero byte, for blake3 it's a `1u8`. Generating the change file
name ends up something like this:As a
side effect, all change files with blake3 hashes end with the latter `C`.
$ BLAKE3_HASH="\x1"
$ echo -n "$(echo foo | blake3sum)${BLAKE3_HASH}" | base32 | tr -d '='
JHOIODPR3Z75MB4UZ26OISPVZTNOK5NP7KTHUJFWFLFQHYBZ3OJAC