Add AES-CTR enc with a start block index

This commit is contained in:
akshaya
2024-08-26 08:01:35 -04:00
parent 7d88ef63e0
commit 1485bb43e3
2 changed files with 72 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
import nimcrypto
import endians
# This function processes 'data' using AES in CTR mode.
# For CTR mode, the same function handles both encryption and decryption.
@@ -15,6 +16,28 @@ proc aes_ctr*(key, iv, data: openArray[byte]): seq[byte] =
ctx.clear()
return output
# This function advances the counter in the AES-CTR IV by a specified number of blocks.
proc advance_ctr*(iv: var openArray[byte], blocks: int) =
var counter: uint64
bigEndian64(addr counter, addr iv[8])
counter += uint64(blocks)
bigEndian64(addr iv[8], addr counter)
# This function encrypting processes 'data' using AES in CTR mode from startIndex, without processing all preceding data.
# For CTR mode, the same function handles both encryption and decryption.
proc aes_ctr_start_index*(key, iv, data: openArray[byte], startIndex: int): seq[byte] =
assert key.len == 16, "Key must be 16 bytes for AES-128"
assert iv.len == 16, "IV must be 16 bytes for AES-128"
assert startIndex mod 16 == 0, "Start index must be a multiple of 16"
var advIV = @iv
# Advance the counter to the start index
let blocksToAdvance = startIndex div 16
advance_ctr(advIV, blocksToAdvance)
return aes_ctr(key, advIV, data)
# This function hashes 'data' using SHA-256.
proc sha256_hash*(data: openArray[byte]): array[32, byte] =
return sha256.digest(data).data

View File

@@ -113,4 +113,52 @@ suite "cryptographic_functions_tests":
let hmacResult = hmac(emptyKey, emptyData)
# Assertions
assert hmacResult == expectedHmac, "HMAC of empty key and data does not match the expected HMAC"
assert hmacResult == expectedHmac, "HMAC of empty key and data does not match the expected HMAC"
test "aes_ctr_start_index_zero_index":
# Define test data
let key = cast[array[16, byte]]("thisis16byteskey")
let iv = cast[array[16, byte]]("thisis16bytesiv!")
let data: seq[byte] = cast[seq[byte]]("thisisdata")
# Encrypt starting from index 0 (should be the same as full data encryption)
let startIndex = 0
let encrypted = aes_ctr_start_index(key, iv, data, startIndex)
# Encrypt the whole data with the original IV
let expected = aes_ctr(key, iv, data)
# Assertions
assert encrypted == expected, "Encrypted data with start index 0 should match the full AES-CTR encryption"
test "aes_ctr_start_index_empty_data":
# Define test data
let key = cast[array[16, byte]]("thisis16byteskey")
let iv = cast[array[16, byte]]("thisis16bytesiv!")
let emptyData: array[0, byte] = []
# Encrypt from start index 0 on empty data
let startIndex = 0
let encrypted = aes_ctr_start_index(key, iv, emptyData, startIndex)
# Encrypting empty data should result in empty data
assert encrypted == emptyData, "Encrypted empty data with start index 0 should be empty"
test "aes_ctr_start_index_middle":
# Define test data
let key = cast[array[16, byte]]("thisis16byteskey")
let iv = cast[array[16, byte]]("thisis16bytesiv!")
let data: seq[byte] = cast[seq[byte]]("thisisverylongdata")
# Encrypt starting from index 16
let startIndex = 16
let encrypted2 = aes_ctr_start_index(key, iv, data[startIndex..^1], startIndex)
# Encrypt the data up to index 15
let encrypted1 = aes_ctr(key, iv, data[0..startIndex-1])
# Encrypt the whole data with the original IV
let expected = aes_ctr(key, iv, data)
# Assertions
assert encrypted1 & encrypted2 == expected, "Encrypted data with start index should match the full AES-CTR encryption"