#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 */

/* Variables and functions */
scalar_t__ get_Product_mac(unsigned char *);
int /*<<< orphan*/ memset(unsigned char *, int /*<<< orphan*/, int);
int /*<<< orphan*/ printf(char *);
scalar_t__ read_buffer_otp(int, unsigned char *, int);
int /*<<< orphan*/ strcmp(unsigned char *, unsigned char *);
unsigned char swim_chang(unsigned char);
int encrypt_read() {
  unsigned char mac[20];
  unsigned char buff[32];
  unsigned char mac_product[20];
  memset(mac, 0, 20);
  memset(mac_product, 0, 20);
  if (read_buffer_otp(0xb8114030, buff, 32) < 0) {
    return -1;
  }
  mac[0] = swim_chang(buff[0]);
  mac[1] = swim_chang(buff[1]);
  mac[2] = swim_chang(buff[4]);
  mac[3] = swim_chang(buff[5]);
  mac[4] = swim_chang(buff[8]);
  mac[5] = swim_chang(buff[9]);
  mac[6] = swim_chang(buff[12]);
  mac[7] = swim_chang(buff[13]);
  mac[8] = swim_chang(buff[16]);
  mac[9] = swim_chang(buff[17]);
  mac[10] = swim_chang(buff[20]);
  mac[11] = swim_chang(buff[21]);
  if (get_Product_mac(mac_product) < 0) {
    printf("get product error\n");
    return -1;
  }
  if (!strcmp(mac_product, mac)) {
    return 0;
  } else {
    return -1;
  }
}


