Let’s play a quick round of word association. I say “end-to-end.”
Now you say …?

If you’re a cryptographer, I bet you say “encryption.” And with good reason: end-to-end encryption is a basic best practice and fundamental building block of secure communication.

In end-to-end encryption, the sender Alice encrypts a message to Carol, before delivering via a third-party (we’ll call Bob). Encryption gives Alice a cryptographically strong guarantee that Bob can’t decrypt and read the message.

The phrase, “end-to-end encryption,” emphasizes the sender encrypting a message. In practice the sender is likely to both sign and encrypt messages, to prevent both spoofing attacks and evesdropping. Should we instead say “end-to-end cryptography”? Nah. It doesn’t have the same ring to it, even if it is more literally accurate.

Lately, I’ve been thinking about benefits associated with end-to-end encryption, only (…wait for it…) without any encryption.

End-to-End, But Not Encrypted

To explain what I mean, let’s say Alice is sending a file without any concern for keeping the contents secret. But Alice is concerned that the recipients receive the contents unaltered. Perhaps Alice is not simply sending, but distributing it widely, i.e. to anyone in the world.

What Alice wants is that anyone with a copy of the file is able to authenticate it, regardless of how they received it.

Authentication is the process of verifying the truthfulness of a fact claimed true by another entity.

I like the term end-to-end authentication to describe this idea, that anyone with a copy of a file is able to verify it. It has quite a lot in common with end-to-end encryption, and some interesting differences:

End-to-End Encryption End-to-End Authentication
Origin: author author or third-party authority
Cryptography (origin): encryption (and signing) signing
Destination: specific recipient(s) arbitrary recipients
Cryptography (destination): decryption (and verifying) verifying

A Use in Software Development

If you’re developing software, you no doubt rely on some dependencies. Perhaps your product is is a dependency of another.

By dependency, I mean source code or assets included in Alice’s software, but not originally authored by Alice.

Before releasing your product, you should be certain its dependencies behave as expected. Once released, those dependencies are in fact part of your product.

How do you check the integrity of those dependencies? This can get complicated, because dependencies may be fetched via a variety of channels (i.e. your favorite version control tool, or your favorite package manager). Integrity depends on the distribution channel, as well as the original author. You’re trusting their benevolence, that they have not been hacked, that their fundamental design is secure, and even that they have not made some honest mistake.

It would be nice if verifying all dependencies was a simple as:

  1. Opt-in to each of your trusted dependency authors (or code auditors).
  2. Automatically verify all dependencies, at build time.

If you’re thinking, this sounds like a job for “end-to-end authentication,” then I agree!
Not only that, I’ve built a tool with this purpose in mind.


I call this tool hancock. Named after John Hancock. In the U.S., John Hancock is not only a famous name, it is slang meanin anyone’s signtature.

Let’s say Alice is the author of some source code. Carol uses Alice’s package as a dependency. Carol wants to be certain that she has an unaltered copy of the software as published by Alice.

Verifier must determine if local copy is authentic

Carol wants this verification to be automated, so that future builds can include Alice’s updates and bug fixes, but will never include malicious code written by someone attempting to spoof Alice.

Signed Testimony

When producing a release version of her software, Alice uses hancock to produce testimony about source code files. Testimony is a data structure that any verifier can inspect to determine whether a local copy is consistent with an original.

verifier compares copy to signed testimony


With a copy of the source file, Alice’s public key, and Alice’s signed testimony, Carol is able to verify that her copy is unaltered. (Otherwise this automated check stops the build process.)

verifier compares copy to signed testimony

Verifiers configure hancock with the public keys of their trusted authorities. An authority might be the original author, an auditor, or a verifier who self-signs a patched version of a dependency.


Hancock separates authentication from distribution, so that it works with either proprietary or open source dependencies. And it works whether Carol cloned the dependency from BobHub.com, or installed it via Bob Package Manager.

Testimony refers to source code by cryptographic hash, minimizing the information leaked. This allows hancock to treat testimony as public information (even if the authenticated source code is not). Currently, hancock uses IPFS to distribute testimony.

Testimony is addressed by a content identifier, which cannot be guessed. To discover testimony, hancock uses an index. The index uses source identifiers to testimony indentifiers, again leaking minimal information about proprietary sources.

Currently, Beyond Central runs the first hancock index.


See hancock source code for documentation, including how to install and use.

Hancock is open source software available under the AGPL 3 license.