// File: shanet[P]Crypto-Example/crypto_example.cpp
// Function: encryptRsa(Crypto*)
void encryptRsa(Crypto *crypto) {
  // Get the message to encrypt
  string message = getMessage("Message to RSA encrypt: ");

  // Encrypt the message with RSA
  unsigned char *encryptedMessage = NULL;
  unsigned char *encryptedKey;
  unsigned char *iv;
  size_t encryptedKeyLength;
  size_t ivLength;

  // +1 on the string length argument because we want to encrypt the NUL terminator too
  int encryptedMessageLength = crypto->rsaEncrypt((const unsigned char*)message.c_str(), message.size()+1,
    &encryptedMessage, &encryptedKey, &encryptedKeyLength, &iv, &ivLength);

  if(encryptedMessageLength == -1) {
    fprintf(stderr, "Encryption failed\n");
    return;
  }

  // Print the encrypted message as a base64 string
  char* b64Message = base64Encode(encryptedMessage, encryptedMessageLength);
  printf("Encrypted message: %s\n", b64Message);

  // Decrypt the message
  char *decryptedMessage = NULL;

  int decryptedMessageLength = crypto->rsaDecrypt(encryptedMessage, (size_t)encryptedMessageLength,
    encryptedKey, encryptedKeyLength, iv, ivLength, (unsigned char**)&decryptedMessage);

  if(decryptedMessageLength == -1) {
    fprintf(stderr, "Decryption failed\n");
    return;
  }

  printf("Decrypted message: %s\n", decryptedMessage);

  // Clean up
  free(encryptedMessage);
  free(decryptedMessage);
  free(encryptedKey);
  free(iv);
  free(b64Message);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
leaq 0xa0a(%rip), %rsi       # 0x4070
leaq -0x28(%rbp), %rdi
movq %rdi, -0x98(%rbp)
callq 0x39d0
movq -0x98(%rbp), %rdi
movq $0x0, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x90(%rbp)
callq 0x2100
movq -0x98(%rbp), %rdi
movq %rax, -0x88(%rbp)
callq 0x2190
movq -0x90(%rbp), %rdi
movq -0x88(%rbp), %rsi
movq %rax, %rdx
incq %rdx
movq %rsp, %rax
leaq -0x50(%rbp), %rcx
movq %rcx, 0x8(%rax)
leaq -0x40(%rbp), %rcx
movq %rcx, (%rax)
leaq -0x30(%rbp), %rcx
leaq -0x38(%rbp), %r8
leaq -0x48(%rbp), %r9
callq 0x2cb0
movl %eax, -0x80(%rbp)
jmp 0x36e4
movl -0x80(%rbp), %eax
movl %eax, -0x54(%rbp)
cmpl $-0x1, -0x54(%rbp)
jne 0x372e
movq 0x28d9(%rip), %rax      # 0x5fd0
movq (%rax), %rdi
leaq 0x988(%rip), %rsi       # 0x4089
movb $0x0, %al
callq 0x2300
movl $0x1, -0x68(%rbp)
jmp 0x381a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x2140
jmp 0x382c
movq -0x30(%rbp), %rdi
movslq -0x54(%rbp), %rsi
callq 0x2580
movq %rax, -0xa0(%rbp)
jmp 0x3744
movq -0xa0(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rsi
leaq 0x942(%rip), %rdi       # 0x409c
xorl %eax, %eax
callq 0x2030
jmp 0x3763
movq $0x0, -0x78(%rbp)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
movslq -0x54(%rbp), %rdx
movq -0x38(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x40(%rbp), %r9
movq -0x50(%rbp), %r10
movq %rsp, %rax
leaq -0x78(%rbp), %r11
movq %r11, 0x8(%rax)
movq %r10, (%rax)
callq 0x2e40
movl %eax, -0xa4(%rbp)
jmp 0x37a2
movl -0xa4(%rbp), %eax
movl %eax, -0x7c(%rbp)
cmpl $-0x1, -0x7c(%rbp)
jne 0x37d2
movq 0x2818(%rip), %rax      # 0x5fd0
movq (%rax), %rdi
leaq 0x8f1(%rip), %rsi       # 0x40b3
movb $0x0, %al
callq 0x2300
movl $0x1, -0x68(%rbp)
jmp 0x381a
movq -0x78(%rbp), %rsi
leaq 0x8e9(%rip), %rdi       # 0x40c6
xorl %eax, %eax
callq 0x2030
jmp 0x37e6
movq -0x30(%rbp), %rdi
callq 0x22a0
movq -0x78(%rbp), %rdi
callq 0x22a0
movq -0x38(%rbp), %rdi
callq 0x22a0
movq -0x40(%rbp), %rdi
callq 0x22a0
movq -0x70(%rbp), %rdi
callq 0x22a0
movl $0x0, -0x68(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x2140
addq $0xc0, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x23b0
nopw %cs:(%rax,%rax)