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

  struct passwd *pw = getpwuid(getuid());

  c_string filename, to_id;

  if (argc == 2) {
    filename = argv[1];
    to_id = pw->pw_name;
  } else if (argc == 3) {
    filename = argv[1];
    to_id = argv[2];
  } else {
    printf("Usage: %s filename [recipient_key_id]\n", argv[0]);
    exit(1);
  }

  // Get the keys

  c_string homedir = pw->pw_dir;
  c_string clmm_path, to_sk_path, to_pk_path;
  asprintf(&clmm_path, "%s/.clmm", homedir);
  
  asprintf(&to_pk_path, "%s/%s.public_encryption_key", clmm_path, to_id);
  c_string to_pk_b64 = (c_string)file_contents(to_pk_path, 0)->data;
  u8* to_pk = b64decode(to_pk_b64, 0)->data;
  
  asprintf(&to_sk_path, "%s/%s.secret_encryption_key", clmm_path, to_id);
  u8* to_sk = file_contents(to_sk_path, 0)->data;

  // Decrypt the secret key

  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++) to_sk[i] ^= passwd_hash[i];
  
  u8 to_pk1[pek_size];
  crypto_scalarmult_base(to_pk1, to_sk);
  if (crypto_verify_32(to_pk, to_pk1)) die("Incorrect pass phrase");

  // Get the from_key, nonce and ciphertext from the encrypted message

  c_string s = (c_string)file_contents(filename, 0)->data;
  c_string nonce_b64 = strtok(s, "\n");
  c_string from_pk_b64 = strtok(0, "\n");
  c_string ciphertext_b64 = strtok(0, "\0");

  u8* nonce = b64decode(nonce_b64, 0)->data;
  u8* from_pk = b64decode(from_pk_b64, 0)->data;

  // Remove newlines from ciphertext
  c_string s1,s2;
  s1 = s2 = ciphertext_b64;
  do {
    if (*s1 != '\n') *s2++ = *s1;
  } while (*s1++);
  *s2++ = '\0';

  size_t offset = crypto_box_BOXZEROBYTES;
  p_vector ciphertext = b64decode(ciphertext_b64, offset);
  u8* c = ciphertext->padding;
  size_t clen = ciphertext->size + offset;

  // Allocate cleartext buffer
  p_vector msg = mkvector(clen, crypto_box_ZEROBYTES);

  // Pre-decryption

  unsigned char k1[crypto_box_BEFORENMBYTES];
  if (crypto_box_beforenm(k1, from_pk, to_sk) != 0)
    die("Crypto setup failed");

  // Decrypt

  if (crypto_box_open_afternm(msg->padding, c, clen, nonce, k1) != 0)
    die("Decrpytion failed");

  fwrite(msg->data, clen-crypto_box_ZEROBYTES, 1, stdout);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %rbx
movl %edi, %r14d
callq 0x1080
movl %eax, %edi
callq 0x1060
movq %rax, %rcx
cmpl $0x2, %r14d
je 0x12f9
cmpl $0x3, %r14d
jne 0x1509
leaq 0x10(%rbx), %rcx
movq 0x8(%rbx), %r14
movq (%rcx), %rbx
movq 0x20(%rax), %rdx
leaq 0x2d20(%rip), %rsi      # 0x402b
xorl %r13d, %r13d
leaq -0x50(%rbp), %r12
movq %r12, %rdi
xorl %eax, %eax
callq 0x1110
movq (%r12), %rdx
leaq 0x2d0d(%rip), %rsi      # 0x4034
leaq -0x40(%rbp), %r15
movq %r15, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1110
movq (%r15), %rdi
xorl %esi, %esi
callq 0x1644
movq 0x10(%rax), %rdi
xorl %esi, %esi
callq 0x177d
movq 0x10(%rax), %r15
movq (%r12), %rdx
leaq 0x2cf4(%rip), %rsi      # 0x4050
leaq -0x48(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x1110
movq (%r12), %rdi
xorl %esi, %esi
callq 0x1644
movq 0x10(%rax), %rbx
leaq 0x2ce9(%rip), %rdi      # 0x406c
callq 0x1120
movq %rax, %r12
movq %rax, %rdi
callq 0x1070
leaq -0xd0(%rbp), %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x2e82
movb -0xd0(%rbp,%r13), %al
xorb %al, (%rbx,%r13)
incq %r13
cmpq $0x20, %r13
jne 0x13a5
leaq -0x90(%rbp), %r12
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2a69
movq %r15, %rdi
movq %r12, %rsi
callq 0x1a99
testl %eax, %eax
je 0x13e7
leaq 0x2ca0(%rip), %rdi      # 0x4082
callq 0x1524
movq %r14, %rdi
xorl %esi, %esi
callq 0x1644
movq 0x10(%rax), %rdi
leaq 0x2c2d(%rip), %r14      # 0x4029
movq %r14, %rsi
callq 0x1160
movq %rax, %r12
xorl %edi, %edi
movq %r14, %rsi
callq 0x1160
movq %rax, %r14
leaq 0x2ca3(%rip), %rsi      # 0x40be
xorl %edi, %edi
callq 0x1160
movq %rax, %r15
movq %r12, %rdi
xorl %esi, %esi
callq 0x177d
movq 0x10(%rax), %rax
movq %rax, -0x38(%rbp)
movq %r14, %rdi
xorl %esi, %esi
callq 0x177d
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
movq %r15, %rax
movq %r15, %rcx
movb (%rcx), %dl
incq %rcx
cmpb $0xa, %dl
je 0x144f
movb %dl, (%rax)
incq %rax
cmpb $0x0, -0x1(%rcx)
jne 0x144f
movb $0x0, (%rax)
movl $0x10, %esi
movq %r15, %rdi
callq 0x177d
movq (%rax), %r15
movq 0x8(%rax), %r14
leaq 0x10(%r15), %r12
movl $0x20, %esi
movq %r12, %rdi
callq 0x15d6
movq %rax, %r13
leaq -0x70(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq %rbx, %rdx
callq 0x2ab0
testl %eax, %eax
je 0x14af
leaq 0x2bee(%rip), %rdi      # 0x4098
callq 0x1524
movq 0x8(%r13), %rdi
leaq -0x70(%rbp), %r8
movq %r14, %rsi
movq %r12, %rdx
movq -0x38(%rbp), %rcx
callq 0x2b07
testl %eax, %eax
je 0x14d6
leaq 0x2bdb(%rip), %rdi      # 0x40ac
callq 0x1524
movq 0x10(%r13), %rdi
addq $-0x10, %r15
movq 0x5afb(%rip), %rax      # 0x6fe0
movq (%rax), %rcx
movl $0x1, %edx
movq %r15, %rsi
callq 0x1190
xorl %eax, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbx), %rsi
leaq 0x2af1(%rip), %rdi      # 0x4004
xorl %eax, %eax
callq 0x1090
movl $0x1, %edi
callq 0x1180