Open secrets
Achieving a significant boost by a few hundred milliseconds in QR code scanning performance is a central theme of this blog. This gain was realized by reducing the amount of information encoded in the QR code, without compromising cryptographic privacy.
In article 4, we discussed how the dynamic portion of the QR code consists of the last 21 characters:

However, this graphic doesn’t clearly illustrate how many characters and how much entropy are allocated to the routing ID and the secret cryptographic key, respectively.
These two values are randomly generated by the webpage, but they are very different by nature:
- The routing ID R is not a secret value. It’s the virtual address of the target webpage, where the mobile device asks the server to deliver the encrypted data. Thus, the server needs to know the value of the routing ID, much like a postman needs to know the postal address on a sealed letter to deliver it.
- The cryptographic key K is a secret value. K is generated by the target webpage, and read by the mobile device. However, we must never reveal its value to the server, to guarantee the end-to-end encryption promise.
The mystery thickens. It’s impossible to use the same value for both the secret and non-secret components. We must not provide the server with any effective way to guess the secret key.
An obvious encoding method would involve concatenating the secret key and the routing ID:

The drawback of this scheme is that encoding two distinct values makes the content larger, and the QR code more complex. We want to encode as little information as possible.
This is where a subtle property of the cryptographic hash function SHA-256 comes into play:
- Let’s generate the crypto key K (a 21 characters passphrase) and encode it into the QR code,
- Let’s use, by convention, the routing ID R = sha256(K), and not encode it into the QR code.

This scheme works because the webpage and the mobile device compute the same value R, derived from K. It is crucial to understand that the reverse operation is impossible: when the server receives the value of R, it has no effective way to determine the secret value K from which R was derived.
Thanks to the non-reversibility property of hash functions, we effectively minimize the information encoded into the QR code. While the secret value K and the non-secret value R are strongly related to each other, it is still impossible for the server to guess K and thus decrypt user data. Your privacy is highly secured by end-to-end encryption.