include("../src/BlockCiphers.jl")
include("testing.jl")

importall BlockCiphers

print("testing AES ")

plain = zeros(Uint8, 16)
k1 = AES(zeros(Uint8, int32(128/8)))
c1 = encrypt(k1, plain)
p1 = decrypt(k1, c1)

@assert_equal(c1, [0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b, 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e])

k2 = AES(zeros(Uint8, int32(128/8)))
c2 = encrypt(k2, plain)
p2 = decrypt(k2, c1)

@assert_equal(c1, c2)
@assert_equal(plain, p1)
@assert_equal(plain, p2)


# from http://www.cs.utsa.edu/~wagner/laws/AEStestRuns.html
begin # Gladman's Test Data, 128-bit key
    key = AES([0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c])

    plain = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end

begin # Gladman's Test Data, 192-bit key
    key = AES([0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0x76, 0x2e, 0x71, 0x60, 0xf3, 0x8b, 0x4d, 0xa5])

    plain = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0xf9, 0xfb, 0x29, 0xae, 0xfc, 0x38, 0x4a, 0x25, 0x03, 0x40, 0xd8, 0x33, 0xb8, 0x7e, 0xbc, 0x00])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end

begin # Gladman's Test Data, 256-bit key
    key = AES([0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 0x76, 0x2e, 0x71, 0x60, 0xf3, 0x8b, 0x4d, 0xa5, 0x6a, 0x78, 0x4d, 0x90, 0x45, 0x19, 0x0c, 0xfe])

    plain = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0x1a, 0x6e, 0x6c, 0x2c, 0x66, 0x2e, 0x7d, 0xa6, 0x50, 0x1f, 0xfb, 0x62, 0xbc, 0x9e, 0x93, 0xf3])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end


begin # AES Specification Test Data, 128-bit key
    key = AES([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f])

    plain = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end

begin # AES Specification Test Data, 192-bit key
    key = AES([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17])

    plain = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end

begin # AES Specification Test Data, 256-bit key
    key = AES([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f])

    plain = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
    encrypted = encrypt(key, plain)

    @assert_equal(encrypted, [0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89])

    decrypted = decrypt(key, encrypted)
    @assert_equal(plain, decrypted)
end

println()

print("testing DES ")

begin
    key = DES([0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0x95, 0xa8, 0xd7, 0x28, 0x13, 0xda, 0xa9, 0x4d])
    @assert_equal(plain, decrypt(key, encrypted))
end

begin
    key = DES([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0x0e, 0xec, 0x14, 0x87, 0xdd, 0x8c, 0x26, 0xd5])
    @assert_equal(plain, decrypt(key, encrypted))
end

begin
    key = DES([0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0x7a, 0xd1, 0x6f, 0xfb, 0x79, 0xc4, 0x59, 0x26])
    @assert_equal(plain, decrypt(key, encrypted))
end

begin
    key = DES([0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0xd3, 0x74, 0x62, 0x94, 0xca, 0x6a, 0x6c, 0xf3])
    @assert_equal(plain, decrypt(key, encrypted))
end

begin
    key = DES([0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0x80, 0x9f, 0x5f, 0x87, 0x3c, 0x1f, 0xd7, 0x61])
    @assert_equal(plain, decrypt(key, encrypted))
end

begin
    key = DES([0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
    plain = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0xc0, 0x2f, 0xaf, 0xfe, 0xc9, 0x89, 0xd1, 0xfc])
    @assert_equal(plain, decrypt(key, encrypted))
end


begin
    key = DES([0x2b, 0xd6, 0x45, 0x9f, 0x82, 0xc5, 0xb3, 0x00])
    plain = [0xea, 0x02, 0x47, 0x14, 0xad, 0x5c, 0x4d, 0x84]

    encrypted = encrypt(key, plain)
    @assert_equal(encrypted, [0x12, 0x6e, 0xfe, 0x8e, 0xd3, 0x12, 0x19, 0x0a])
    @assert_equal(plain, decrypt(key, encrypted))
end



println()