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

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

  c_string filename, to_id, from_id;

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

  c_string homedir = pw->pw_dir;
  c_string clmm_path, to_pk_path, from_sk_path, from_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(&from_pk_path, "%s/%s.public_encryption_key", clmm_path, from_id);
  c_string from_pk_b64 = (c_string)file_contents(from_pk_path, 0)->data;
  u8* from_pk = b64decode(from_pk_b64, 0)->data;

  asprintf(&from_sk_path, "%s/%s.secret_encryption_key", clmm_path, from_id);
  u8 from_sk[sek_size];
  FILE *f = fopen(from_sk_path, "r");
  fread(from_sk, sek_size, 1, f);
  fclose(f);

  // 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++) from_sk[i] ^= passwd_hash[i];

  u8 from_pk1[pek_size];
  crypto_scalarmult_base(from_pk1, from_sk);
  if (crypto_verify_32(from_pk, from_pk1)) die("Incorrect pass phrase");

  p_vector msg = file_contents(filename, crypto_box_ZEROBYTES);
  u8 *m = msg->padding;
  size_t mlen = msg->size;
  size_t clen = mlen + crypto_box_ZEROBYTES;

  // Pre-encryption

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

  p_vector nonce = mkvector(crypto_box_NONCEBYTES, 0);
  randombytes(nonce->data, crypto_box_NONCEBYTES);

  // Allocate ciphertext
  size_t offset = crypto_box_BOXZEROBYTES;
  p_vector ciphertext = mkvector(clen - offset, offset);
  u8 *c = ciphertext->padding;

  // Encrypt

  if (crypto_box_afternm(c, m, clen, nonce->data, k1) != 0)
    die("Encrpytion failed");

  // Output

  c_string s = b64encode(ciphertext);
  c_string s_end = s + strlen(s) - 76;

  printf("%s\n%s\n", b64encode(nonce), from_pk_b64);
  c_string s1 = s;
  for (; s1<s_end; s1+=76) {
    fwrite(s1, 76, 1, stdout);
    putchar('\n');
  }
  puts(s1);
  putchar('\n');
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, %rbx
movl %edi, %r14d
callq 0x1090
movl %eax, %edi
callq 0x1070
movq %rax, %rcx
cmpl $0x3, %r14d
je 0x12f9
cmpl $0x4, %r14d
jne 0x1570
leaq 0x18(%rbx), %rcx
movq 0x8(%rbx), %rdx
movq %rdx, -0x30(%rbp)
movq 0x10(%rbx), %r15
movq (%rcx), %r13
movq 0x20(%rax), %rdx
leaq 0x2d26(%rip), %rsi      # 0x4039
xorl %ebx, %ebx
leaq -0x80(%rbp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x1120
movq (%r14), %rdx
leaq 0x2d15(%rip), %rsi      # 0x4042
leaq -0x78(%rbp), %r12
movq %r12, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x1120
movq (%r12), %rdi
xorl %esi, %esi
callq 0x16ac
movq 0x10(%rax), %rdi
xorl %esi, %esi
callq 0x17e5
movq 0x10(%rax), %r15
movq (%r14), %rdx
leaq -0x68(%rbp), %r12
movq %r12, %rdi
leaq 0x2cd9(%rip), %rsi      # 0x4042
movq %r13, %rcx
xorl %eax, %eax
callq 0x1120
movq (%r12), %rdi
xorl %esi, %esi
callq 0x16ac
movq 0x10(%rax), %rdi
movq %rdi, -0x38(%rbp)
xorl %esi, %esi
callq 0x17e5
movq 0x10(%rax), %r12
movq (%r14), %rdx
leaq 0x2cc3(%rip), %rsi      # 0x405e
leaq -0x70(%rbp), %r14
movq %r14, %rdi
movq %r13, %rcx
xorl %eax, %eax
callq 0x1120
movq (%r14), %rdi
leaq 0x2cc4(%rip), %rsi      # 0x407a
callq 0x1150
movq %rax, %r14
leaq -0x60(%rbp), %rdi
movl $0x20, %esi
movl $0x1, %edx
movq %rax, %rcx
callq 0x1050
movq %r14, %rdi
callq 0x1060
leaq 0x2c99(%rip), %rdi      # 0x407c
callq 0x1130
movq %rax, %r14
movq %rax, %rdi
callq 0x1080
leaq -0x100(%rbp), %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x2efc
movb -0x100(%rbp,%rbx), %al
xorb %al, -0x60(%rbp,%rbx)
incq %rbx
cmpq $0x20, %rbx
jne 0x1405
leaq -0xc0(%rbp), %r14
leaq -0x60(%rbp), %rsi
movq %r14, %rdi
callq 0x2ae3
movq %r12, %rdi
movq %r14, %rsi
callq 0x1afe
testl %eax, %eax
je 0x1447
leaq 0x2c50(%rip), %rdi      # 0x4092
callq 0x158c
movl $0x20, %esi
movq -0x30(%rbp), %rdi
callq 0x16ac
movq (%rax), %r13
movq 0x8(%rax), %r14
leaq 0x20(%r13), %r12
leaq -0xa0(%rbp), %rdi
leaq -0x60(%rbp), %rdx
movq %r15, %rsi
callq 0x2b2a
testl %eax, %eax
je 0x1483
leaq 0x2c2a(%rip), %rdi      # 0x40a8
callq 0x158c
movl $0x18, %edi
xorl %esi, %esi
callq 0x163e
movq %rax, %r15
movq 0x10(%rax), %rdi
movl $0x18, %esi
callq 0x159f
addq $0x10, %r13
movl $0x10, %esi
movq %r13, %rdi
callq 0x163e
movq %rax, %r13
movq 0x8(%rax), %rdi
movq 0x10(%r15), %rcx
leaq -0xa0(%rbp), %r8
movq %r14, %rsi
movq %r12, %rdx
callq 0x2b77
testl %eax, %eax
je 0x14de
leaq 0x2be3(%rip), %rdi      # 0x40bc
callq 0x158c
movq %r13, %rdi
callq 0x17b3
movq %rax, %r14
movq %rax, %rdi
callq 0x1080
leaq (%r14,%rax), %rbx
addq $-0x4c, %rbx
movq %r15, %rdi
callq 0x17b3
leaq 0x2bc6(%rip), %rdi      # 0x40ce
movq %rax, %rsi
movq -0x38(%rbp), %rdx
xorl %eax, %eax
callq 0x10a0
cmpq %rbx, %r14
jae 0x154a
movq 0x5abe(%rip), %r15      # 0x6fe0
movq (%r15), %rcx
movl $0x4c, %esi
movl $0x1, %edx
movq %r14, %rdi
callq 0x1190
movl $0xa, %edi
callq 0x1030
addq $0x4c, %r14
cmpq %rbx, %r14
jb 0x1522
movq %r14, %rdi
callq 0x1040
movl $0xa, %edi
callq 0x1030
xorl %eax, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rbx), %rsi
leaq 0x2a8a(%rip), %rdi      # 0x4004
xorl %eax, %eax
callq 0x10a0
movl $0x1, %edi
callq 0x1180
nop