// File: /workspace/github_c_makefile_star2_O2/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 0x12b9
cmpl $0x4, %r14d
jne 0x152d
leaq 0x18(%rbx), %rcx
movq 0x8(%rbx), %rdx
movq %rdx, -0x38(%rbp)
movq 0x10(%rbx), %r15
movq (%rcx), %r13
movq 0x20(%rax), %rdx
leaq 0x2d66(%rip), %rsi      # 0x4039
xorl %ebx, %ebx
leaq -0x80(%rbp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdx
leaq 0x2d55(%rip), %rsi      # 0x4042
leaq -0x78(%rbp), %r12
movq %r12, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x1100
movq (%r12), %rdi
xorl %esi, %esi
callq 0x1665
movq 0x10(%rax), %rdi
xorl %esi, %esi
callq 0x1770
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
movq (%r14), %rdx
leaq -0x68(%rbp), %r15
movq %r15, %rdi
leaq 0x2d15(%rip), %rsi      # 0x4042
movq %r13, %rcx
xorl %eax, %eax
callq 0x1100
movq (%r15), %rdi
xorl %esi, %esi
callq 0x1665
movq 0x10(%rax), %rdi
movq %rdi, -0x40(%rbp)
xorl %esi, %esi
callq 0x1770
movq 0x10(%rax), %r12
movq (%r14), %rdx
leaq 0x2d00(%rip), %rsi      # 0x405e
leaq -0x70(%rbp), %r14
movq %r14, %rdi
movq %r13, %rcx
xorl %eax, %eax
callq 0x1100
movq (%r14), %rdi
leaq 0x2d01(%rip), %rsi      # 0x407a
callq 0x1130
movq %rax, %r14
leaq -0x60(%rbp), %rdi
pushq $0x20
popq %rsi
pushq $0x1
popq %rdx
movq %rax, %rcx
callq 0x1050
movq %r14, %rdi
callq 0x1060
leaq 0x2cda(%rip), %rdi      # 0x407c
callq 0x1110
movq %rax, %r14
movq %rax, %rdi
callq 0x1080
leaq -0x100(%rbp), %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x2c32
cmpq $0x20, %rbx
je 0x13da
movb -0x100(%rbp,%rbx), %al
xorb %al, -0x60(%rbp,%rbx)
incq %rbx
jmp 0x13c4
leaq -0xc0(%rbp), %r14
leaq -0x60(%rbp), %rsi
movq %r14, %rdi
callq 0x2863
movq %r12, %rdi
movq %r14, %rsi
callq 0x1a78
testl %eax, %eax
je 0x1408
leaq 0x2c8f(%rip), %rdi      # 0x4092
callq 0x1548
pushq $0x20
popq %rsi
movq -0x38(%rbp), %rdi
callq 0x1665
movq (%rax), %r15
movq 0x8(%rax), %r12
leaq 0x20(%r15), %r13
leaq -0xa0(%rbp), %rdi
leaq -0x60(%rbp), %rdx
movq -0x30(%rbp), %rsi
callq 0x28a1
testl %eax, %eax
je 0x1443
leaq 0x2c6a(%rip), %rdi      # 0x40a8
callq 0x1548
pushq $0x18
popq %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x15f1
movq %rax, %r14
movq 0x10(%rax), %rdi
movq %rbx, %rsi
callq 0x1559
addq $0x10, %r15
pushq $0x10
popq %rsi
movq %r15, %rdi
callq 0x15f1
movq %rax, %r15
movq 0x8(%rax), %rdi
movq 0x10(%r14), %rcx
leaq -0xa0(%rbp), %r8
movq %r12, %rsi
movq %r13, %rdx
callq 0x28e8
testl %eax, %eax
je 0x149b
leaq 0x2c26(%rip), %rdi      # 0x40bc
callq 0x1548
movq %r15, %rdi
callq 0x173e
movq %rax, %r15
movq %rax, %rdi
callq 0x1080
leaq (%r15,%rax), %r13
addq $-0x4c, %r13
movq %r14, %rdi
callq 0x173e
leaq 0x2c09(%rip), %rdi      # 0x40ce
movq %rax, %rsi
movq -0x40(%rbp), %rdx
xorl %eax, %eax
callq 0x10a0
pushq $0x4c
popq %rbx
pushq $0x1
popq %r14
pushq $0xa
popq %r12
cmpq %r13, %r15
jae 0x1509
movq 0x5af6(%rip), %rax      # 0x6fe0
movq (%rax), %rcx
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x1170
movl %r12d, %edi
callq 0x1030
addq $0x4c, %r15
jmp 0x14de
movq %r15, %rdi
callq 0x1040
pushq $0xa
popq %rdi
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 0x2acd(%rip), %rdi      # 0x4004
xorl %eax, %eax
callq 0x10a0
pushq $0x1
popq %rdi
callq 0x1160
nop