A world of nonces
Each share action is identified throughout the mobile app, the server, and the target web page, by its action ID. The action ID is a random number generated by the mobile app, when the user initiates the “Share with … Push to Computer - Cool Maze” process, and it is meant to be unique. This is called a nonce.
We routinely generate nonces without a central component verifying their uniqueness. Instead, we make them long enough so that the probability of generating the same number twice is vanishingly small. Such collisions are very unlikely, and would not have serious consequences for the security and privacy of the system.
One-off values
Target secret
The target web page randomly generates a secret “password” shared only between the target and the source mobile device, via the QR code. This password is a nonce!
Mobile secret
The mobile device starts encrypting and uploading data in the background before it has scanned the QR code, for performance reasons. This is why it first generates its own cryptographic key. That’s a nonce!
Routing ID
Data is delivered from source to target using a one-off Routing ID. As explained in article 13, the value of the Routing ID is derived from the Target secret, for performance reason, to minimize the length of the message shared from target to source in the QR code. The Routing ID is conventionally derived from a nonce.
Salt
We derive the Target secret and the Mobile secret into AES keys using PBKDF2. These two secrets being already randomly generated, dictionary attacks would not be effective. PBKDF2 still requires a salt parameter, thus we pass a static constant for simplicity, to avoid unnecessary transmission overhead. The salt is not a nonce!
Initialization Vectors
Each share action involves the encryption and decryption of several items: the resource contents, a filename, and a preview image. Because the same Target AES key and Mobile AES key are reused across the three encrypted items, each item must use a different Initialization Vector (IV). All the IVs are nonces!
Object name
The encrypted resources may briefly transit through Google Cloud Storage. Their “Object name” (like a filename) is arbitrary. It’s a nonce!
Cookie
The Prefetch optimization assigns an ephemeral 3-letter name to the user’s browser. That’s a nonce!
Short URL
The backend sometimes needs to generate a short-lived, short-length URL for an encrypted resource. That’s a nonce!
Safe generation
To guarantee the privacy of our end-to-end encryption system, it is crucial that our nonces cannot be guessed. This is why we use only cryptographically safe random number generators:
- window.crypto in Javascript, for the target web page
- java.security.SecureRandom in Java, for the Android app
- SecRandomCopyBytes in Swift, for the iOS app
- crypto/rand in Go, for the server