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 … Cool Maze - Push to Computer” 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.
Initialization Vectors
Each share action involves the encryption and decryption of several chunks of data: the resource contents, a filename, and a preview image. Using the same Target AES key (derived from the password) and Mobile AES key (derived from Mobile secret) for these chunks, it is necessary to use a different Initialization Vector (IV) for each chunk. All the IV 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 numbers 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