// File: /workspace/github_c_makefile_star2_O0/ioerror[P]csidh-reference-implementation/csidh_util.c
// Function: main
int main(int argc, char **argv) {
  private_key _private_key;
  public_key _public_key;
  public_key shared_secret_key;

  bzero(&_private_key, sizeof(private_key));
  bzero(&_public_key, sizeof(public_key));
  bzero(&shared_secret_key, sizeof(public_key));

  int option = 0;
  size_t verbose = 0;
  size_t generation_mode = 0;
  size_t derivation_mode = 0;
  size_t error = 0;
  bool csidh_validate = false;
  char *priv_key_file = NULL;
  char *pub_key_file = NULL;

  while ((option = getopt(argc, argv, "hvVgdp:s:")) != -1) {
    switch (option) {
    case 'V':
      fprintf(stderr, "csidh-p%i-util version: %f\n", BITS, VERSION);
      return 0;
    case 'h':
      fprintf(stderr, "csidh-p%i-util version: %f\n", BITS, VERSION);
      fprintf(stderr, "  -V: print version\n");
      fprintf(stderr, "  -verbose: increase verbosity\n");
      fprintf(stderr, "  -g: key generation mode\n");
      fprintf(stderr, "  -d: key derivation mode\n");
      fprintf(stderr, "  -p: public key file name\n");
      fprintf(stderr, "  -s: private key file name\n");
      return 0;
    case 'v':
      verbose += 1;
      break;
    case 'g':
      generation_mode = 1;
      if (derivation_mode) {
        error += 1;
      };
      break;
    case 'd':
      derivation_mode = 1;
      if (generation_mode) {
        error = 1;
      };
      break;
    case 'p':
      pub_key_file = optarg;
      if (verbose) {
        fprintf(stderr, "pub_key_file=%s\n", pub_key_file);
      };
      break;
    case 's':
      priv_key_file = optarg;
      if (verbose) {
        fprintf(stderr, "priv_key_file=%s\n", priv_key_file);
      };
      break;
    default:
      exit(1);
    }
  }

  if (error) {
    error_exit("Mutually exclusive options chosen");
  }

  if (generation_mode) {
    if (verbose) {
      fprintf(stderr, "Key generation mode\n");
    }
    csidh_private(&_private_key);
    csidh_validate = csidh(&_public_key, &base, &_private_key);
    if (!csidh_validate) {
      error_exit("csidh_validate: failed");
    }
    pprint_sk(&_private_key);
    pprint_pk(&_public_key);
    save_file(priv_key_file, &_private_key, (uint64_t) sizeof(private_key));
    save_file(pub_key_file, &_public_key,  (uint64_t) sizeof(public_key));
    return 0;
  }

  if (derivation_mode) {
    if (verbose) {
      fprintf(stderr, "DH mode\n");
    }

    if (sizeof(private_key) !=
        ((priv_key_file != NULL)
             ? read_file(priv_key_file, (uint8_t *)&_private_key,
                        (uint64_t) sizeof(private_key))
             : read_stdin((uint8_t *)&_private_key, (uint64_t) sizeof(private_key)))) {
      error_exit("Unable to read correct number of bytes for private key");
    }

    if (sizeof(public_key) !=
        ((pub_key_file != NULL)
             ? read_file(pub_key_file, (uint8_t *)&_public_key,
                         sizeof(public_key))
             : read_stdin((uint8_t *)&_public_key, sizeof(public_key)))) {
      error_exit("Unable to read correct number of bytes for public key");
    }

    csidh_validate = csidh(&shared_secret_key, &_public_key, &_private_key);
    if (!csidh_validate) {
      error_exit("csidh_validate: failed");
    }
    if (verbose) {
      pprint_sk(&_private_key);
      pprint_pk(&_public_key);
    }
    pprint_ss((uint64_t *)&shared_secret_key);
    return 0;
  }

  return 1;
}

