#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint8_t;

/* Variables and functions */
int /*<<< orphan*/ AES_ECB_encrypt(int *, int *, int *, int);
scalar_t__ memcmp(char *, char *, int);
int /*<<< orphan*/ printf(char *);
void test_encrypt_ecb(void) {
  uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
                   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
  uint8_t out[] = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
                   0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};
  uint8_t in[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
                  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
  uint8_t buffer[16];
  AES_ECB_encrypt(in, key, buffer, 16);
  printf("ECB encrypt: ");
  if (0 == memcmp((char *)out, (char *)buffer, 16)) {
    printf("SUCCESS!\n");
  } else {
    printf("FAILURE!\n");
  }
}


x86 assembly (clang, -O0):
<test_encrypt_ecb>:
push   %rbp
mov    %rsp,%rbp
sub    $0x100,%rsp
lea    -0x40(%rbp),%rdi
lea    0xeaa(%rip),%rsi
mov    $0x40,%edx
call   1050 <memcpy@plt>
lea    -0x80(%rbp),%rdi
lea    0xed5(%rip),%rsi
mov    $0x40,%edx
call   1050 <memcpy@plt>
lea    -0xc0(%rbp),%rdi
lea    0xefd(%rip),%rsi
mov    $0x40,%edx
call   1050 <memcpy@plt>
lea    -0xc0(%rbp),%rdi
lea    -0x40(%rbp),%rsi
lea    -0x100(%rbp),%rdx
mov    $0x10,%ecx
call   1060 <AES_ECB_encrypt@plt>
lea    0xf10(%rip),%rdi
call   1030 <printf@plt>
lea    -0x80(%rbp),%rdi
lea    -0x100(%rbp),%rsi
mov    $0x10,%edx
call   1040 <memcmp@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    %rcx,%rax
jne    11e9 <test_encrypt_ecb+0xa9>
lea    0xeef(%rip),%rdi
call   1030 <printf@plt>
jmp    11f5 <test_encrypt_ecb+0xb5>
lea    0xee8(%rip),%rdi
call   1030 <printf@plt>
add    $0x100,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<test_encrypt_ecb>:
push   %rbx
sub    $0x100,%rsp
movaps 0xee1(%rip),%xmm0
movaps %xmm0,0xb0(%rsp)
movaps 0xec2(%rip),%xmm0
movaps %xmm0,0xa0(%rsp)
movaps 0xea3(%rip),%xmm0
movaps %xmm0,0x90(%rsp)
movaps 0xe84(%rip),%xmm0
movaps %xmm0,0x80(%rsp)
movaps 0xee5(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xec9(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movaps 0xead(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
movaps 0xe91(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movaps 0xef5(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xed9(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xebd(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xea1(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    %rsp,%rdi
lea    0x80(%rsp),%rsi
lea    0xc0(%rsp),%rbx
mov    %rbx,%rdx
mov    $0x10,%ecx
call   1060 <AES_ECB_encrypt@plt>
lea    0xeb6(%rip),%rdi
call   1040 <printf@plt>
lea    0x40(%rsp),%rdi
mov    %rbx,%rsi
mov    $0x10,%edx
call   1050 <memcmp@plt>
test   %rax,%rax
lea    0xeac(%rip),%rax
lea    0xe9c(%rip),%rdi
cmove  %rax,%rdi
call   1030 <puts@plt>
add    $0x100,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@__const.test_encrypt_ecb.key = [16 x i32] [i32 43, i32 126, i32 21, i32 22, i32 40, i32 174, i32 210, i32 166, i32 171, i32 247, i32 21, i32 136, i32 9, i32 207, i32 79, i32 60]
@__const.test_encrypt_ecb.out = [16 x i32] [i32 58, i32 215, i32 123, i32 180, i32 13, i32 122, i32 54, i32 96, i32 168, i32 158, i32 202, i32 243, i32 36, i32 102, i32 239, i32 151]
@__const.test_encrypt_ecb.in = [16 x i32] [i32 107, i32 193, i32 190, i32 226, i32 46, i32 64, i32 159, i32 150, i32 233, i32 61, i32 126, i32 17, i32 115, i32 147, i32 23, i32 42]
@.str = [14 x i8] c"ECB encrypt: \00"
@.str.1 = [10 x i8] c"SUCCESS!\0A\00"
@.str.2 = [10 x i8] c"FAILURE!\0A\00"
define void @test_encrypt_ecb() {
%1 = alloca [16 x i32]
%2 = alloca [16 x i32]
%3 = alloca [16 x i32]
%4 = alloca [16 x i32]
%5 = bitcast [16 x i32]* %1 to i8*
%6 = bitcast [16 x i32]* %2 to i8*
%7 = bitcast [16 x i32]* %3 to i8*
%8 = getelementptr inbounds [16 x i32], [16 x i32]* %3, i64 0, i64 0
%9 = getelementptr inbounds [16 x i32], [16 x i32]* %1, i64 0, i64 0
%10 = getelementptr inbounds [16 x i32], [16 x i32]* %4, i64 0, i64 0
%11 = call i32 @AES_ECB_encrypt(i32* %8, i32* %9, i32* %10, i32 16)
%12 = call i32 @printf(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
%13 = getelementptr inbounds [16 x i32], [16 x i32]* %2, i64 0, i64 0
%14 = bitcast i32* %13 to i8*
%15 = getelementptr inbounds [16 x i32], [16 x i32]* %4, i64 0, i64 0
%16 = bitcast i32* %15 to i8*
%17 = call i64 @memcmp(i8* %14, i8* %16, i32 16)
%18 = icmp eq i64 0, %17
br i1 %18, label %19, label %21
19: ; preds = %0
%20 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i64 0, i64 0))
br label %23
21: ; preds = %0
%22 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i64 0, i64 0))
br label %23
23: ; preds = %21, %19
ret void
}

LLVM IR (-O2):
@__const.test_encrypt_ecb.key = [16 x i32] [i32 43, i32 126, i32 21, i32 22, i32 40, i32 174, i32 210, i32 166, i32 171, i32 247, i32 21, i32 136, i32 9, i32 207, i32 79, i32 60]
@__const.test_encrypt_ecb.out = [16 x i32] [i32 58, i32 215, i32 123, i32 180, i32 13, i32 122, i32 54, i32 96, i32 168, i32 158, i32 202, i32 243, i32 36, i32 102, i32 239, i32 151]
@__const.test_encrypt_ecb.in = [16 x i32] [i32 107, i32 193, i32 190, i32 226, i32 46, i32 64, i32 159, i32 150, i32 233, i32 61, i32 126, i32 17, i32 115, i32 147, i32 23, i32 42]
@.str = [14 x i8] c"ECB encrypt: \00"
@str = [9 x i8] c"FAILURE!\00"
@str.3 = [9 x i8] c"SUCCESS!\00"
define void @test_encrypt_ecb() {
%1 = alloca [16 x i32]
%2 = alloca [16 x i32]
%3 = alloca [16 x i32]
%4 = alloca [16 x i32]
%5 = bitcast [16 x i32]* %1 to i8*
%6 = bitcast [16 x i32]* %2 to i8*
%7 = bitcast [16 x i32]* %3 to i8*
%8 = bitcast [16 x i32]* %4 to i8*
%9 = getelementptr inbounds [16 x i32], [16 x i32]* %3, i64 0, i64 0
%10 = getelementptr inbounds [16 x i32], [16 x i32]* %1, i64 0, i64 0
%11 = getelementptr inbounds [16 x i32], [16 x i32]* %4, i64 0, i64 0
%12 = call i32 @AES_ECB_encrypt(i32* %9, i32* %10, i32* %11, i32 16)
%13 = call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
%14 = call i64 @memcmp(i8* %6, i8* %8, i32 16)
%15 = icmp eq i64 %14, 0
%16 = select i1 %15, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @str.3, i64 0, i64 0), i8* getelementptr inbounds ([9 x i8], [9 x i8]* @str, i64 0, i64 0)
%17 = call i32 @puts(i8* dereferenceable(1) %16)
ret void
}