#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;
typedef int /*<<< orphan*/ out1;

/* Variables and functions */
int /*<<< orphan*/ curve25519_donna(int *, int const *, int const *);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *);
scalar_t__ memcmp(int *, int *, int);
int /*<<< orphan*/ stderr;
int main() {
  static const uint8_t point1[32] = {
      0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  };
  static const uint8_t point2[32] = {
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  };
  static const uint8_t scalar[32] = {1};
  uint8_t out1[32], out2[32];
  curve25519_donna(out1, scalar, point1);
  curve25519_donna(out2, scalar, point2);
  if (0 == memcmp(out1, out2, sizeof(out1))) {
    fprintf(stderr, "Top bit not ignored.\n");
    return 1;
  }
  fprintf(stderr, "Top bit correctly ignored.\n");
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x110,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x90(%rbp),%rdi
lea    0xfb0(%rip),%rsi
lea    0xea9(%rip),%rdx
call   1030 <curve25519_donna@plt>
lea    -0x110(%rbp),%rdi
lea    0xf96(%rip),%rsi
lea    0xf0f(%rip),%rdx
call   1030 <curve25519_donna@plt>
lea    -0x90(%rbp),%rdi
lea    -0x110(%rbp),%rsi
mov    $0x80,%edx
call   1040 <memcmp@plt>
mov    %rax,%rcx
xor    %eax,%eax
cmp    %rcx,%rax
jne    11bd <main+0x8d>
mov    0x2e3d(%rip),%rax
mov    (%rax),%edi
lea    0xfd4(%rip),%rsi
call   1050 <fprintf@plt>
movl   $0x1,-0x4(%rbp)
jmp    11d9 <main+0xa9>
mov    0x2e1c(%rip),%rax
mov    (%rax),%edi
lea    0xfc9(%rip),%rsi
call   1050 <fprintf@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x110,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r15
push   %r14
push   %rbx
sub    $0x100,%rsp
lea    0xfbd(%rip),%r15
lea    0xeb6(%rip),%rdx
lea    0x80(%rsp),%r14
mov    %r14,%rdi
mov    %r15,%rsi
call   1030 <curve25519_donna@plt>
lea    0xf1c(%rip),%rdx
mov    %rsp,%rbx
mov    %rbx,%rdi
mov    %r15,%rsi
call   1030 <curve25519_donna@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x80,%edx
call   1040 <memcmp@plt>
xor    %ebx,%ebx
test   %rax,%rax
sete   %bl
mov    0x2e4f(%rip),%rax
mov    (%rax),%edi
lea    0xfe6(%rip),%rax
lea    0xff5(%rip),%rsi
cmove  %rax,%rsi
call   1050 <fprintf@plt>
mov    %ebx,%eax
add    $0x100,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@main.point1 = internal constant <{ i32, [31 x i32] }> <{ i32 37, [31 x i32] zeroinitializer }>
@main.point2 = internal constant [32 x i32] [i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255]
@main.scalar = internal constant <{ i32, [31 x i32] }> <{ i32 1, [31 x i32] zeroinitializer }>
@stderr = global i32 0
@.str = [22 x i8] c"Top bit not ignored.\0A\00"
@.str.1 = [28 x i8] c"Top bit correctly ignored.\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [32 x i32]
%3 = alloca [32 x i32]
store i32 0, i32* %1
%4 = getelementptr inbounds [32 x i32], [32 x i32]* %2, i64 0, i64 0
%5 = call i32 @curve25519_donna(i32* %4, i32* getelementptr inbounds ([32 x i32], [32 x i32]* bitcast (<{ i32, [31 x i32] }>* @main.scalar to [32 x i32]*), i64 0, i64 0), i32* getelementptr inbounds ([32 x i32], [32 x i32]* bitcast (<{ i32, [31 x i32] }>* @main.point1 to [32 x i32]*), i64 0, i64 0))
%6 = getelementptr inbounds [32 x i32], [32 x i32]* %3, i64 0, i64 0
%7 = call i32 @curve25519_donna(i32* %6, i32* getelementptr inbounds ([32 x i32], [32 x i32]* bitcast (<{ i32, [31 x i32] }>* @main.scalar to [32 x i32]*), i64 0, i64 0), i32* getelementptr inbounds ([32 x i32], [32 x i32]* @main.point2, i64 0, i64 0))
%8 = getelementptr inbounds [32 x i32], [32 x i32]* %2, i64 0, i64 0
%9 = getelementptr inbounds [32 x i32], [32 x i32]* %3, i64 0, i64 0
%10 = call i64 @memcmp(i32* %8, i32* %9, i32 128)
%11 = icmp eq i64 0, %10
br i1 %11, label %12, label %15
12: ; preds = %0
%13 = load i32, i32* @stderr
%14 = call i32 @fprintf(i32 %13, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0))
store i32 1, i32* %1
br label %18
15: ; preds = %0
%16 = load i32, i32* @stderr
%17 = call i32 @fprintf(i32 %16, i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0))
store i32 0, i32* %1
br label %18
18: ; preds = %15, %12
%19 = load i32, i32* %1
ret i32 %19
}

LLVM IR (-O2):
@main.point1 = internal constant <{ i32, [31 x i32] }> <{ i32 37, [31 x i32] zeroinitializer }>
@main.point2 = internal constant [32 x i32] [i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255, i32 255]
@main.scalar = internal constant <{ i32, [31 x i32] }> <{ i32 1, [31 x i32] zeroinitializer }>
@stderr = global i32 0
@.str = [22 x i8] c"Top bit not ignored.\0A\00"
@.str.1 = [28 x i8] c"Top bit correctly ignored.\0A\00"
define i32 @main() {
%1 = alloca [32 x i32]
%2 = alloca [32 x i32]
%3 = bitcast [32 x i32]* %1 to i8*
%4 = bitcast [32 x i32]* %2 to i8*
%5 = getelementptr inbounds [32 x i32], [32 x i32]* %1, i64 0, i64 0
%6 = call i32 @curve25519_donna(i32* %5, i32* getelementptr inbounds (<{ i32, [31 x i32] }>, <{ i32, [31 x i32] }>* @main.scalar, i64 0, i32 0), i32* getelementptr inbounds (<{ i32, [31 x i32] }>, <{ i32, [31 x i32] }>* @main.point1, i64 0, i32 0))
%7 = getelementptr inbounds [32 x i32], [32 x i32]* %2, i64 0, i64 0
%8 = call i32 @curve25519_donna(i32* %7, i32* getelementptr inbounds (<{ i32, [31 x i32] }>, <{ i32, [31 x i32] }>* @main.scalar, i64 0, i32 0), i32* getelementptr inbounds ([32 x i32], [32 x i32]* @main.point2, i64 0, i64 0))
%9 = call i64 @memcmp(i32* %5, i32* %7, i32 128)
%10 = icmp eq i64 %9, 0
%11 = load i32, i32* @stderr
%12 = select i1 %10, i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i64 0, i64 0), i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.str.1, i64 0, i64 0)
%13 = zext i1 %10 to i32
%14 = call i32 @fprintf(i32 %11, i8* %12)
ret i32 %13
}