#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 */
int /*<<< orphan*/ gc_hmac_md5(char const *, size_t, char const *, size_t,
                               char *);
size_t strlen(char const *);
void cram_md5_digest(const char *challenge, size_t challengelen,
                     const char *secret, size_t secretlen, char response[32]) {
  char hash[16];
  size_t i;
  gc_hmac_md5(secret, secretlen ? secretlen : strlen(secret), challenge,
              challengelen ? challengelen : strlen(challenge), hash);
  for (i = 0; i < 16; i++) {
    *response++ = ((hash[i] >> 4 & 0x0F) > 9 ? 'a' + (hash[i] >> 4 & 0x0F) - 10
                                             : '0' + (hash[i] >> 4 & 0x0F));
    *response++ = ((hash[i] & 0x0F) > 9 ? 'a' + (hash[i] & 0x0F) - 10
                                        : '0' + (hash[i] & 0x0F));
  }
}


x86 assembly (clang, -O0):
<cram_md5_digest>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     115f <cram_md5_digest+0x3f>
mov    -0x20(%rbp),%rax
mov    %rax,-0x58(%rbp)
jmp    116c <cram_md5_digest+0x4c>
mov    -0x18(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x58(%rbp)
mov    -0x58(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x60(%rbp)
cmpq   $0x0,-0x10(%rbp)
je     1194 <cram_md5_digest+0x74>
mov    -0x10(%rbp),%rax
mov    %rax,-0x70(%rbp)
jmp    11a1 <cram_md5_digest+0x81>
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x70(%rbp)
mov    -0x60(%rbp),%rdx
mov    -0x68(%rbp),%rsi
mov    -0x50(%rbp),%rdi
mov    -0x70(%rbp),%rcx
lea    -0x40(%rbp),%r8
call   1030 <gc_hmac_md5@plt>
movq   $0x0,-0x48(%rbp)
cmpq   $0x10,-0x48(%rbp)
jae    1295 <cram_md5_digest+0x175>
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
sar    $0x4,%eax
and    $0xf,%eax
cmp    $0x9,%eax
jle    1202 <cram_md5_digest+0xe2>
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
sar    $0x4,%eax
and    $0xf,%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %eax,-0x74(%rbp)
jmp    1217 <cram_md5_digest+0xf7>
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
sar    $0x4,%eax
and    $0xf,%eax
add    $0x30,%eax
mov    %eax,-0x74(%rbp)
mov    -0x74(%rbp),%eax
mov    %al,%cl
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x28(%rbp)
mov    %cl,(%rax)
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
and    $0xf,%eax
cmp    $0x9,%eax
jle    125c <cram_md5_digest+0x13c>
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
and    $0xf,%eax
add    $0x61,%eax
sub    $0xa,%eax
mov    %eax,-0x78(%rbp)
jmp    126e <cram_md5_digest+0x14e>
mov    -0x48(%rbp),%rax
movsbl -0x40(%rbp,%rax,1),%eax
and    $0xf,%eax
add    $0x30,%eax
mov    %eax,-0x78(%rbp)
mov    -0x78(%rbp),%eax
mov    %al,%cl
mov    -0x28(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x28(%rbp)
mov    %cl,(%rax)
mov    -0x48(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x48(%rbp)
jmp    11c2 <cram_md5_digest+0xa2>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cram_md5_digest>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x10,%rsp
mov    %r8,%r14
mov    %rcx,%rbx
mov    %rdx,%r15
mov    %rsi,%r13
mov    %rdi,%r12
test   %rcx,%rcx
je     126a <cram_md5_digest+0x14a>
test   %r13,%r13
je     127e <cram_md5_digest+0x15e>
mov    %rsp,%r8
mov    %r15,%rdi
mov    %rbx,%rsi
mov    %r12,%rdx
mov    %r13,%rcx
call   1030 <gc_hmac_md5@plt>
movq   (%rsp),%xmm7
movdqa %xmm7,%xmm3
psrlw  $0x4,%xmm3
movdqa 0xe87(%rip),%xmm8
pand   %xmm8,%xmm3
movdqa 0xe8a(%rip),%xmm0
movdqa %xmm7,%xmm4
pminub %xmm0,%xmm4
pcmpeqb %xmm7,%xmm4
movdqa 0xe86(%rip),%xmm1
movdqa %xmm3,%xmm5
paddb  %xmm1,%xmm5
movdqa 0xe86(%rip),%xmm2
por    %xmm2,%xmm3
pand   %xmm4,%xmm3
pandn  %xmm5,%xmm4
por    %xmm3,%xmm4
movdqa 0xe7d(%rip),%xmm9
pand   %xmm9,%xmm7
movdqa 0xe80(%rip),%xmm3
movdqa %xmm7,%xmm6
pminub %xmm3,%xmm6
pcmpeqb %xmm7,%xmm6
movdqa %xmm7,%xmm5
paddb  %xmm1,%xmm5
por    %xmm2,%xmm7
pand   %xmm6,%xmm7
pandn  %xmm5,%xmm6
por    %xmm7,%xmm6
punpcklbw %xmm6,%xmm4
movdqu %xmm4,(%r14)
movq   0x8(%rsp),%xmm6
movdqa %xmm6,%xmm4
psrlw  $0x4,%xmm4
pand   %xmm8,%xmm4
pminub %xmm6,%xmm0
pcmpeqb %xmm6,%xmm0
movdqa %xmm4,%xmm5
paddb  %xmm1,%xmm5
por    %xmm2,%xmm4
pand   %xmm0,%xmm4
pandn  %xmm5,%xmm0
por    %xmm4,%xmm0
pand   %xmm9,%xmm6
pminub %xmm6,%xmm3
pcmpeqb %xmm6,%xmm3
paddb  %xmm6,%xmm1
por    %xmm2,%xmm6
pand   %xmm3,%xmm6
pandn  %xmm1,%xmm3
por    %xmm6,%xmm3
punpcklbw %xmm3,%xmm0
movdqu %xmm0,0x10(%r14)
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret
mov    %r15,%rdi
call   1040 <strlen@plt>
mov    %rax,%rbx
test   %r13,%r13
jne    114e <cram_md5_digest+0x2e>
mov    %r12,%rdi
call   1040 <strlen@plt>
mov    %rax,%r13
jmp    114e <cram_md5_digest+0x2e>

LLVM IR (-O0):
define void @cram_md5_digest(i8* %0, i64 %1, i8* %2, i64 %3, i8* %4) {
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i8*
%9 = alloca i64
%10 = alloca i8*
%11 = alloca [16 x i8]
%12 = alloca i64
store i8* %0, i8** %6
store i64 %1, i64* %7
store i8* %2, i8** %8
store i64 %3, i64* %9
store i8* %4, i8** %10
%13 = load i8*, i8** %8
%14 = load i64, i64* %9
%15 = icmp ne i64 %14, 0
br i1 %15, label %16, label %18
16: ; preds = %5
%17 = load i64, i64* %9
br label %21
18: ; preds = %5
%19 = load i8*, i8** %8
%20 = call i64 @strlen(i8* %19)
br label %21
21: ; preds = %18, %16
%22 = phi i64 [ %17, %16 ], [ %20, %18 ]
%23 = load i8*, i8** %6
%24 = load i64, i64* %7
%25 = icmp ne i64 %24, 0
br i1 %25, label %26, label %28
26: ; preds = %21
%27 = load i64, i64* %7
br label %31
28: ; preds = %21
%29 = load i8*, i8** %6
%30 = call i64 @strlen(i8* %29)
br label %31
31: ; preds = %28, %26
%32 = phi i64 [ %27, %26 ], [ %30, %28 ]
%33 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 0
%34 = call i32 @gc_hmac_md5(i8* %13, i64 %22, i8* %23, i64 %32, i8* %33)
store i64 0, i64* %12
br label %35
35: ; preds = %94, %31
%36 = load i64, i64* %12
%37 = icmp ult i64 %36, 16
br i1 %37, label %38, label %97
38: ; preds = %35
%39 = load i64, i64* %12
%40 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %39
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = ashr i32 %42, 4
%44 = and i32 %43, 15
%45 = icmp sgt i32 %44, 9
br i1 %45, label %46, label %55
46: ; preds = %38
%47 = load i64, i64* %12
%48 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %47
%49 = load i8, i8* %48
%50 = sext i8 %49 to i32
%51 = ashr i32 %50, 4
%52 = and i32 %51, 15
%53 = add nsw i32 97, %52
%54 = sub nsw i32 %53, 10
br label %63
55: ; preds = %38
%56 = load i64, i64* %12
%57 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %56
%58 = load i8, i8* %57
%59 = sext i8 %58 to i32
%60 = ashr i32 %59, 4
%61 = and i32 %60, 15
%62 = add nsw i32 48, %61
br label %63
63: ; preds = %55, %46
%64 = phi i32 [ %54, %46 ], [ %62, %55 ]
%65 = trunc i32 %64 to i8
%66 = load i8*, i8** %10
%67 = getelementptr inbounds i8, i8* %66, i32 1
store i8* %67, i8** %10
store i8 %65, i8* %66
%68 = load i64, i64* %12
%69 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %68
%70 = load i8, i8* %69
%71 = sext i8 %70 to i32
%72 = and i32 %71, 15
%73 = icmp sgt i32 %72, 9
br i1 %73, label %74, label %82
74: ; preds = %63
%75 = load i64, i64* %12
%76 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %75
%77 = load i8, i8* %76
%78 = sext i8 %77 to i32
%79 = and i32 %78, 15
%80 = add nsw i32 97, %79
%81 = sub nsw i32 %80, 10
br label %89
82: ; preds = %63
%83 = load i64, i64* %12
%84 = getelementptr inbounds [16 x i8], [16 x i8]* %11, i64 0, i64 %83
%85 = load i8, i8* %84
%86 = sext i8 %85 to i32
%87 = and i32 %86, 15
%88 = add nsw i32 48, %87
br label %89
89: ; preds = %82, %74
%90 = phi i32 [ %81, %74 ], [ %88, %82 ]
%91 = trunc i32 %90 to i8
%92 = load i8*, i8** %10
%93 = getelementptr inbounds i8, i8* %92, i32 1
store i8* %93, i8** %10
store i8 %91, i8* %92
br label %94
94: ; preds = %89
%95 = load i64, i64* %12
%96 = add i64 %95, 1
store i64 %96, i64* %12
br label %35
97: ; preds = %35
ret void
}

LLVM IR (-O2):
define void @cram_md5_digest(i8* %0, i64 %1, i8* %2, i64 %3, i8* nocapture writeonly %4) {
%6 = alloca [16 x i8]
%7 = getelementptr inbounds [16 x i8], [16 x i8]* %6, i64 0, i64 0
%8 = icmp eq i64 %3, 0
br i1 %8, label %9, label %11
9: ; preds = %5
%10 = tail call i64 @strlen(i8* dereferenceable(1) %2)
br label %11
11: ; preds = %5, %9
%12 = phi i64 [ %10, %9 ], [ %3, %5 ]
%13 = icmp eq i64 %1, 0
br i1 %13, label %14, label %16
14: ; preds = %11
%15 = tail call i64 @strlen(i8* dereferenceable(1) %0)
br label %16
16: ; preds = %11, %14
%17 = phi i64 [ %15, %14 ], [ %1, %11 ]
%18 = call i32 @gc_hmac_md5(i8* %2, i64 %12, i8* %0, i64 %17, i8* %7)
%19 = bitcast [16 x i8]* %6 to <8 x i8>*
%20 = load <8 x i8>, <8 x i8>* %19
%21 = lshr <8 x i8> %20, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%22 = icmp ugt <8 x i8> %20, <i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97>
%23 = add nuw nsw <8 x i8> %21, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%24 = or <8 x i8> %21, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%25 = select <8 x i1> %22, <8 x i8> %23, <8 x i8> %24
%26 = and <8 x i8> %20, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%27 = icmp ugt <8 x i8> %26, <i8 9, i8 9, i8 9, i8 9, i8 9, i8 9, i8 9, i8 9>
%28 = add nuw nsw <8 x i8> %26, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%29 = or <8 x i8> %26, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%30 = select <8 x i1> %27, <8 x i8> %28, <8 x i8> %29
%31 = bitcast i8* %4 to <16 x i8>*
%32 = shufflevector <8 x i8> %25, <8 x i8> %30, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %32, <16 x i8>* %31
%33 = getelementptr inbounds [16 x i8], [16 x i8]* %6, i64 0, i64 8
%34 = bitcast i8* %33 to <8 x i8>*
%35 = load <8 x i8>, <8 x i8>* %34
%36 = lshr <8 x i8> %35, <i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4, i8 4>
%37 = icmp ugt <8 x i8> %35, <i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97, i8 -97>
%38 = add nuw nsw <8 x i8> %36, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%39 = or <8 x i8> %36, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%40 = select <8 x i1> %37, <8 x i8> %38, <8 x i8> %39
%41 = and <8 x i8> %35, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%42 = icmp ugt <8 x i8> %41, <i8 9, i8 9, i8 9, i8 9, i8 9, i8 9, i8 9, i8 9>
%43 = add nuw nsw <8 x i8> %41, <i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87, i8 87>
%44 = or <8 x i8> %41, <i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48, i8 48>
%45 = select <8 x i1> %42, <8 x i8> %43, <8 x i8> %44
%46 = getelementptr inbounds i8, i8* %4, i64 16
%47 = bitcast i8* %46 to <16 x i8>*
%48 = shufflevector <8 x i8> %40, <8 x i8> %45, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
store <16 x i8> %48, <16 x i8>* %47
ret void
}