// File: /workspace/github_c_makefile_star2_O0/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
subq $0x100, %rsp            # imm = 0x100
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
callq 0x1090
movl %eax, %edi
callq 0x1070
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdx
leaq -0x28(%rbp), %rdi
leaq 0x4d00(%rip), %rsi      # 0x6004
movb $0x0, %al
callq 0x1130
movq -0x28(%rbp), %rdx
leaq -0x30(%rbp), %rdi
leaq 0x4cf3(%rip), %rsi      # 0x600d
movb $0x0, %al
callq 0x1130
movq -0x30(%rbp), %rdi
callq 0x10a0
cmpl $0x0, %eax
je 0x1345
leaq 0x4ce3(%rip), %rdi      # 0x6019
callq 0x1180
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x11a0
movq -0x28(%rbp), %rdi
movl $0x1c0, %esi            # imm = 0x1C0
callq 0x1140
cmpl $0x1, -0x8(%rbp)
jne 0x1369
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xd8(%rbp)
jmp 0x1378
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rdx
movq -0x38(%rbp), %rcx
leaq -0x40(%rbp), %rdi
leaq 0x4c89(%rip), %rsi      # 0x601f
movb $0x0, %al
callq 0x1130
movq -0x28(%rbp), %rdx
movq -0x38(%rbp), %rcx
leaq -0x48(%rbp), %rdi
leaq 0x4c8b(%rip), %rsi      # 0x603b
movb $0x0, %al
callq 0x1130
movq -0x28(%rbp), %rdx
movq -0x38(%rbp), %rcx
leaq -0x50(%rbp), %rdi
leaq 0x4c8d(%rip), %rsi      # 0x6057
movb $0x0, %al
callq 0x1130
movq -0x28(%rbp), %rdx
movq -0x38(%rbp), %rcx
leaq -0x58(%rbp), %rdi
leaq 0x4c8c(%rip), %rsi      # 0x6070
movb $0x0, %al
callq 0x1130
movq -0x48(%rbp), %rdi
callq 0x1700
cmpq $0x0, %rax
jg 0x1427
movq -0x58(%rbp), %rdi
callq 0x1700
cmpq $0x0, %rax
jg 0x1427
movq -0x50(%rbp), %rdi
callq 0x1700
cmpq $0x0, %rax
jg 0x1427
movq -0x40(%rbp), %rdi
callq 0x1700
cmpq $0x0, %rax
jle 0x1469
movq -0x38(%rbp), %rsi
leaq 0x4c57(%rip), %rdi      # 0x6089
movb $0x0, %al
callq 0x10b0
leaq 0x4c86(%rip), %rdi      # 0x60c6
movb $0x0, %al
callq 0x10b0
movq -0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq 0x4ca3(%rip), %rdi      # 0x60f9
movb $0x0, %al
callq 0x10b0
leaq 0x4ca5(%rip), %rdi      # 0x6109
callq 0x1670
movl $0x20, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x1750
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rdi
movl $0x20, %esi
callq 0x1690
movl $0x20, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x1750
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x3bd0
movl $0x40, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x1750
movq %rax, -0x70(%rbp)
movl $0x20, %edi
xorl %eax, %eax
movl %eax, %esi
callq 0x1750
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x70(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x4650
leaq 0x4c16(%rip), %rdi      # 0x610a
callq 0x1150
movq %rax, -0x80(%rbp)
leaq -0xc0(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x80(%rbp), %rdi
callq 0x1080
movq -0xe8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq %rax, %rdx
callq 0x4460
movl $0x0, -0xc4(%rbp)
cmpl $0x20, -0xc4(%rbp)
jge 0x1580
movslq -0xc4(%rbp), %rax
movzbl -0xc0(%rbp,%rax), %esi
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0xc4(%rbp), %rcx
movzbl (%rax,%rcx), %edx
xorl %esi, %edx
movb %dl, (%rax,%rcx)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x153f
movq -0x80(%rbp), %rdi
callq 0x1080
movq %rax, %rdi
callq 0x1120
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
movq -0x80(%rbp), %rsi
callq 0x1030
leaq 0x4b71(%rip), %rdi      # 0x6120
callq 0x1150
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rdi
movq -0xd0(%rbp), %rsi
callq 0x10f0
cmpl $0x0, %eax
je 0x15d9
leaq 0x4b61(%rip), %rdi      # 0x6135
callq 0x1670
movl $0xdb, %edi
callq 0x1100
movq -0x40(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x68(%rbp), %rdi
callq 0x1950
movq -0xf8(%rbp), %rdi
movq %rax, %rsi
callq 0x1900
movq -0x50(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x78(%rbp), %rdi
callq 0x1950
movq -0xf0(%rbp), %rdi
movq %rax, %rsi
callq 0x1900
movl $0xff, %edi
callq 0x1100
movq -0x48(%rbp), %rdi
movq -0x60(%rbp), %rsi
callq 0x18a0
movq -0x58(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x18a0
movq -0x38(%rbp), %rsi
leaq 0x4af8(%rip), %rdi      # 0x6150
movb $0x0, %al
callq 0x10b0
movl -0x4(%rbp), %eax
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nopl (%rax,%rax)