// Assembly:
subq $0x118, %rsp            # imm = 0x118
movl $0x0, 0x114(%rsp)
movl %edi, 0x110(%rsp)
movq %rsi, 0x108(%rsp)
leaq 0xe3(%rsp), %rdi
movl $0x25, %esi
callq 0x10e0
leaq 0xa0(%rsp), %rdi
movl $0x40, %esi
callq 0x10e0
leaq 0x60(%rsp), %rdi
movl $0x40, %esi
callq 0x10e0
movl $0x0, 0x5c(%rsp)
movq $0x0, 0x50(%rsp)
movq $0x0, 0x48(%rsp)
movq $0x0, 0x40(%rsp)
movq $0x0, 0x38(%rsp)
movb $0x0, 0x37(%rsp)
movq $0x0, 0x28(%rsp)
movq $0x0, 0x20(%rsp)
movl 0x110(%rsp), %edi
movq 0x108(%rsp), %rsi
leaq 0x3a8a(%rip), %rdx      # 0x50b7
callq 0x10f0
movl %eax, 0x5c(%rsp)
cmpl $-0x1, %eax
je 0x1833
movl 0x5c(%rsp), %eax
addl $-0x56, %eax
movl %eax, %ecx
movq %rcx, 0x18(%rsp)
subl $0x20, %eax
ja 0x1824
movq 0x18(%rsp), %rax
leaq 0x39ae(%rip), %rcx      # 0x5010
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x5986(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a45(%rip), %rsi      # 0x50c1
movl $0x200, %edx            # imm = 0x200
vmovsd 0x397f(%rip), %xmm0     # 0x5008
movb $0x1, %al
callq 0x10a0
movl $0x0, 0x114(%rsp)
jmp 0x1a60
movq 0x5951(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a10(%rip), %rsi      # 0x50c1
movl $0x200, %edx            # imm = 0x200
vmovsd 0x394a(%rip), %xmm0     # 0x5008
movb $0x1, %al
callq 0x10a0
movq 0x592c(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a07(%rip), %rsi      # 0x50dd
movb $0x0, %al
callq 0x10a0
movq 0x5914(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a04(%rip), %rsi      # 0x50f2
movb $0x0, %al
callq 0x10a0
movq 0x58fc(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a0c(%rip), %rsi      # 0x5112
movb $0x0, %al
callq 0x10a0
movq 0x58e4(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a0f(%rip), %rsi      # 0x512d
movb $0x0, %al
callq 0x10a0
movq 0x58cc(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a12(%rip), %rsi      # 0x5148
movb $0x0, %al
callq 0x10a0
movq 0x58b4(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x3a16(%rip), %rsi      # 0x5164
movb $0x0, %al
callq 0x10a0
movl $0x0, 0x114(%rsp)
jmp 0x1a60
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0x182e
movq $0x1, 0x48(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x1797
movq 0x38(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
jmp 0x182e
movq $0x1, 0x40(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x17b6
movq $0x1, 0x38(%rsp)
jmp 0x182e
movq 0x5819(%rip), %rax      # 0x6fd8
movq (%rax), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x17ec
movq 0x5822(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movq 0x20(%rsp), %rdx
leaq 0x399c(%rip), %rsi      # 0x5181
movb $0x0, %al
callq 0x10a0
jmp 0x182e
movq 0x57e3(%rip), %rax      # 0x6fd8
movq (%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x50(%rsp)
je 0x1822
movq 0x57ec(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movq 0x28(%rsp), %rdx
leaq 0x3977(%rip), %rsi      # 0x5192
movb $0x0, %al
callq 0x10a0
jmp 0x182e
movl $0x1, %edi
callq 0x1100
jmp 0x1617
cmpq $0x0, 0x38(%rsp)
je 0x1847
leaq 0x3962(%rip), %rdi      # 0x51a4
callq 0x1400
cmpq $0x0, 0x48(%rsp)
je 0x190d
cmpq $0x0, 0x50(%rsp)
je 0x1873
movq 0x5796(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x395a(%rip), %rsi      # 0x51c6
movb $0x0, %al
callq 0x10a0
leaq 0xe3(%rsp), %rdi
callq 0x1a70
leaq 0xa0(%rsp), %rdi
leaq 0x39e1(%rip), %rsi      # 0x5270
leaq 0xe3(%rsp), %rdx
callq 0x2750
andb $0x1, %al
movb %al, 0x37(%rsp)
testb $0x1, 0x37(%rsp)
jne 0x18b5
leaq 0x392b(%rip), %rdi      # 0x51db
callq 0x1400
leaq 0xe3(%rsp), %rdi
callq 0x1270
leaq 0xa0(%rsp), %rdi
callq 0x1210
movq 0x28(%rsp), %rdi
leaq 0xe3(%rsp), %rsi
movl $0x25, %edx
callq 0x1330
movq 0x20(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
movl $0x40, %edx
callq 0x1330
movl $0x0, 0x114(%rsp)
jmp 0x1a60
cmpq $0x0, 0x40(%rsp)
je 0x1a55
cmpq $0x0, 0x50(%rsp)
je 0x1939
movq 0x56d0(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
leaq 0x38c0(%rip), %rsi      # 0x51f2
movb $0x0, %al
callq 0x10a0
cmpq $0x0, 0x28(%rsp)
je 0x195f
movq 0x28(%rsp), %rdi
leaq 0xe3(%rsp), %rsi
movl $0x25, %edx
callq 0x1430
movq %rax, 0x10(%rsp)
jmp 0x1976
leaq 0xe3(%rsp), %rdi
movl $0x25, %esi
callq 0x1500
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rcx
movl $0x25, %eax
cmpq %rcx, %rax
je 0x1991
leaq 0x386f(%rip), %rdi      # 0x51fb
callq 0x1400
cmpq $0x0, 0x20(%rsp)
je 0x19b7
movq 0x20(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
movl $0x40, %edx
callq 0x1430
movq %rax, 0x8(%rsp)
jmp 0x19ce
leaq 0xa0(%rsp), %rdi
movl $0x40, %esi
callq 0x1500
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rcx
movl $0x40, %eax
cmpq %rcx, %rax
je 0x19e9
leaq 0x384e(%rip), %rdi      # 0x5232
callq 0x1400
leaq 0x60(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
leaq 0xe3(%rsp), %rdx
callq 0x2750
andb $0x1, %al
movb %al, 0x37(%rsp)
testb $0x1, 0x37(%rsp)
jne 0x1a1c
leaq 0x37c4(%rip), %rdi      # 0x51db
callq 0x1400
cmpq $0x0, 0x50(%rsp)
je 0x1a3e
leaq 0xe3(%rsp), %rdi
callq 0x1270
leaq 0xa0(%rsp), %rdi
callq 0x1210
leaq 0x60(%rsp), %rdi
callq 0x12d0
movl $0x0, 0x114(%rsp)
jmp 0x1a60
movl $0x1, 0x114(%rsp)
movl 0x114(%rsp), %eax
addq $0x118, %rsp            # imm = 0x118
retq
nop