A hashname is a unique fingerprint to represent the union of one or more public keys of different formats (Cipher Sets), providing consistent verifiable endpoint addresses when utilizing multiple different public-key algorithms. This enables a compatibility layer for improving the algorithms used so that any application can increase security in newer versions while still being able to represent itself securely to older ones.
A hashname can be viewed as a portable, secure, virtual equivalent of a MAC address, since it is a universally unique identifier for a network endpoint that is also self-generated and cryptographically verifiable.
The value is always a base 32 encoded string that is 52 characters long. When decoded it is always a 32 byte binary value, which corresponds to the result of a SHA-256 hash digest. An example hashname is kw3akwcypoedvfdquuppofpujbu7rplhj3vjvmvbkvf7z3do7kkq
.
A hashname is calculated by combining one or more Cipher Set Keys (CSK) through multiple rounds of SHA-256 hashing.
The generation has three distinct steps, all of them operating on binary/byte inputs and outputs:
- Every
CSK
is identified by a single uniqueCSID
and sorted by it from low to high (e.g.CS1a
is lower thenCS3a
) - Each
CSK
is hashed into intermediate digest values - Roll-up hashing of the
CSIDs
and intermediate values generates the final 32-byte digest
Any hashname generation software does not need to know or understand the Cipher Sets or support the algorithms defined there, it only has to do the consistent hashing of any given set of CSID
and CSK
pair inputs.
The intermediate digest values may be used and exchanged directly instead of the original CSK
to minimize the amount of data required to calculate and verify a hashname with multiple keys.
To calculate the hashname the intermediate digests are sequentially hashed in ascending order by their CSID
. Each one contributes two values: the single byte CSID
value and the 32 byte intermediate digest value. The calculated hash is rolled up, wherein each resulting 32 byte binary output is concatenated with the next binary value as the input. An example calculation would look like (in pseudo-code):
hash = sha256(0x1a)
hash = sha256(hash + 0x21b6...f350)
hash = sha256(hash + 0x3a)
hash = sha256(hash + 0x97d8...7101)
final = hash