#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*/ processBlock(unsigned char *, unsigned char *,
                                unsigned char *);
void sha1(const unsigned char message[], unsigned char length,
          unsigned char out[]) {
  unsigned char old[] = {0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB,
                         0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32,
                         0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0};
  unsigned char lenght_low = 0;
  unsigned char lenght_high = 0;
  unsigned char index = 0;
  unsigned char message_block[64];
  for (unsigned char i = 0; i < length; i++) {
    message_block[index++] = message[i];
    lenght_low += 8;
    if (lenght_low == 0) {
      lenght_high++;
    }
    if (index == 64) {
      processBlock(old, out, message_block);
      for (unsigned char i = 0; i < 20; i++) {
        old[i] = out[i];
      }
      index = 0;
    }
  }
  message_block[index++] = 0x80;
  if (index > 55) {
    while (index < 64) {
      message_block[index++] = 0;
    }
    processBlock(old, out, message_block);
    for (unsigned char i = 0; i < 20; i++) {
      old[i] = out[i];
    }
    index = 0;
  }
  while (index < 62) {
    message_block[index++] = 0;
  }
  message_block[62] = lenght_high;
  message_block[63] = lenght_low;
  processBlock(old, out, message_block);
}


x86 assembly (clang, -O0):
<sha1>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %sil,%al
mov    %rdi,-0x8(%rbp)
mov    %al,-0x9(%rbp)
mov    %rdx,-0x18(%rbp)
mov    0xed0(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xecd(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xecb(%rip),%eax
mov    %eax,-0x20(%rbp)
movb   $0x0,-0x31(%rbp)
movb   $0x0,-0x32(%rbp)
movb   $0x0,-0x33(%rbp)
movb   $0x0,-0x81(%rbp)
movzbl -0x81(%rbp),%eax
movzbl -0x9(%rbp),%ecx
cmp    %ecx,%eax
jge    122a <sha1+0x11a>
mov    -0x8(%rbp),%rax
movzbl -0x81(%rbp),%ecx
mov    (%rax,%rcx,1),%cl
mov    -0x33(%rbp),%al
mov    %al,%dl
add    $0x1,%dl
mov    %dl,-0x33(%rbp)
movzbl %al,%eax
mov    %cl,-0x80(%rbp,%rax,1)
movzbl -0x31(%rbp),%eax
add    $0x8,%eax
mov    %al,-0x31(%rbp)
movzbl -0x31(%rbp),%eax
cmp    $0x0,%eax
jne    11ad <sha1+0x9d>
mov    -0x32(%rbp),%al
add    $0x1,%al
mov    %al,-0x32(%rbp)
movzbl -0x33(%rbp),%eax
cmp    $0x40,%eax
jne    1212 <sha1+0x102>
lea    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
lea    -0x80(%rbp),%rdx
call   1030 <processBlock@plt>
movb   $0x0,-0x82(%rbp)
movzbl -0x82(%rbp),%eax
cmp    $0x14,%eax
jge    120e <sha1+0xfe>
mov    -0x18(%rbp),%rax
movzbl -0x82(%rbp),%ecx
mov    (%rax,%rcx,1),%cl
movzbl -0x82(%rbp),%eax
mov    %cl,-0x30(%rbp,%rax,1)
mov    -0x82(%rbp),%al
add    $0x1,%al
mov    %al,-0x82(%rbp)
jmp    11d2 <sha1+0xc2>
movb   $0x0,-0x33(%rbp)
jmp    1217 <sha1+0x107>
mov    -0x81(%rbp),%al
add    $0x1,%al
mov    %al,-0x81(%rbp)
jmp    115b <sha1+0x4b>
mov    -0x33(%rbp),%al
mov    %al,%cl
add    $0x1,%cl
mov    %cl,-0x33(%rbp)
movzbl %al,%eax
movb   $0x80,-0x80(%rbp,%rax,1)
movzbl -0x33(%rbp),%eax
cmp    $0x37,%eax
jle    12cc <sha1+0x1bc>
jmp    124f <sha1+0x13f>
movzbl -0x33(%rbp),%eax
cmp    $0x40,%eax
jge    1274 <sha1+0x164>
mov    -0x33(%rbp),%al
mov    %al,%cl
add    $0x1,%cl
mov    %cl,-0x33(%rbp)
movzbl %al,%eax
movb   $0x0,-0x80(%rbp,%rax,1)
jmp    124f <sha1+0x13f>
lea    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
lea    -0x80(%rbp),%rdx
call   1030 <processBlock@plt>
movb   $0x0,-0x83(%rbp)
movzbl -0x83(%rbp),%eax
cmp    $0x14,%eax
jge    12c8 <sha1+0x1b8>
mov    -0x18(%rbp),%rax
movzbl -0x83(%rbp),%ecx
mov    (%rax,%rcx,1),%cl
movzbl -0x83(%rbp),%eax
mov    %cl,-0x30(%rbp,%rax,1)
mov    -0x83(%rbp),%al
add    $0x1,%al
mov    %al,-0x83(%rbp)
jmp    128c <sha1+0x17c>
movb   $0x0,-0x33(%rbp)
jmp    12d1 <sha1+0x1c1>
movzbl -0x33(%rbp),%eax
cmp    $0x3e,%eax
jge    12f6 <sha1+0x1e6>
mov    -0x33(%rbp),%al
mov    %al,%cl
add    $0x1,%cl
mov    %cl,-0x33(%rbp)
movzbl %al,%eax
movb   $0x0,-0x80(%rbp,%rax,1)
jmp    12d1 <sha1+0x1c1>
mov    -0x32(%rbp),%al
mov    %al,-0x42(%rbp)
mov    -0x31(%rbp),%al
mov    %al,-0x41(%rbp)
lea    -0x30(%rbp),%rdi
mov    -0x18(%rbp),%rsi
lea    -0x80(%rbp),%rdx
call   1030 <processBlock@plt>
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sha1>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x78,%rsp
mov    %rdx,%r13
movaps 0xec8(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movl   $0xf0e1d2c3,0x20(%rsp)
f0
test   %esi,%esi
je     1223 <sha1+0x103>
mov    %rdi,%rbp
mov    %esi,0xc(%rsp)
movzbl %sil,%r14d
shl    $0x3,%r14
xor    %r15d,%r15d
xor    %eax,%eax
xor    %ebx,%ebx
jmp    1180 <sha1+0x60>
cs nopw 0x0(%rax,%rax,1)
nop
add    %r12b,%bl
add    $0x1,%rbp
add    $0x8,%r15
cmp    %r15,%r14
je     11c1 <sha1+0xa1>
movzbl 0x0(%rbp),%ecx
movzbl %al,%edx
add    $0x1,%al
mov    %cl,0x30(%rsp,%rdx,1)
cmp    $0xf8,%r15b
sete   %r12b
cmp    $0x40,%al
jne    1170 <sha1+0x50>
lea    0x10(%rsp),%rdi
mov    %r13,%rsi
lea    0x30(%rsp),%rdx
call   1040 <processBlock@plt>
movups 0x0(%r13),%xmm0
movaps %xmm0,0x10(%rsp)
mov    0x10(%r13),%eax
mov    %eax,0x20(%rsp)
xor    %eax,%eax
jmp    1170 <sha1+0x50>
mov    0xc(%rsp),%ebp
shl    $0x3,%bpl
lea    0x1(%rax),%ecx
movzbl %al,%edx
movb   $0x80,0x30(%rsp,%rdx,1)
cmp    $0x38,%cl
jb     122e <sha1+0x10e>
cmp    $0x3f,%cl
ja     11fb <sha1+0xdb>
movzbl %cl,%ecx
lea    (%rsp,%rcx,1),%rdi
add    $0x30,%rdi
mov    $0x3e,%cl
sub    %al,%cl
movzbl %cl,%edx
add    $0x1,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
lea    0x10(%rsp),%rdi
lea    0x30(%rsp),%rdx
mov    %r13,%rsi
call   1040 <processBlock@plt>
movups 0x0(%r13),%xmm0
movaps %xmm0,0x10(%rsp)
mov    0x10(%r13),%eax
mov    %eax,0x20(%rsp)
xor    %ecx,%ecx
jmp    122e <sha1+0x10e>
movb   $0x80,0x30(%rsp)
mov    $0x1,%cl
xor    %ebx,%ebx
xor    %ebp,%ebp
movzbl %cl,%eax
lea    (%rsp,%rax,1),%rdi
add    $0x30,%rdi
mov    $0x3d,%cl
sub    %al,%cl
movzbl %cl,%edx
add    $0x1,%rdx
xor    %esi,%esi
call   1030 <memset@plt>
mov    %bl,0x6e(%rsp)
mov    %bpl,0x6f(%rsp)
lea    0x10(%rsp),%rdi
lea    0x30(%rsp),%rdx
mov    %r13,%rsi
call   1040 <processBlock@plt>
add    $0x78,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.sha1.old = [20 x i8] c"gE#\01\EF\CD\AB\89\98\BA\DC\FE\102Tv\C3\D2\E1\F0"
define void @sha1(i8* %0, i8 zeroext %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8
%6 = alloca i8*
%7 = alloca [20 x i8]
%8 = alloca i8
%9 = alloca i8
%10 = alloca i8
%11 = alloca [64 x i8]
%12 = alloca i8
%13 = alloca i8
%14 = alloca i8
store i8* %0, i8** %4
store i8 %1, i8* %5
store i8* %2, i8** %6
%15 = bitcast [20 x i8]* %7 to i8*
store i8 0, i8* %8
store i8 0, i8* %9
store i8 0, i8* %10
store i8 0, i8* %12
br label %16
16: ; preds = %69, %3
%17 = load i8, i8* %12
%18 = zext i8 %17 to i32
%19 = load i8, i8* %5
%20 = zext i8 %19 to i32
%21 = icmp slt i32 %18, %20
br i1 %21, label %22, label %72
22: ; preds = %16
%23 = load i8*, i8** %4
%24 = load i8, i8* %12
%25 = zext i8 %24 to i64
%26 = getelementptr inbounds i8, i8* %23, i64 %25
%27 = load i8, i8* %26
%28 = load i8, i8* %10
%29 = add i8 %28, 1
store i8 %29, i8* %10
%30 = zext i8 %28 to i64
%31 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 %30
store i8 %27, i8* %31
%32 = load i8, i8* %8
%33 = zext i8 %32 to i32
%34 = add nsw i32 %33, 8
%35 = trunc i32 %34 to i8
store i8 %35, i8* %8
%36 = load i8, i8* %8
%37 = zext i8 %36 to i32
%38 = icmp eq i32 %37, 0
br i1 %38, label %39, label %42
39: ; preds = %22
%40 = load i8, i8* %9
%41 = add i8 %40, 1
store i8 %41, i8* %9
br label %42
42: ; preds = %39, %22
%43 = load i8, i8* %10
%44 = zext i8 %43 to i32
%45 = icmp eq i32 %44, 64
br i1 %45, label %46, label %68
46: ; preds = %42
%47 = getelementptr inbounds [20 x i8], [20 x i8]* %7, i64 0, i64 0
%48 = load i8*, i8** %6
%49 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 0
%50 = call i32 @processBlock(i8* %47, i8* %48, i8* %49)
store i8 0, i8* %13
br label %51
51: ; preds = %64, %46
%52 = load i8, i8* %13
%53 = zext i8 %52 to i32
%54 = icmp slt i32 %53, 20
br i1 %54, label %55, label %67
55: ; preds = %51
%56 = load i8*, i8** %6
%57 = load i8, i8* %13
%58 = zext i8 %57 to i64
%59 = getelementptr inbounds i8, i8* %56, i64 %58
%60 = load i8, i8* %59
%61 = load i8, i8* %13
%62 = zext i8 %61 to i64
%63 = getelementptr inbounds [20 x i8], [20 x i8]* %7, i64 0, i64 %62
store i8 %60, i8* %63
br label %64
64: ; preds = %55
%65 = load i8, i8* %13
%66 = add i8 %65, 1
store i8 %66, i8* %13
br label %51
67: ; preds = %51
store i8 0, i8* %10
br label %68
68: ; preds = %67, %42
br label %69
69: ; preds = %68
%70 = load i8, i8* %12
%71 = add i8 %70, 1
store i8 %71, i8* %12
br label %16
72: ; preds = %16
%73 = load i8, i8* %10
%74 = add i8 %73, 1
store i8 %74, i8* %10
%75 = zext i8 %73 to i64
%76 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 %75
store i8 -128, i8* %76
%77 = load i8, i8* %10
%78 = zext i8 %77 to i32
%79 = icmp sgt i32 %78, 55
br i1 %79, label %80, label %112
80: ; preds = %72
br label %81
81: ; preds = %85, %80
%82 = load i8, i8* %10
%83 = zext i8 %82 to i32
%84 = icmp slt i32 %83, 64
br i1 %84, label %85, label %90
85: ; preds = %81
%86 = load i8, i8* %10
%87 = add i8 %86, 1
store i8 %87, i8* %10
%88 = zext i8 %86 to i64
%89 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 %88
store i8 0, i8* %89
br label %81
90: ; preds = %81
%91 = getelementptr inbounds [20 x i8], [20 x i8]* %7, i64 0, i64 0
%92 = load i8*, i8** %6
%93 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 0
%94 = call i32 @processBlock(i8* %91, i8* %92, i8* %93)
store i8 0, i8* %14
br label %95
95: ; preds = %108, %90
%96 = load i8, i8* %14
%97 = zext i8 %96 to i32
%98 = icmp slt i32 %97, 20
br i1 %98, label %99, label %111
99: ; preds = %95
%100 = load i8*, i8** %6
%101 = load i8, i8* %14
%102 = zext i8 %101 to i64
%103 = getelementptr inbounds i8, i8* %100, i64 %102
%104 = load i8, i8* %103
%105 = load i8, i8* %14
%106 = zext i8 %105 to i64
%107 = getelementptr inbounds [20 x i8], [20 x i8]* %7, i64 0, i64 %106
store i8 %104, i8* %107
br label %108
108: ; preds = %99
%109 = load i8, i8* %14
%110 = add i8 %109, 1
store i8 %110, i8* %14
br label %95
111: ; preds = %95
store i8 0, i8* %10
br label %112
112: ; preds = %111, %72
br label %113
113: ; preds = %117, %112
%114 = load i8, i8* %10
%115 = zext i8 %114 to i32
%116 = icmp slt i32 %115, 62
br i1 %116, label %117, label %122
117: ; preds = %113
%118 = load i8, i8* %10
%119 = add i8 %118, 1
store i8 %119, i8* %10
%120 = zext i8 %118 to i64
%121 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 %120
store i8 0, i8* %121
br label %113
122: ; preds = %113
%123 = load i8, i8* %9
%124 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 62
store i8 %123, i8* %124
%125 = load i8, i8* %8
%126 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 63
store i8 %125, i8* %126
%127 = getelementptr inbounds [20 x i8], [20 x i8]* %7, i64 0, i64 0
%128 = load i8*, i8** %6
%129 = getelementptr inbounds [64 x i8], [64 x i8]* %11, i64 0, i64 0
%130 = call i32 @processBlock(i8* %127, i8* %128, i8* %129)
ret void
}

LLVM IR (-O2):
@__const.sha1.old = [20 x i8] c"gE#\01\EF\CD\AB\89\98\BA\DC\FE\102Tv\C3\D2\E1\F0"
define void @sha1(i8* nocapture %0, i8 zeroext %1, i8* %2) {
%4 = alloca [20 x i8]
%5 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%6 = alloca [64 x i8]
%7 = getelementptr inbounds [20 x i8], [20 x i8]* %4, i64 0, i64 0
%8 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 0
%9 = icmp eq i8 %1, 0
br i1 %9, label %10, label %12
10: ; preds = %3
%11 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 0
store i8 -128, i8* %11
br label %51
12: ; preds = %3
%13 = zext i8 %1 to i64
br label %28
14: ; preds = %45
%15 = shl i8 %1, 3
%16 = add i8 %46, 1
%17 = zext i8 %46 to i64
%18 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 %17
store i8 -128, i8* %18
%19 = icmp ugt i8 %16, 55
br i1 %19, label %20, label %51
20: ; preds = %14
%21 = icmp ult i8 %16, 64
br i1 %21, label %22, label %49
22: ; preds = %20
%23 = zext i8 %16 to i64
%24 = getelementptr [64 x i8], [64 x i8]* %6, i64 0, i64 %23
%25 = sub nuw nsw i8 62, %46
%26 = zext i8 %25 to i64
%27 = add nuw nsw i64 %26, 1
br label %49
28: ; preds = %12, %45
%29 = phi i64 [ 0, %12 ], [ %47, %45 ]
%30 = phi i8 [ 0, %12 ], [ %46, %45 ]
%31 = phi i8 [ 0, %12 ], [ %41, %45 ]
%32 = phi i8 [ 0, %12 ], [ %38, %45 ]
%33 = getelementptr inbounds i8, i8* %0, i64 %29
%34 = load i8, i8* %33
%35 = add i8 %30, 1
%36 = zext i8 %30 to i64
%37 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 %36
store i8 %34, i8* %37
%38 = add i8 %32, 8
%39 = icmp eq i8 %38, 0
%40 = zext i1 %39 to i8
%41 = add i8 %31, %40
%42 = icmp eq i8 %35, 64
br i1 %42, label %43, label %45
43: ; preds = %28
%44 = call i32 @processBlock(i8* %7, i8* %2, i8* %8)
br label %45
45: ; preds = %43, %28
%46 = phi i8 [ %35, %28 ], [ 0, %43 ]
%47 = add nuw nsw i64 %29, 1
%48 = icmp eq i64 %47, %13
br i1 %48, label %14, label %28
49: ; preds = %22, %20
%50 = call i32 @processBlock(i8* %7, i8* %2, i8* %8)
br label %51
51: ; preds = %10, %49, %14
%52 = phi i8 [ %41, %14 ], [ %41, %49 ], [ 0, %10 ]
%53 = phi i8 [ %15, %14 ], [ %15, %49 ], [ 0, %10 ]
%54 = phi i8 [ %16, %14 ], [ 0, %49 ], [ 1, %10 ]
%55 = zext i8 %54 to i64
%56 = getelementptr [64 x i8], [64 x i8]* %6, i64 0, i64 %55
%57 = sub nuw nsw i8 61, %54
%58 = zext i8 %57 to i64
%59 = add nuw nsw i64 %58, 1
%60 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 62
store i8 %52, i8* %60
%61 = getelementptr inbounds [64 x i8], [64 x i8]* %6, i64 0, i64 63
store i8 %53, i8* %61
%62 = call i32 @processBlock(i8* %7, i8* %2, i8* %8)
ret void
}