private static void BytesToWords128(byte[] key, out QWords128 words128) { fixed(byte *k = key) { words128 = *((QWords128 *)k); } }
static void Update(byte *bytes, uint len, QWords128 *keyStreamBuf, ref uint keystreamBufferPos, ref QWords128 counter, Keys128128 keys) { while (len > 0) { var remainningKeystream = KeystreamBufferSize - keystreamBufferPos; if (remainningKeystream == 0) { keystreamBufferPos = 0; remainningKeystream = KeystreamBufferSize; var ksb = keyStreamBuf; for (uint i = 0; i < KsBlockCount; i += 4) { for (uint j = 0; j < 4; j++) { ksb[i + j] = counter; if (++counter.v1 == 0) { ++counter.v0; } } Cipher.encrypt_128_128_4blocks(keys, &ksb[i]); } } var count = len < remainningKeystream ? len : remainningKeystream; NaiveUtils.XorBytesUnsafe((byte *)keyStreamBuf + keystreamBufferPos, bytes, count); bytes += count; len -= count; keystreamBufferPos += count; } }
// Generate key schedule and encrypt at the same time public static void encrypt_128_128(QWords128 key, ref QWords128 ciphertext) { speck_round_64(ref ciphertext.v1, ref ciphertext.v0, key.v0); for (uint64 i = 0; i < ROUNDS128128 - 1; i++) { speck_round_64(ref key.v1, ref key.v0, i); speck_round_64(ref ciphertext.v1, ref ciphertext.v0, key.v0); } }
public static Keys128128 getKeySchedules_128_128(QWords128 key) { var r = Keys128128.alloc(); var keys = r.keys; keys[0] = key.v0; for (uint64 i = 0; i < ROUNDS128128 - 1; i++) { speck_round_64(ref key.v1, ref key.v0, i); keys[1 + i] = key.v0; } return(r); }