look at the code for GCM encrypt:
proc encrypt*[T](ctx: var GCM[T]; input: openArray[byte]; output: var openArray[byte]) =
mixin encrypt
var ectr: array[16, byte]
assert(len(input) <= len(output))
var length = len(input)
var offset = 0
ctx.datalen += uint64(length)
while length > 0:
let uselen = if length < 16: length else: 16
inc128(ctx.y)
ctx.cipher.encrypt(ctx.y, ectr)
for i in 0 ..< uselen:
output[offset + i] = ectr[i] xor input[offset + i]
ghash(ctx.buf, ctx.h, output.toOpenArray(offset, offset + uselen - 1))
length -= uselen
offset += uselen
here, ectr holds the keystream values that are xored with the input (ectr[i] xor input[offset + i]), but what if the input is not a multiple of 16 bytes? The keystream gets truncated. This means that calling encrypt in multiple chunks does not produce the same output as a full length run when the input chunks are not multiples of 16 bytes. Encrypting and then decrypting will still work the same as long as the chunk sizes are the same (thus the key stream truncates the same way), but kinda sucks. In order for client to code properly use these functions they have to create 16 byte aligned buffers with 0 padding so they can rip the keystream out and manually xor it with the next round of data to keep the stream valid. This requires the entire stream to be copied for no reason.
Fixing this is as simple as lifting ectr into the GCM object and priming it in init. Then just replenish it in encrypt and decrypt when you need more keystream.
look at the code for GCM encrypt:
here,
ectrholds the keystream values that arexored with the input (ectr[i] xor input[offset + i]), but what if the input is not a multiple of 16 bytes? The keystream gets truncated. This means that callingencryptin multiple chunks does not produce the same output as a full length run when the input chunks are not multiples of 16 bytes. Encrypting and then decrypting will still work the same as long as the chunk sizes are the same (thus the key stream truncates the same way), but kinda sucks. In order for client to code properly use these functions they have to create 16 byte aligned buffers with 0 padding so they can rip the keystream out and manuallyxorit with the next round of data to keep the stream valid. This requires the entire stream to be copied for no reason.Fixing this is as simple as lifting
ectrinto the GCM object and priming it ininit. Then just replenish it inencryptanddecryptwhen you need more keystream.