#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_GROUP;
typedef int /*<<< orphan*/ BN_CTX;
typedef int /*<<< orphan*/ BIGNUM;

/* Variables and functions */
int /*<<< orphan*/ BN_CTX_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ *BN_CTX_new();
int /*<<< orphan*/ BN_free(int /*<<< orphan*/ *);
int /*<<< orphan*/ BN_hex2bn(int /*<<< orphan*/ **, char *);
int /*<<< orphan*/ BN_value_one();
int /*<<< orphan*/ EC_GFp_mont_method();
int /*<<< orphan*/ *EC_GROUP_new(int /*<<< orphan*/);
int EC_GROUP_set_curve_GFp(int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                           int /*<<< orphan*/ *, int /*<<< orphan*/ *,
                           int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_GROUP_set_generator(int /*<<< orphan*/ *,
                                          int /*<<< orphan*/ *,
                                          int /*<<< orphan*/ *,
                                          int /*<<< orphan*/);
int /*<<< orphan*/ *EC_POINT_new(int /*<<< orphan*/ *);
int /*<<< orphan*/ EC_POINT_set_affine_coordinates_GFp(int /*<<< orphan*/ *,
                                                       int /*<<< orphan*/ *,
                                                       int /*<<< orphan*/ *,
                                                       int /*<<< orphan*/ *,
                                                       int /*<<< orphan*/ *);
EC_GROUP *sm2_ec_group() {
  EC_GROUP *ecg = EC_GROUP_new(EC_GFp_mont_method());
  BN_CTX *ctx = BN_CTX_new();
  BIGNUM *p = NULL, *a = NULL, *b = NULL;
  BN_hex2bn(&p,
            "8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3");
  BN_hex2bn(&a,
            "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498");
  BN_hex2bn(&b,
            "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A");
  if (EC_GROUP_set_curve_GFp(ecg, p, a, b, ctx) != 1)
    return 0;
  ;
  BIGNUM *Gx = NULL, *Gy = NULL, *N = NULL;
  BN_hex2bn(&Gx,
            "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D");
  BN_hex2bn(&Gy,
            "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2");
  BN_hex2bn(&N,
            "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7");
  EC_POINT *generator = EC_POINT_new(ecg);
  EC_POINT_set_affine_coordinates_GFp(ecg, generator, Gx, Gy, ctx);
  EC_GROUP_set_generator(ecg, generator, N, BN_value_one());
  BN_free(p);
  BN_free(a);
  BN_free(b);
  BN_free(Gx);
  BN_free(Gy);
  BN_free(N);
  BN_CTX_free(ctx);
  return ecg;
}


x86 assembly (clang, -O0):
<sm2_ec_group>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    $0x0,%al
call   10a0 <EC_GFp_mont_method@plt>
mov    %eax,%edi
call   1060 <EC_GROUP_new@plt>
mov    %rax,-0x10(%rbp)
mov    $0x0,%al
call   1090 <BN_CTX_new@plt>
mov    %rax,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
lea    -0x20(%rbp),%rdi
lea    0xe08(%rip),%rsi
call   1030 <BN_hex2bn@plt>
lea    -0x28(%rbp),%rdi
lea    0xe39(%rip),%rsi
call   1030 <BN_hex2bn@plt>
lea    -0x30(%rbp),%rdi
lea    0xe6a(%rip),%rsi
call   1030 <BN_hex2bn@plt>
mov    -0x10(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x28(%rbp),%rdx
mov    -0x30(%rbp),%rcx
mov    -0x18(%rbp),%r8
call   1050 <EC_GROUP_set_curve_GFp@plt>
cmp    $0x1,%eax
je     124c <sm2_ec_group+0x9c>
movq   $0x0,-0x8(%rbp)
jmp    1333 <sm2_ec_group+0x183>
movq   $0x0,-0x38(%rbp)
movq   $0x0,-0x40(%rbp)
movq   $0x0,-0x48(%rbp)
lea    -0x38(%rbp),%rdi
lea    0xe54(%rip),%rsi
call   1030 <BN_hex2bn@plt>
lea    -0x40(%rbp),%rdi
lea    0xe85(%rip),%rsi
call   1030 <BN_hex2bn@plt>
lea    -0x48(%rbp),%rdi
lea    0xeb6(%rip),%rsi
call   1030 <BN_hex2bn@plt>
mov    -0x10(%rbp),%rdi
call   10d0 <EC_POINT_new@plt>
mov    %rax,-0x50(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x50(%rbp),%rsi
mov    -0x38(%rbp),%rdx
mov    -0x40(%rbp),%rcx
mov    -0x18(%rbp),%r8
call   10b0 <EC_POINT_set_affine_coordinates_GFp@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x50(%rbp),%rax
mov    %rax,-0x60(%rbp)
mov    -0x48(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    $0x0,%al
call   1040 <BN_value_one@plt>
mov    -0x68(%rbp),%rdi
mov    -0x60(%rbp),%rsi
mov    -0x58(%rbp),%rdx
mov    %eax,%ecx
call   10c0 <EC_GROUP_set_generator@plt>
mov    -0x20(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x28(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x30(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x38(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x40(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x48(%rbp),%rdi
call   1080 <BN_free@plt>
mov    -0x18(%rbp),%rdi
call   1070 <BN_CTX_free@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sm2_ec_group>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x38,%rsp
xor    %ebx,%ebx
xor    %eax,%eax
call   10a0 <EC_GFp_mont_method@plt>
mov    %eax,%edi
call   1060 <EC_GROUP_new@plt>
mov    %rax,%r15
xor    %eax,%eax
call   1090 <BN_CTX_new@plt>
mov    %rax,%r14
movq   $0x0,0x30(%rsp)
movq   $0x0,0x28(%rsp)
movq   $0x0,0x20(%rsp)
lea    0xe06(%rip),%rsi
lea    0x30(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
lea    0xe36(%rip),%rsi
lea    0x28(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
lea    0xe66(%rip),%rsi
lea    0x20(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
mov    0x30(%rsp),%rsi
mov    0x28(%rsp),%rdx
mov    0x20(%rsp),%rcx
mov    %r15,%rdi
mov    %r14,%r8
call   1050 <EC_GROUP_set_curve_GFp@plt>
cmp    $0x1,%eax
jne    131d <sm2_ec_group+0x16d>
movq   $0x0,0x18(%rsp)
movq   $0x0,0x10(%rsp)
movq   $0x0,0x8(%rsp)
lea    0xe58(%rip),%rsi
lea    0x18(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
lea    0xe88(%rip),%rsi
lea    0x10(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
lea    0xeb8(%rip),%rsi
lea    0x8(%rsp),%rdi
call   1030 <BN_hex2bn@plt>
mov    %r15,%rdi
call   10d0 <EC_POINT_new@plt>
mov    %rax,%rbx
mov    0x18(%rsp),%rdx
mov    0x10(%rsp),%rcx
mov    %r15,%rdi
mov    %rax,%rsi
mov    %r14,%r8
call   10b0 <EC_POINT_set_affine_coordinates_GFp@plt>
mov    0x8(%rsp),%r12
xor    %eax,%eax
call   1040 <BN_value_one@plt>
mov    %r15,%rdi
mov    %rbx,%rsi
mov    %r12,%rdx
mov    %eax,%ecx
call   10c0 <EC_GROUP_set_generator@plt>
mov    0x30(%rsp),%rdi
call   1080 <BN_free@plt>
mov    0x28(%rsp),%rdi
call   1080 <BN_free@plt>
mov    0x20(%rsp),%rdi
call   1080 <BN_free@plt>
mov    0x18(%rsp),%rdi
call   1080 <BN_free@plt>
mov    0x10(%rsp),%rdi
call   1080 <BN_free@plt>
mov    0x8(%rsp),%rdi
call   1080 <BN_free@plt>
mov    %r14,%rdi
call   1070 <BN_CTX_free@plt>
mov    %r15,%rbx
mov    %rbx,%rax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@.str = [65 x i8] c"8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\00"
@.str.1 = [65 x i8] c"787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\00"
@.str.2 = [65 x i8] c"63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\00"
@.str.3 = [65 x i8] c"421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\00"
@.str.4 = [65 x i8] c"0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\00"
@.str.5 = [65 x i8] c"8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\00"
define i32* @sm2_ec_group() {
%1 = alloca i32*
%2 = alloca i32*
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i32*
%6 = alloca i32*
%7 = alloca i32*
%8 = alloca i32*
%9 = alloca i32*
%10 = alloca i32*
%11 = call i32 (...) @EC_GFp_mont_method()
%12 = call i32* @EC_GROUP_new(i32 %11)
store i32* %12, i32** %2
%13 = call i32* (...) @BN_CTX_new()
store i32* %13, i32** %3
store i32* null, i32** %4
store i32* null, i32** %5
store i32* null, i32** %6
%14 = call i32 @BN_hex2bn(i32** %4, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i64 0, i64 0))
%15 = call i32 @BN_hex2bn(i32** %5, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.1, i64 0, i64 0))
%16 = call i32 @BN_hex2bn(i32** %6, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.2, i64 0, i64 0))
%17 = load i32*, i32** %2
%18 = load i32*, i32** %4
%19 = load i32*, i32** %5
%20 = load i32*, i32** %6
%21 = load i32*, i32** %3
%22 = call i32 @EC_GROUP_set_curve_GFp(i32* %17, i32* %18, i32* %19, i32* %20, i32* %21)
%23 = icmp ne i32 %22, 1
br i1 %23, label %24, label %25
24: ; preds = %0
store i32* null, i32** %1
br label %57
25: ; preds = %0
store i32* null, i32** %7
store i32* null, i32** %8
store i32* null, i32** %9
%26 = call i32 @BN_hex2bn(i32** %7, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.3, i64 0, i64 0))
%27 = call i32 @BN_hex2bn(i32** %8, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.4, i64 0, i64 0))
%28 = call i32 @BN_hex2bn(i32** %9, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.5, i64 0, i64 0))
%29 = load i32*, i32** %2
%30 = call i32* @EC_POINT_new(i32* %29)
store i32* %30, i32** %10
%31 = load i32*, i32** %2
%32 = load i32*, i32** %10
%33 = load i32*, i32** %7
%34 = load i32*, i32** %8
%35 = load i32*, i32** %3
%36 = call i32 @EC_POINT_set_affine_coordinates_GFp(i32* %31, i32* %32, i32* %33, i32* %34, i32* %35)
%37 = load i32*, i32** %2
%38 = load i32*, i32** %10
%39 = load i32*, i32** %9
%40 = call i32 (...) @BN_value_one()
%41 = call i32 @EC_GROUP_set_generator(i32* %37, i32* %38, i32* %39, i32 %40)
%42 = load i32*, i32** %4
%43 = call i32 @BN_free(i32* %42)
%44 = load i32*, i32** %5
%45 = call i32 @BN_free(i32* %44)
%46 = load i32*, i32** %6
%47 = call i32 @BN_free(i32* %46)
%48 = load i32*, i32** %7
%49 = call i32 @BN_free(i32* %48)
%50 = load i32*, i32** %8
%51 = call i32 @BN_free(i32* %50)
%52 = load i32*, i32** %9
%53 = call i32 @BN_free(i32* %52)
%54 = load i32*, i32** %3
%55 = call i32 @BN_CTX_free(i32* %54)
%56 = load i32*, i32** %2
store i32* %56, i32** %1
br label %57
57: ; preds = %25, %24
%58 = load i32*, i32** %1
ret i32* %58
}

LLVM IR (-O2):
@.str = [65 x i8] c"8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3\00"
@.str.1 = [65 x i8] c"787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498\00"
@.str.2 = [65 x i8] c"63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A\00"
@.str.3 = [65 x i8] c"421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D\00"
@.str.4 = [65 x i8] c"0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2\00"
@.str.5 = [65 x i8] c"8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7\00"
define i32* @sm2_ec_group() {
%1 = alloca i32*
%2 = alloca i32*
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i32*
%6 = alloca i32*
%7 = tail call i32 (...) @EC_GFp_mont_method()
%8 = tail call i32* @EC_GROUP_new(i32 %7)
%9 = tail call i32* (...) @BN_CTX_new()
%10 = bitcast i32** %1 to i8*
store i32* null, i32** %1
%11 = bitcast i32** %2 to i8*
store i32* null, i32** %2
%12 = bitcast i32** %3 to i8*
store i32* null, i32** %3
%13 = call i32 @BN_hex2bn(i32** %1, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str, i64 0, i64 0))
%14 = call i32 @BN_hex2bn(i32** %2, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.1, i64 0, i64 0))
%15 = call i32 @BN_hex2bn(i32** %3, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.2, i64 0, i64 0))
%16 = load i32*, i32** %1
%17 = load i32*, i32** %2
%18 = load i32*, i32** %3
%19 = call i32 @EC_GROUP_set_curve_GFp(i32* %8, i32* %16, i32* %17, i32* %18, i32* %9)
%20 = icmp eq i32 %19, 1
br i1 %20, label %21, label %48
21: ; preds = %0
%22 = bitcast i32** %4 to i8*
store i32* null, i32** %4
%23 = bitcast i32** %5 to i8*
store i32* null, i32** %5
%24 = bitcast i32** %6 to i8*
store i32* null, i32** %6
%25 = call i32 @BN_hex2bn(i32** %4, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.3, i64 0, i64 0))
%26 = call i32 @BN_hex2bn(i32** %5, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.4, i64 0, i64 0))
%27 = call i32 @BN_hex2bn(i32** %6, i8* getelementptr inbounds ([65 x i8], [65 x i8]* @.str.5, i64 0, i64 0))
%28 = call i32* @EC_POINT_new(i32* %8)
%29 = load i32*, i32** %4
%30 = load i32*, i32** %5
%31 = call i32 @EC_POINT_set_affine_coordinates_GFp(i32* %8, i32* %28, i32* %29, i32* %30, i32* %9)
%32 = load i32*, i32** %6
%33 = call i32 (...) @BN_value_one()
%34 = call i32 @EC_GROUP_set_generator(i32* %8, i32* %28, i32* %32, i32 %33)
%35 = load i32*, i32** %1
%36 = call i32 @BN_free(i32* %35)
%37 = load i32*, i32** %2
%38 = call i32 @BN_free(i32* %37)
%39 = load i32*, i32** %3
%40 = call i32 @BN_free(i32* %39)
%41 = load i32*, i32** %4
%42 = call i32 @BN_free(i32* %41)
%43 = load i32*, i32** %5
%44 = call i32 @BN_free(i32* %43)
%45 = load i32*, i32** %6
%46 = call i32 @BN_free(i32* %45)
%47 = call i32 @BN_CTX_free(i32* %9)
br label %48
48: ; preds = %0, %21
%49 = phi i32* [ %8, %21 ], [ null, %0 ]
ret i32* %49
}