user: What is the c source code of the assembly code below?

```asm
<BN_generate_prime_ex>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %esi,-0x3c(%rbp)
  mov    %edx,-0x40(%rbp)
  mov    %rcx,-0x48(%rbp)
  mov    %r8,-0x50(%rbp)
  mov    %r9,-0x58(%rbp)
  movl   $0x0,-0x24(%rbp)
  movl   $0x0,-0x1c(%rbp)
  mov    -0x3c(%rbp),%eax
  mov    %eax,%edi
  call   <BN_prime_checks_for_size@plt>
  mov    %eax,-0x18(%rbp)
  mov    $0x0,%eax
  call   <BN_CTX_new@plt>
  mov    %rax,-0x10(%rbp)
  cmpq   $0x0,-0x10(%rbp)
  je     L216
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <BN_CTX_start@plt>
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <BN_CTX_get@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  je     L94
  nop
L7:
  cmpq   $0x0,-0x48(%rbp)
  jne    L77
  mov    -0x3c(%rbp),%edx
  mov    -0x38(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <probable_prime@plt>
  test   %eax,%eax
  jne    L106
  jmp    L20
L77:
  cmpl   $0x0,-0x40(%rbp)
  je     L275
  mov    -0x10(%rbp),%rdi
  mov    -0x50(%rbp),%rcx
  mov    -0x48(%rbp),%rdx
  mov    -0x3c(%rbp),%esi
  mov    -0x38(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <probable_prime_dh_safe@plt>
  test   %eax,%eax
  jne    L106
  jmp    L20
L275:
  mov    -0x10(%rbp),%rdi
  mov    -0x50(%rbp),%rcx
  mov    -0x48(%rbp),%rdx
  mov    -0x3c(%rbp),%esi
  mov    -0x38(%rbp),%rax
  mov    %rdi,%r8
  mov    %rax,%rdi
  call   <probable_prime_dh@plt>
  test   %eax,%eax
  je     L13
L106:
  mov    -0x1c(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x1c(%rbp)
  mov    -0x58(%rbp),%rcx
  mov    %eax,%edx
  mov    $0x0,%esi
  mov    %rcx,%rdi
  call   <BN_GENCB_call@plt>
  test   %eax,%eax
  je     L55
  cmpl   $0x0,-0x40(%rbp)
  jne    L204
  mov    -0x58(%rbp),%rcx
  mov    -0x10(%rbp),%rdx
  mov    -0x18(%rbp),%esi
  mov    -0x38(%rbp),%rax
  mov    %rcx,%r8
  mov    $0x0,%ecx
  mov    %rax,%rdi
  call   <BN_is_prime_fasttest_ex@plt>
  mov    %eax,-0x20(%rbp)
  cmpl   $0xffffffff,-0x20(%rbp)
  je     L247
  cmpl   $0x0,-0x20(%rbp)
  jne    L81
  jmp    L7
L204:
  mov    -0x38(%rbp),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <BN_rshift1@plt>
  test   %eax,%eax
  je     L295
  movl   $0x0,-0x20(%rbp)
  jmp    L233
L64:
  mov    -0x58(%rbp),%rcx
  mov    -0x10(%rbp),%rdx
  mov    -0x38(%rbp),%rax
  mov    %rcx,%r8
  mov    $0x0,%ecx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <BN_is_prime_fasttest_ex@plt>
  mov    %eax,-0x14(%rbp)
  cmpl   $0xffffffff,-0x14(%rbp)
  je     L160
  cmpl   $0x0,-0x14(%rbp)
  jne    L129
  jmp    L7
L129:
  mov    -0x58(%rbp),%rcx
  mov    -0x10(%rbp),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rcx,%r8
  mov    $0x0,%ecx
  mov    $0x1,%esi
  mov    %rax,%rdi
  call   <BN_is_prime_fasttest_ex@plt>
  mov    %eax,-0x14(%rbp)
  cmpl   $0xffffffff,-0x14(%rbp)
  je     L318
  cmpl   $0x0,-0x14(%rbp)
  jne    L47
  jmp    L7
L47:
  mov    -0x1c(%rbp),%eax
  lea    -0x1(%rax),%edx
  mov    -0x58(%rbp),%rax
  mov    $0x2,%esi
  mov    %rax,%rdi
  call   <BN_GENCB_call@plt>
  test   %eax,%eax
  je     L338
  addl   $0x1,-0x20(%rbp)
L233:
  mov    -0x20(%rbp),%eax
  cmp    -0x18(%rbp),%eax
  jl     L64
L81:
  movl   $0x1,-0x24(%rbp)
  jmp    L20
L216:
  nop
  jmp    L20
L94:
  nop
  jmp    L20
L13:
  nop
  jmp    L20
L55:
  nop
  jmp    L20
L247:
  nop
  jmp    L20
L295:
  nop
  jmp    L20
L160:
  nop
  jmp    L20
L318:
  nop
  jmp    L20
L338:
  nop
L20:
  cmpq   $0x0,-0x10(%rbp)
  je     L282
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <BN_CTX_end@plt>
  mov    -0x10(%rbp),%rax
  mov    %rax,%rdi
  call   <BN_CTX_free@plt>
L282:
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <bn_check_top@plt>
  mov    -0x24(%rbp),%eax
  leave
  ret
```

assistant: ```c
int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) {
  BIGNUM *t;
  int found = 0;
  int i, j, c1 = 0;
  BN_CTX *ctx;
  int checks = BN_prime_checks_for_size(bits);
  ctx = BN_CTX_new();
  if (ctx == NULL)
    goto err;
  BN_CTX_start(ctx);
  t = BN_CTX_get(ctx);
  if (!t)
    goto err;
loop:
  if (add == NULL) {
    if (!probable_prime(ret, bits))
      goto err;
  } else {
    if (safe) {
      if (!probable_prime_dh_safe(ret, bits, add, rem, ctx))
        goto err;
    } else {
      if (!probable_prime_dh(ret, bits, add, rem, ctx))
        goto err;
    }
  }
  if (!BN_GENCB_call(cb, 0, c1++))
    goto err;
  if (!safe) {
    i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb);
    if (i == -1)
      goto err;
    if (i == 0)
      goto loop;
  } else {
    if (!BN_rshift1(t, ret))
      goto err;
    for (i = 0; i < checks; i++) {
      j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb);
      if (j == -1)
        goto err;
      if (j == 0)
        goto loop;
      j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb);
      if (j == -1)
        goto err;
      if (j == 0)
        goto loop;
      if (!BN_GENCB_call(cb, 2, c1 - 1))
        goto err;
    }
  }
  found = 1;
err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
  }
  bn_check_top(ret);
  return found;
}
```