// File: /workspace/github_c_makefile_star2_O2/rongarret[P]clmm/genkeys.c
// Function: main
int main(int argc, char** argv) {

  // Construct the path to the ~/.clmm directory and make sure it exsits
  struct passwd *pw = getpwuid(getuid());
  c_string homedir = pw->pw_dir;
  c_string clmm_path, mkdir_cmd;
  asprintf(&clmm_path, "%s/.clmm", homedir);
  asprintf(&mkdir_cmd, "mkdir -p %s", clmm_path);
  if (system(mkdir_cmd)) {
    perror("mkdir");
    exit(-1);
  }
  chmod(clmm_path, 0700);

  // Get the key name, default to the user's name
  c_string key_name = (argc == 1 ? pw->pw_name : argv[1]);

  // Construct the paths to the key files
  c_string pek_path, sek_path, psk_path, ssk_path;
  asprintf(&pek_path, "%s/%s.public_encryption_key", clmm_path, key_name);
  asprintf(&sek_path, "%s/%s.secret_encryption_key", clmm_path, key_name);
  asprintf(&psk_path, "%s/%s.public_signing_key", clmm_path, key_name);
  asprintf(&ssk_path, "%s/%s.secret_signing_key", clmm_path, key_name);

  if (file_size(sek_path)>0 || file_size(ssk_path)>0 ||
      file_size(psk_path)>0 || file_size(pek_path)>0) {
    printf("Keys for %s already exist.  If you want to re-generate them\n",
	   key_name);
    printf("you must first delete the existing keys by doing:\n");
    printf("  rm -f %s/%s.*\n", clmm_path, key_name);
    die("");
  }

  // Generate a secret key
  p_vector my_sek = mkvector(sek_size, 0);
  randombytes(my_sek->data, sek_size);

  // Generate the public key
  p_vector my_pek = mkvector(pek_size, 0);
  crypto_scalarmult_base(my_pek->data, my_sek->data);

  // Generate the signing keypair
  p_vector my_ssk = mkvector(ssk_size, 0);
  p_vector my_psk = mkvector(psk_size, 0);
  crypto_sign_keypair(my_psk->data, my_ssk->data);

  // Encrypt the secret keys
  char *passwd = getpass("Enter a pass phrase: ");
  u8 passwd_hash[crypto_hash_BYTES];
  crypto_hash(passwd_hash, (u8*)passwd, strlen(passwd));
  for (int i=0; i<sek_size; i++) (my_sek->data[i]) ^= passwd_hash[i];

  c_string passwd1 = malloc(strlen(passwd));
  strcpy(passwd1, passwd);
  passwd = getpass("Verify pass phrase: ");
  if (strcmp(passwd, passwd1)) die("Pass phrases do not match.");

  // Write the public keys

  umask(0333);
  write_cstring(pek_path, b64encode(my_pek));
  write_cstring(psk_path, b64encode(my_psk));

  // Write secret keys in binary to make it a little less tempting to share

  umask(0377);
  write_pvector(sek_path, my_sek);
  write_pvector(ssk_path, my_ssk);

  printf("Successfully generated new keys for %s\n", key_name);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rsi, %rbx
movl %edi, %r14d
callq 0x1090
movl %eax, %edi
callq 0x1070
movq %rax, %r15
movq 0x20(%rax), %rdx
leaq 0x2d14(%rip), %rsi      # 0x4004
leaq -0x30(%rbp), %r12
movq %r12, %rdi
xorl %eax, %eax
callq 0x1130
movq (%r12), %rdx
leaq 0x2d04(%rip), %rsi      # 0x400d
leaq -0x70(%rbp), %r12
movq %r12, %rdi
xorl %eax, %eax
callq 0x1130
movq (%r12), %rdi
callq 0x10a0
testl %eax, %eax
jne 0x1593
movq -0x30(%rbp), %rdi
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x1140
addq $0x8, %rbx
cmpl $0x1, %r14d
cmoveq %r15, %rbx
movq (%rbx), %rbx
movq -0x30(%rbp), %rdx
leaq 0x2ccf(%rip), %rsi      # 0x401f
leaq -0x48(%rbp), %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1130
movq -0x30(%rbp), %rdx
leaq 0x2cd2(%rip), %rsi      # 0x403b
leaq -0x68(%rbp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1130
movq -0x30(%rbp), %rdx
leaq 0x2cd2(%rip), %rsi      # 0x4057
leaq -0x40(%rbp), %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1130
movq -0x30(%rbp), %rdx
leaq 0x2cd2(%rip), %rsi      # 0x4070
leaq -0x38(%rbp), %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1130
movq (%r14), %rdi
callq 0x161e
testq %rax, %rax
jg 0x13e3
movq -0x38(%rbp), %rdi
callq 0x161e
testq %rax, %rax
jg 0x13e3
movq -0x40(%rbp), %rdi
callq 0x161e
testq %rax, %rax
jg 0x13e3
movq -0x48(%rbp), %rdi
callq 0x161e
testq %rax, %rax
jle 0x1421
leaq 0x2c9f(%rip), %rdi      # 0x4089
movq %rbx, %rsi
xorl %eax, %eax
callq 0x10b0
leaq 0x2d4a(%rip), %rdi      # 0x4145
callq 0x1040
movq -0x30(%rbp), %rsi
leaq 0x2cbb(%rip), %rdi      # 0x40c6
movq %rbx, %rdx
xorl %eax, %eax
callq 0x10b0
leaq 0x2cba(%rip), %rdi      # 0x40d6
callq 0x15a8
xorl %r12d, %r12d
pushq $0x20
popq %r15
movq %r15, %rdi
xorl %esi, %esi
callq 0x1651
movq %rax, %r14
movq 0x10(%rax), %rdi
movq %r15, %rsi
callq 0x15b9
movq %r15, %rdi
xorl %esi, %esi
callq 0x1651
movq %rax, -0x58(%rbp)
movq 0x10(%rax), %rdi
movq 0x10(%r14), %rsi
callq 0x28c3
pushq $0x40
popq %rdi
xorl %esi, %esi
callq 0x1651
movq %rax, %r13
movq %r15, %rdi
xorl %esi, %esi
callq 0x1651
movq %rax, -0x50(%rbp)
movq 0x10(%rax), %rdi
movq %r13, -0x60(%rbp)
movq 0x10(%r13), %rsi
callq 0x2d90
leaq 0x2c48(%rip), %rdi      # 0x40d7
callq 0x1150
movq %rax, %r15
movq %rax, %rdi
callq 0x1080
leaq -0xb0(%rbp), %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2c92
cmpq $0x20, %r12
je 0x14cc
movb -0xb0(%rbp,%r12), %al
movq 0x10(%r14), %rcx
xorb %al, (%rcx,%r12)
incq %r12
jmp 0x14b1
movq %r15, %rdi
callq 0x1080
movq %rax, %rdi
callq 0x1120
movq %rax, %r12
movq %rax, %rdi
movq %r15, %rsi
callq 0x1030
leaq 0x2bfc(%rip), %rdi      # 0x40ed
callq 0x1150
movq %rax, %rdi
movq %r12, %rsi
callq 0x10f0
testl %eax, %eax
je 0x1511
leaq 0x2bf6(%rip), %rdi      # 0x4102
callq 0x15a8
movl $0xdb, %edi
callq 0x1100
movq -0x48(%rbp), %r15
movq -0x58(%rbp), %rdi
callq 0x179e
movq %r15, %rdi
movq %rax, %rsi
callq 0x1769
movq -0x40(%rbp), %r15
movq -0x50(%rbp), %rdi
callq 0x179e
movq %r15, %rdi
movq %rax, %rsi
callq 0x1769
movl $0xff, %edi
callq 0x1100
movq -0x68(%rbp), %rdi
movq %r14, %rsi
callq 0x172c
movq -0x38(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x172c
leaq 0x2ba8(%rip), %rdi      # 0x411d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x10b0
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2a7f(%rip), %rdi      # 0x4019
callq 0x1180
pushq $-0x1
popq %rdi
callq 0x11a0
nop