A note on hashes
Posted on
Quick note on hashes in Pijul.
All hashes in Pijul are blake3https://github.com/BLAKE3-team/BLAKE3 which is a 32-byte hash. The default implementation of blake3 appears to be in Rust, but there’s a C implementation 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