#' Authenticated Encryption
#'
#' Exchange secure messages through curve25519 authenticated encryption.
#'
#' Authenticated encryption implements best practices for secure messaging.
#' It requires that both sender and receiver have a keypair and know each
#' other's public key. Each message gets authenticated with the key of the
#' sender and encrypted with the key of the receiver.
#'
#' Even though public keys are not confidential, you should not exchange them
#' over the same insecure channel you are trying to protect. If the connection
#' is being tampered with, the attacker could simply replace the key with another
#' one to hijack the interaction.
#'
#' Most people share their public key by posting them on their website or on a
#' public keyserver. Another alternative is having your public key signed by a
#' mutually trusted third party. HTTPS does this using Certificate Authorities.
#'
#' @export
#' @useDynLib sodium R_secure_send
#' @rdname messaging
#' @name Authenticated encryption
#' @references \url{https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption}
#' @examples # Bob's keypair:
#' bob_key <- keygen()
#' bob_pubkey <- pubkey(bob_key)
#'
#' # Alice's keypair:
#' alice_key <- keygen()
#' alice_pubkey <- pubkey(alice_key)
#'
#' # Bob sends encrypted message for Alice:
#' msg <- charToRaw("TTIP is evil")
#' ciphertext <- auth_encrypt(msg, bob_key, alice_pubkey)
#'
#' # Alice verifies and decrypts with her key
#' out <- auth_decrypt(ciphertext, alice_key, bob_pubkey)
#' stopifnot(identical(out, msg))
#'
#' # Alice sends encrypted message for Bob
#' msg <- charToRaw("Let's protest")
#' ciphertext <- auth_encrypt(msg, alice_key, bob_pubkey)
#'
#' # Bob verifies and decrypts with his key
#' out <- auth_decrypt(ciphertext, bob_key, alice_pubkey)
#' stopifnot(identical(out, msg))
#' @param msg message to be encrypted
#' @param bin encrypted ciphertext generated by \code{secure_send}
#' @param key your own private key
#' @param pubkey other person's public key
#' @param nonce non-secret unique data to randomize the cipher
auth_encrypt <- function(msg, key, pubkey, nonce = random(24)){
  stopifnot(is.raw(msg))
  stopifnot(is.raw(key))
  stopifnot(is.raw(pubkey))
  stopifnot(is.raw(nonce))
  res <- .Call(R_secure_send, msg, key, pubkey, nonce)
  structure(res, nonce = nonce)
}

#' @export
#' @rdname messaging
#' @useDynLib sodium R_secure_recv
auth_decrypt <- function(bin, key, pubkey, nonce = attr(bin, "nonce")){
  stopifnot(is.raw(bin))
  stopifnot(is.raw(key))
  stopifnot(is.raw(pubkey))
  stopifnot(is.raw(nonce))
  .Call(R_secure_recv, bin, key, pubkey, nonce)
}
