Skip to content

Commit

Permalink
Merge pull request #8 from kanav99/aesblock
Browse files Browse the repository at this point in the history
AESBlock Type
  • Loading branch information
kanav99 authored Apr 28, 2020
2 parents 1e207d8 + 7ca31e1 commit 16c601b
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 51 deletions.
10 changes: 5 additions & 5 deletions src/block_decryption.jl
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key)
function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key) where {B<:AESBlock}
cache = gen_cache(key)
AESDecryptBlock!(result, block, key, cache)
end

function AESDecryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key)
function AESDecryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key) where {B<:AESBlock}
result = zeros(UInt8, 16)
cache = gen_cache(key)
AESDecryptBlock!(result, block, key, cache)
result
end

function AESDecryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key, cache)
function AESDecryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key, cache) where {B<:AESBlock}
result = zeros(UInt8, 16)
AESDecryptBlock!(result, block, key, cache)
result
end

function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key::AES128Key, cache::CipherCache)
function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key::AES128Key, cache::CipherCache) where {B<:AESBlock}
current = result
copyto!(current, block)
K = cache.K
Expand Down Expand Up @@ -110,7 +110,7 @@ function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block
current
end

function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key::AES192Key, cache::CipherCache)
function AESDecryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key::AES192Key, cache::CipherCache) where {B<:AESBlock}
current = result
copyto!(current, block)
K = cache.K
Expand Down
10 changes: 5 additions & 5 deletions src/block_encryption.jl
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
"""
Note: you can pass `result` and `block` as same pointers
"""
function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key)
function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key) where {B<:AESBlock}
cache = gen_cache(key)
AESEncryptBlock!(result, block, key, cache)
end

function AESEncryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key, cache)
function AESEncryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key, cache) where {B<:AESBlock}
result = zeros(UInt8, 16)
AESEncryptBlock!(result, block, key, cache)
result
end

function AESEncryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key)
function AESEncryptBlock(block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key) where {B<:AESBlock}
result = zeros(UInt8, 16)
cache = gen_cache(key)
AESEncryptBlock!(result, block, key, cache)
result
end

function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key::AES128Key, cache::CipherCache)
function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key::AES128Key, cache::CipherCache) where {B<:AESBlock}
current = result
copyto!(current, block)
K = cache.K
Expand Down Expand Up @@ -96,7 +96,7 @@ function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block
current
end

