#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 /*<<< orphan*/ EC_POINT;
typedef int /*<<< orphan*/ EC_KEY;
typedef int /*<<< orphan*/ EC_GROUP;
typedef int /*<<< orphan*/ BIGNUM;

/* Variables and functions */
int /*<<< orphan*/ *BN_bin2bn(unsigned char const *, size_t,
                              int /*<<< orphan*/ *);
int /*<<< orphan*/ BN_clear_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_KEY_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ *EC_KEY_get0_group(int /*<<< orphan*/ *);
int /*<<< orphan*/ *EC_KEY_new_by_curve_name(int);
int /*<<< orphan*/ EC_KEY_set_private_key(int /*<<< orphan*/ *,
                                          int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_KEY_set_public_key(int /*<<< orphan*/ *,
                                         int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_POINT_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_POINT_mul(int /*<<< orphan*/ const *,
                                int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                                int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                                int /*<<< orphan*/ *);
int /*<<< orphan*/ *EC_POINT_new(int /*<<< orphan*/ const *);
EC_KEY *mk_eckey(int nid, const unsigned char *p, size_t plen) {
  int ok = 0;
  EC_KEY *k = NULL;
  BIGNUM *priv = NULL;
  EC_POINT *pub = NULL;
  const EC_GROUP *grp;
  k = EC_KEY_new_by_curve_name(nid);
  if (!k)
    goto err;
  priv = BN_bin2bn(p, plen, NULL);
  if (!priv)
    goto err;
  if (!EC_KEY_set_private_key(k, priv))
    goto err;
  grp = EC_KEY_get0_group(k);
  pub = EC_POINT_new(grp);
  if (!pub)
    goto err;
  if (!EC_POINT_mul(grp, pub, priv, NULL, NULL, NULL))
    goto err;
  if (!EC_KEY_set_public_key(k, pub))
    goto err;
  ok = 1;
err:
  if (priv)
    BN_clear_free(priv);
  if (pub)
    EC_POINT_free(pub);
  if (ok)
    return k;
  else if (k)
    EC_KEY_free(k);
  return NULL;
}


x86 assembly (clang, -O0):
<mk_eckey>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movq   $0x0,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
mov    -0xc(%rbp),%edi
call   10c0 <EC_KEY_new_by_curve_name@plt>
mov    %rax,-0x30(%rbp)
cmpq   $0x0,-0x30(%rbp)
jne    11ee <mk_eckey+0x4e>
jmp    12a4 <mk_eckey+0x104>
mov    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
xor    %eax,%eax
mov    %eax,%edx
call   1050 <BN_bin2bn@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
jne    1213 <mk_eckey+0x73>
jmp    12a4 <mk_eckey+0x104>
mov    -0x30(%rbp),%rdi
mov    -0x38(%rbp),%rsi
call   1060 <EC_KEY_set_private_key@plt>
cmp    $0x0,%eax
jne    122e <mk_eckey+0x8e>
jmp    12a4 <mk_eckey+0x104>
mov    -0x30(%rbp),%rdi
call   1070 <EC_KEY_get0_group@plt>
mov    %rax,-0x48(%rbp)
mov    -0x48(%rbp),%rdi
call   10b0 <EC_POINT_new@plt>
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
jne    1258 <mk_eckey+0xb8>
jmp    12a4 <mk_eckey+0x104>
mov    -0x48(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x38(%rbp),%rdx
xor    %eax,%eax
mov    %eax,%r9d
mov    %r9,%rcx
mov    %r9,%r8
call   1040 <EC_POINT_mul@plt>
cmp    $0x0,%eax
jne    1282 <mk_eckey+0xe2>
jmp    12a4 <mk_eckey+0x104>
mov    -0x30(%rbp),%rdi
mov    -0x40(%rbp),%rsi
call   1030 <EC_KEY_set_public_key@plt>
cmp    $0x0,%eax
jne    129d <mk_eckey+0xfd>
jmp    12a4 <mk_eckey+0x104>
movl   $0x1,-0x24(%rbp)
cmpq   $0x0,-0x38(%rbp)
je     12b8 <mk_eckey+0x118>
mov    -0x38(%rbp),%rdi
call   1090 <BN_clear_free@plt>
cmpq   $0x0,-0x40(%rbp)
je     12cc <mk_eckey+0x12c>
mov    -0x40(%rbp),%rdi
call   10a0 <EC_POINT_free@plt>
cmpl   $0x0,-0x24(%rbp)
je     12e3 <mk_eckey+0x143>
mov    -0x30(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    1304 <mk_eckey+0x164>
cmpq   $0x0,-0x30(%rbp)
je     12f7 <mk_eckey+0x157>
mov    -0x30(%rbp),%rdi
call   1080 <EC_KEY_free@plt>
jmp    12fc <mk_eckey+0x15c>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mk_eckey>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdx,%r14
mov    %rsi,%rbx
call   10c0 <EC_KEY_new_by_curve_name@plt>
test   %rax,%rax
je     1262 <mk_eckey+0xc2>
mov    %rax,%r13
mov    %rbx,%rdi
mov    %r14,%rsi
xor    %edx,%edx
call   1050 <BN_bin2bn@plt>
test   %rax,%rax
je     125a <mk_eckey+0xba>
mov    %rax,%r14
mov    %r13,%rdi
mov    %rax,%rsi
call   1060 <EC_KEY_set_private_key@plt>
test   %eax,%eax
je     1240 <mk_eckey+0xa0>
mov    %r13,%rdi
call   1070 <EC_KEY_get0_group@plt>
mov    %rax,%r12
mov    %rax,%rdi
call   10b0 <EC_POINT_new@plt>
test   %rax,%rax
je     1240 <mk_eckey+0xa0>
mov    %rax,%r15
mov    %r12,%rdi
mov    %rax,%rsi
mov    %r14,%rdx
xor    %ecx,%ecx
xor    %r8d,%r8d
xor    %r9d,%r9d
call   1040 <EC_POINT_mul@plt>
test   %eax,%eax
je     124a <mk_eckey+0xaa>
mov    %r13,%rdi
mov    %r15,%rsi
call   1030 <EC_KEY_set_public_key@plt>
mov    %eax,%ebx
mov    %r14,%rdi
call   1090 <BN_clear_free@plt>
mov    %r15,%rdi
call   10a0 <EC_POINT_free@plt>
test   %ebx,%ebx
jne    1265 <mk_eckey+0xc5>
jmp    125a <mk_eckey+0xba>
mov    %r14,%rdi
call   1090 <BN_clear_free@plt>
jmp    125a <mk_eckey+0xba>
mov    %r14,%rdi
call   1090 <BN_clear_free@plt>
mov    %r15,%rdi
call   10a0 <EC_POINT_free@plt>
mov    %r13,%rdi
call   1080 <EC_KEY_free@plt>
xor    %r13d,%r13d
mov    %r13,%rax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i32* @mk_eckey(i32 %0, i8* %1, i64 %2) {
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i32
%9 = alloca i32*
%10 = alloca i32*
%11 = alloca i32*
%12 = alloca i32*
store i32 %0, i32* %5
store i8* %1, i8** %6
store i64 %2, i64* %7
store i32 0, i32* %8
store i32* null, i32** %9
store i32* null, i32** %10
store i32* null, i32** %11
%13 = load i32, i32* %5
%14 = call i32* @EC_KEY_new_by_curve_name(i32 %13)
store i32* %14, i32** %9
%15 = load i32*, i32** %9
%16 = icmp ne i32* %15, null
br i1 %16, label %18, label %17
17: ; preds = %3
br label %53
18: ; preds = %3
%19 = load i8*, i8** %6
%20 = load i64, i64* %7
%21 = call i32* @BN_bin2bn(i8* %19, i64 %20, i32* null)
store i32* %21, i32** %10
%22 = load i32*, i32** %10
%23 = icmp ne i32* %22, null
br i1 %23, label %25, label %24
24: ; preds = %18
br label %53
25: ; preds = %18
%26 = load i32*, i32** %9
%27 = load i32*, i32** %10
%28 = call i32 @EC_KEY_set_private_key(i32* %26, i32* %27)
%29 = icmp ne i32 %28, 0
br i1 %29, label %31, label %30
30: ; preds = %25
br label %53
31: ; preds = %25
%32 = load i32*, i32** %9
%33 = call i32* @EC_KEY_get0_group(i32* %32)
store i32* %33, i32** %12
%34 = load i32*, i32** %12
%35 = call i32* @EC_POINT_new(i32* %34)
store i32* %35, i32** %11
%36 = load i32*, i32** %11
%37 = icmp ne i32* %36, null
br i1 %37, label %39, label %38
38: ; preds = %31
br label %53
39: ; preds = %31
%40 = load i32*, i32** %12
%41 = load i32*, i32** %11
%42 = load i32*, i32** %10
%43 = call i32 @EC_POINT_mul(i32* %40, i32* %41, i32* %42, i32* null, i32* null, i32* null)
%44 = icmp ne i32 %43, 0
br i1 %44, label %46, label %45
45: ; preds = %39
br label %53
46: ; preds = %39
%47 = load i32*, i32** %9
%48 = load i32*, i32** %11
%49 = call i32 @EC_KEY_set_public_key(i32* %47, i32* %48)
%50 = icmp ne i32 %49, 0
br i1 %50, label %52, label %51
51: ; preds = %46
br label %53
52: ; preds = %46
store i32 1, i32* %8
br label %53
53: ; preds = %52, %51, %45, %38, %30, %24, %17
%54 = load i32*, i32** %10
%55 = icmp ne i32* %54, null
br i1 %55, label %56, label %59
56: ; preds = %53
%57 = load i32*, i32** %10
%58 = call i32 @BN_clear_free(i32* %57)
br label %59
59: ; preds = %56, %53
%60 = load i32*, i32** %11
%61 = icmp ne i32* %60, null
br i1 %61, label %62, label %65
62: ; preds = %59
%63 = load i32*, i32** %11
%64 = call i32 @EC_POINT_free(i32* %63)
br label %65
65: ; preds = %62, %59
%66 = load i32, i32* %8
%67 = icmp ne i32 %66, 0
br i1 %67, label %68, label %70
68: ; preds = %65
%69 = load i32*, i32** %9
store i32* %69, i32** %4
br label %78
70: ; preds = %65
%71 = load i32*, i32** %9
%72 = icmp ne i32* %71, null
br i1 %72, label %73, label %76
73: ; preds = %70
%74 = load i32*, i32** %9
%75 = call i32 @EC_KEY_free(i32* %74)
br label %76
76: ; preds = %73, %70
br label %77
77: ; preds = %76
store i32* null, i32** %4
br label %78
78: ; preds = %77, %68
%79 = load i32*, i32** %4
ret i32* %79
}

LLVM IR (-O2):
define i32* @mk_eckey(i32 %0, i8* %1, i64 %2) {
%4 = tail call i32* @EC_KEY_new_by_curve_name(i32 %0)
%5 = icmp eq i32* %4, null
br i1 %5, label %31, label %6
6: ; preds = %3
%7 = tail call i32* @BN_bin2bn(i8* %1, i64 %2, i32* null)
%8 = icmp eq i32* %7, null
br i1 %8, label %29, label %9
9: ; preds = %6
%10 = tail call i32 @EC_KEY_set_private_key(i32* %4, i32* %7)
%11 = icmp eq i32 %10, 0
br i1 %11, label %24, label %12
12: ; preds = %9
%13 = tail call i32* @EC_KEY_get0_group(i32* %4)
%14 = tail call i32* @EC_POINT_new(i32* %13)
%15 = icmp eq i32* %14, null
br i1 %15, label %24, label %16
16: ; preds = %12
%17 = tail call i32 @EC_POINT_mul(i32* %13, i32* %14, i32* %7, i32* null, i32* null, i32* null)
%18 = icmp eq i32 %17, 0
br i1 %18, label %26, label %19
19: ; preds = %16
%20 = tail call i32 @EC_KEY_set_public_key(i32* %4, i32* %14)
%21 = icmp eq i32 %20, 0
%22 = tail call i32 @BN_clear_free(i32* %7)
%23 = tail call i32 @EC_POINT_free(i32* %14)
br i1 %21, label %29, label %31
24: ; preds = %9, %12
%25 = tail call i32 @BN_clear_free(i32* %7)
br label %29
26: ; preds = %16
%27 = tail call i32 @BN_clear_free(i32* %7)
%28 = tail call i32 @EC_POINT_free(i32* %14)
br label %29
29: ; preds = %26, %6, %24, %19
%30 = tail call i32 @EC_KEY_free(i32* %4)
br label %31
31: ; preds = %19, %3, %29
%32 = phi i32* [ null, %29 ], [ null, %3 ], [ %4, %19 ]
ret i32* %32
}