C.3. Random-Access Decryption

If the one-time key is not yet cached: – Read the random nonce and the key commitment from the front of the stream, derive the one-time key, and verify the key commitment as above. – Cache the one-time key. • If the authentic plaintext length is not yet cached: – Get the apparent ciphertext length from the underlying stream. For example, with a ciphertext saved on disk, this would be the file size. This value may be inauthentic, and we need to authenticate it. – Compute the apparent length of the final ciphertext chunk. This is the total length, minus the random nonce and commitment lengths (56), modulo 16400. Subtract that length from the total to give the apparent start offset of the final ciphertext chunk. – Seek the underlying stream to that start offset. – Read the final ciphertext chunk and decrypt it with AES-GCM using the onetime key and the appropriate final chunk nonce.

– If decryption succeeds, the ciphertext length is authentic. Compute the authentic plaintext length by subtracting the random nonce and commitment lengths, plus 16 bytes times the number of chunks (the GCM tags), from the ciphertext length. – Cache the authentic plaintext length. • If the plaintext seek target is beyond the authentic plaintext length, arrange to return EOF to the caller for any subsequent reads. • Otherwise, seek the underlying stream to the start of the ciphertext chunk corresponding to the caller’s plaintext seek target. To account for the seek offset within that chunk, arrange to skip the appropriate number of bytes after the next decryption.

Last updated