function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}}, block::Union{Array{UInt8, 1}, SubArray{UInt8}}, key::AES192Key, cache::CipherCache)
function AESEncryptBlock!(result::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, block::Union{Array{UInt8, 1}, SubArray{UInt8}, B}, key::AES192Key, cache::CipherCache) where {B<:AESBlock}
current = result
copyto!(current, block)
K = cache.K
Expand Down
48 changes: 27 additions & 21 deletions src/modes/cbc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@ function AESCBC!(ciphertext, plaintext, iv::Array{UInt8, 1}, key::AbstractAESKey
ciphertext[len+i] = pad
end
iters = Int((len + pad) / 16)
for i in 1:iters
start = 16(i-1)+1
ending = 16i
view_res = @view(ciphertext[start:ending])
if i == 1
@. view_res = view_res iv
else
@. view_res = view_res @view(ciphertext[start-16:ending-16])
end
AESEncryptBlock!(view_res, view_res, key, cache)
ciphertextblock = AESBlock(ciphertext)
prevblock = AESBlock(ciphertext)
# iteration 1 start
ciphertextblock .⊻= iv
AESEncryptBlock!(ciphertextblock, ciphertextblock, key, cache)
increment!(ciphertextblock)
# iteration 1 end
for i in 2:iters
@. ciphertextblock ⊻= prevblock
AESEncryptBlock!(ciphertextblock, ciphertextblock, key, cache)
increment!(ciphertextblock)
increment!(prevblock)
end
ciphertext
end
Expand All @@ -40,17 +42,21 @@ end
function AESCBC_D!(plaintext, ciphertext::Array{UInt8, 1}, iv::Array{UInt8, 1}, key::AbstractAESKey, cache::AbstractAESCache; remove_pad=true)
len = length(ciphertext)
iters = Int(len / 16)
for i in 1:iters
start = 16(i-1)+1
ending = 16i
ct_res = @view(ciphertext[start:ending])
view_res = @view(plaintext[start:ending])
AESDecryptBlock!(view_res, ct_res, key, cache)
if i == 1
@. view_res = view_res iv
else
@. view_res = view_res @view(ciphertext[start-16:ending-16])
end
plaintextblock = AESBlock(plaintext)
ciphertextblock = AESBlock(ciphertext)
prevblock = AESBlock(ciphertext)
# iteration 1 start
AESDecryptBlock!(plaintextblock, ciphertextblock, key, cache)
plaintextblock .⊻= iv
increment!(plaintextblock)
increment!(ciphertextblock)
# iteration 1 end
for i in 2:iters
AESDecryptBlock!(plaintextblock, ciphertextblock, key, cache)
plaintextblock .⊻= prevblock
increment!(plaintextblock)
increment!(ciphertextblock)
increment!(prevblock)
end
if remove_pad
pad = plaintext[end]
Expand Down
20 changes: 11 additions & 9 deletions src/modes/ctr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,26 @@ end
function AESCTR!(ciphertext, plaintext, iv::Array{UInt8, 1}, key::AbstractAESKey, cache::AbstractAESCache)
len = length(plaintext)
pad = 16 - (len % 16)
result = similar(Array{UInt8, 1}, len)
iters = Int((len + pad) / 16)
counter = cache.modecache
counter .= iv
ciphertextblock = AESBlock(ciphertext)
plaintextblock = AESBlock(plaintext)
for i in 1:(iters-1)
start = 16(i-1)+1
ending = 16i
resultview = @view(result[start:ending])
AESEncryptBlock!(resultview, counter, key, cache)
@. resultview ⊻= @view(plaintext[start:ending])
AESEncryptBlock!(ciphertextblock, counter, key, cache)
@. ciphertextblock ⊻= plaintextblock
increment!(counter)
increment!(ciphertextblock)
increment!(plaintextblock)
end
# for the last iteration, we dont need counter no more
# we can use the inplace property of AES
AESEncryptBlock!(counter, counter, key, cache)
start = 16(iters-1)+1
@. @view(result[start:len]) = @view(plaintext[start:len]) @view(counter[1:16-pad])
result
offset = 16(iters-1)
for i in 1:(16-pad)
ciphertext[offset+i] = UInt8(plaintext[offset+i]) counter[i]
end
ciphertext
end

# Encryption is same as decryption in CTR mode for a give Key and IV
Expand Down
17 changes: 8 additions & 9 deletions src/modes/ecb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ function AESECB!(ciphertext, plaintext, key::AbstractAESKey, cache::AbstractAESC
ciphertext[len+i] = pad
end
iters = Int((len + pad) / 16)
ciphertextblock = AESBlock(ciphertext)
for i in 1:iters
start = 16(i-1)+1
ending = 16i
view_res = @view(ciphertext[start:ending])
AESEncryptBlock!(view_res, view_res, key, cache)
AESEncryptBlock!(ciphertextblock, ciphertextblock, key, cache)
increment!(ciphertextblock)
end
ciphertext
end
Expand All @@ -35,12 +34,12 @@ end
function AESECB_D!(plaintext, ciphertext::Array{UInt8, 1}, key::AbstractAESKey, cache::AbstractAESCache)
len = length(ciphertext)
iters = Int(len / 16)
ciphertextblock = AESBlock(ciphertext)
plaintextblock = AESBlock(plaintext)
for i in 1:iters
start = 16(i-1)+1
ending = 16i
ct_view = @view(ciphertext[start:ending])
res_view = @view(plaintext[start:ending])
AESDecryptBlock!(res_view, ct_view, key, cache)
AESDecryptBlock!(plaintextblock, ciphertextblock, key, cache)
increment!(ciphertextblock)
increment!(plaintextblock)
end
pad = plaintext[end]
@view(plaintext[1:len-pad])
Expand Down
28 changes: 28 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,31 @@ end

@inline needs_iv(cipher) = iscbc(cipher) || isctr(cipher)

# Block type

mutable struct AESBlock{dataType,offsetType} <: AbstractArray{UInt8, 1}
data::dataType
offset::offsetType
function AESBlock(data, offset=1, len=16)
new{typeof(data), typeof(offset)}(data, offset)
end
end

function Base.getindex(block::B, i) where {B<:AESBlock}
return UInt8(block.data[16*(block.offset - 1) + i])
end

function Base.setindex!(block::B, val, i) where {B<:AESBlock}
block.data[16*(block.offset - 1) + i] = eltype(block.data)(val)
end

function Base.copyto!(block::B, arr::AbstractArray{T2,1}) where {B<:AESBlock, T2}
for i in 1:16
block.data[16*(block.offset - 1) + i] = eltype(block.data)(arr[i])
end
end

@inline Base.size(block::AESBlock) = (16,)
@inline Base.length(block::AESBlock) = 16

increment!(block::B) where {B<:AESBlock} = block.offset += 1
4 changes: 2 additions & 2 deletions test/ctr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ using Rijndael, Test
k = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]
key = AES128Key(k)

plaintext = Array{UInt8}("The quick brown fox jumps over the lazy dog.")
plaintext = "The quick brown fox jumps over the lazy dog."
iv = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f]

cipher = AES(;key_length=128, mode=Rijndael.CTR, key=key)
Expand All @@ -17,5 +17,5 @@ ciphertext = [0x04, 0x96, 0x02, 0xec, 0xe8, 0x18, 0x5b, 0xd5,
0xfe, 0x8f, 0xaf, 0xe5, 0x64, 0xf9, 0xe9, 0x62,
0xdd, 0xa1, 0xe7, 0xb6]

@test pt == plaintext
@test pt === plaintext
@test ct.data == ciphertext

0 comments on commit 16c601b

Please sign in to comment.