x86 assembly (clang, -O0):
<encrypt_read>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
lea    -0x20(%rbp),%rdi
xor    %esi,%esi
mov    $0x14,%edx
call   1040 <memset@plt>
lea    -0x60(%rbp),%rdi
xor    %esi,%esi
mov    $0x14,%edx
call   1040 <memset@plt>
lea    -0x40(%rbp),%rsi
mov    $0xb8114030,%edi
mov    $0x20,%edx
call   1050 <read_buffer_otp@plt>
cmp    $0x0,%rax
jge    11b1 <encrypt_read+0x51>
movl   $0xffffffff,-0x4(%rbp)
jmp    1295 <encrypt_read+0x135>
movzbl -0x40(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x20(%rbp)
movzbl -0x3f(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1f(%rbp)
movzbl -0x3c(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1e(%rbp)
movzbl -0x3b(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1d(%rbp)
movzbl -0x38(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1c(%rbp)
movzbl -0x37(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1b(%rbp)
movzbl -0x34(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x1a(%rbp)
movzbl -0x33(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x19(%rbp)
movzbl -0x30(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x18(%rbp)
movzbl -0x2f(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x17(%rbp)
movzbl -0x2c(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x16(%rbp)
movzbl -0x2b(%rbp),%edi
call   1070 <swim_chang@plt>
mov    %al,-0x15(%rbp)
lea    -0x60(%rbp),%rdi
call   1080 <get_Product_mac@plt>
cmp    $0x0,%rax
jge    126c <encrypt_read+0x10c>
lea    0xda5(%rip),%rdi
call   1030 <printf@plt>
movl   $0xffffffff,-0x4(%rbp)
jmp    1295 <encrypt_read+0x135>
lea    -0x60(%rbp),%rdi
lea    -0x20(%rbp),%rsi
call   1060 <strcmp@plt>
cmp    $0x0,%eax
jne    128e <encrypt_read+0x12e>
movl   $0x0,-0x4(%rbp)
jmp    1295 <encrypt_read+0x135>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<encrypt_read>:
push   %rbx
sub    $0x60,%rsp
mov    %rsp,%rdi
xor    %esi,%esi
mov    $0x14,%edx
call   1040 <memset@plt>
lea    0x40(%rsp),%rdi
xor    %esi,%esi
mov    $0x14,%edx
call   1040 <memset@plt>
lea    0x20(%rsp),%rsi
mov    $0xb8114030,%edi
mov    $0x20,%edx
call   1050 <read_buffer_otp@plt>
mov    $0xffffffff,%ebx
test   %rax,%rax
js     127c <encrypt_read+0x11c>
movzbl 0x20(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,(%rsp)
movzbl 0x21(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x1(%rsp)
movzbl 0x24(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x2(%rsp)
movzbl 0x25(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x3(%rsp)
movzbl 0x28(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x4(%rsp)
movzbl 0x29(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x5(%rsp)
movzbl 0x2c(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x6(%rsp)
movzbl 0x2d(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x7(%rsp)
movzbl 0x30(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x8(%rsp)
movzbl 0x31(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0x9(%rsp)
movzbl 0x34(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0xa(%rsp)
movzbl 0x35(%rsp),%edi
call   1070 <swim_chang@plt>
mov    %al,0xb(%rsp)
lea    0x40(%rsp),%rdi
call   1080 <get_Product_mac@plt>
test   %rax,%rax
js     1270 <encrypt_read+0x110>
lea    0x40(%rsp),%rdi
mov    %rsp,%rsi
call   1060 <strcmp@plt>
neg    %eax
sbb    %ebx,%ebx
jmp    127c <encrypt_read+0x11c>
lea    0xd89(%rip),%rdi
call   1030 <puts@plt>
mov    %ebx,%eax
add    $0x60,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@.str = [19 x i8] c"get product error\0A\00"
define i32 @encrypt_read() {
%1 = alloca i32
%2 = alloca [20 x i8]
%3 = alloca [32 x i8]
%4 = alloca [20 x i8]
%5 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 0
%6 = call i32 @memset(i8* %5, i32 0, i32 20)
%7 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%8 = call i32 @memset(i8* %7, i32 0, i32 20)
%9 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 0
%10 = call i64 @read_buffer_otp(i32 -1206829008, i8* %9, i32 32)
%11 = icmp slt i64 %10, 0
br i1 %11, label %12, label %13
12: ; preds = %0
store i32 -1, i32* %1
br label %74
13: ; preds = %0
%14 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 0
%15 = load i8, i8* %14
%16 = call zeroext i8 @swim_chang(i8 zeroext %15)
%17 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 0
store i8 %16, i8* %17
%18 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 1
%19 = load i8, i8* %18
%20 = call zeroext i8 @swim_chang(i8 zeroext %19)
%21 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 1
store i8 %20, i8* %21
%22 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 4
%23 = load i8, i8* %22
%24 = call zeroext i8 @swim_chang(i8 zeroext %23)
%25 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 2
store i8 %24, i8* %25
%26 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 5
%27 = load i8, i8* %26
%28 = call zeroext i8 @swim_chang(i8 zeroext %27)
%29 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 3
store i8 %28, i8* %29
%30 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 8
%31 = load i8, i8* %30
%32 = call zeroext i8 @swim_chang(i8 zeroext %31)
%33 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 4
store i8 %32, i8* %33
%34 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 9
%35 = load i8, i8* %34
%36 = call zeroext i8 @swim_chang(i8 zeroext %35)
%37 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 5
store i8 %36, i8* %37
%38 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 12
%39 = load i8, i8* %38
%40 = call zeroext i8 @swim_chang(i8 zeroext %39)
%41 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 6
store i8 %40, i8* %41
%42 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 13
%43 = load i8, i8* %42
%44 = call zeroext i8 @swim_chang(i8 zeroext %43)
%45 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 7
store i8 %44, i8* %45
%46 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 16
%47 = load i8, i8* %46
%48 = call zeroext i8 @swim_chang(i8 zeroext %47)
%49 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 8
store i8 %48, i8* %49
%50 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 17
%51 = load i8, i8* %50
%52 = call zeroext i8 @swim_chang(i8 zeroext %51)
%53 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 9
store i8 %52, i8* %53
%54 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 20
%55 = load i8, i8* %54
%56 = call zeroext i8 @swim_chang(i8 zeroext %55)
%57 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 10
store i8 %56, i8* %57
%58 = getelementptr inbounds [32 x i8], [32 x i8]* %3, i64 0, i64 21
%59 = load i8, i8* %58
%60 = call zeroext i8 @swim_chang(i8 zeroext %59)
%61 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 11
store i8 %60, i8* %61
%62 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%63 = call i64 @get_Product_mac(i8* %62)
%64 = icmp slt i64 %63, 0
br i1 %64, label %65, label %67
65: ; preds = %13
%66 = call i32 @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0))
store i32 -1, i32* %1
br label %74
67: ; preds = %13
%68 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%69 = getelementptr inbounds [20 x i8], [20 x i8]* %2, i64 0, i64 0
%70 = call i32 @strcmp(i8* %68, i8* %69)
%71 = icmp ne i32 %70, 0
br i1 %71, label %73, label %72
72: ; preds = %67
store i32 0, i32* %1
br label %74
73: ; preds = %67
store i32 -1, i32* %1
br label %74
74: ; preds = %73, %72, %65, %12
%75 = load i32, i32* %1
ret i32 %75
}

LLVM IR (-O2):
@str = [18 x i8] c"get product error\00"
define i32 @encrypt_read() {
%1 = alloca [20 x i8]
%2 = alloca [32 x i8]
%3 = alloca [20 x i8]
%4 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 0
%5 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 0
%6 = getelementptr inbounds [20 x i8], [20 x i8]* %3, i64 0, i64 0
%7 = call i32 @memset(i8* %4, i32 0, i32 20)
%8 = call i32 @memset(i8* %6, i32 0, i32 20)
%9 = call i64 @read_buffer_otp(i32 -1206829008, i8* %5, i32 32)
%10 = icmp slt i64 %9, 0
br i1 %10, label %66, label %11
11: ; preds = %0
%12 = load i8, i8* %5
%13 = call zeroext i8 @swim_chang(i8 zeroext %12)
store i8 %13, i8* %4
%14 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 1
%15 = load i8, i8* %14
%16 = call zeroext i8 @swim_chang(i8 zeroext %15)
%17 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 1
store i8 %16, i8* %17
%18 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 4
%19 = load i8, i8* %18
%20 = call zeroext i8 @swim_chang(i8 zeroext %19)
%21 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 2
store i8 %20, i8* %21
%22 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 5
%23 = load i8, i8* %22
%24 = call zeroext i8 @swim_chang(i8 zeroext %23)
%25 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 3
store i8 %24, i8* %25
%26 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 8
%27 = load i8, i8* %26
%28 = call zeroext i8 @swim_chang(i8 zeroext %27)
%29 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 4
store i8 %28, i8* %29
%30 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 9
%31 = load i8, i8* %30
%32 = call zeroext i8 @swim_chang(i8 zeroext %31)
%33 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 5
store i8 %32, i8* %33
%34 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 12
%35 = load i8, i8* %34
%36 = call zeroext i8 @swim_chang(i8 zeroext %35)
%37 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 6
store i8 %36, i8* %37
%38 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 13
%39 = load i8, i8* %38
%40 = call zeroext i8 @swim_chang(i8 zeroext %39)
%41 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 7
store i8 %40, i8* %41
%42 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 16
%43 = load i8, i8* %42
%44 = call zeroext i8 @swim_chang(i8 zeroext %43)
%45 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 8
store i8 %44, i8* %45
%46 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 17
%47 = load i8, i8* %46
%48 = call zeroext i8 @swim_chang(i8 zeroext %47)
%49 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 9
store i8 %48, i8* %49
%50 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 20
%51 = load i8, i8* %50
%52 = call zeroext i8 @swim_chang(i8 zeroext %51)
%53 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 10
store i8 %52, i8* %53
%54 = getelementptr inbounds [32 x i8], [32 x i8]* %2, i64 0, i64 21
%55 = load i8, i8* %54
%56 = call zeroext i8 @swim_chang(i8 zeroext %55)
%57 = getelementptr inbounds [20 x i8], [20 x i8]* %1, i64 0, i64 11
store i8 %56, i8* %57
%58 = call i64 @get_Product_mac(i8* %6)
%59 = icmp slt i64 %58, 0
br i1 %59, label %60, label %62
60: ; preds = %11
%61 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @str, i64 0, i64 0))
br label %66
62: ; preds = %11
%63 = call i32 @strcmp(i8* %6, i8* %4)
%64 = icmp ne i32 %63, 0
%65 = sext i1 %64 to i32
br label %66
66: ; preds = %62, %0, %60
%67 = phi i32 [ -1, %60 ], [ -1, %0 ], [ %65, %62 ]
ret i32 %67
}