1#' Curve25519 2#' 3#' Curve25519 is a recently added low-level algorithm that can be used both for 4#' diffie-hellman (called X25519) and for signatures (called ED25519). Note that 5#' these functions are only available when building against version 1.1.1 or 6#' newer of the openssl library. The same functions are also available in the 7#' sodium R package. 8#' 9#' @export 10#' @name curve25519 11#' @rdname curve25519 12#' @param x a 32 byte raw vector with (pub)key data 13#' @examples # Generate a keypair 14#' if(openssl_config()$x25519){ 15#' key <- ed25519_keygen() 16#' pubkey <- as.list(key)$pubkey 17#' 18#' # Sign message 19#' msg <- serialize(iris, NULL) 20#' sig <- ed25519_sign(msg, key) 21#' 22#' # Verify the signature 23#' ed25519_verify(msg, sig, pubkey) 24#' 25#' # Diffie Hellman example: 26#' key1 <- x25519_keygen() 27#' key2 <- x25519_keygen() 28#' 29#' # Both parties can derive the same secret 30#' x25519_diffie_hellman(key1, key2$pubkey) 31#' x25519_diffie_hellman(key2, key1$pubkey) 32#' 33#' # Import/export sodium keys 34#' rawkey <- sodium::sig_keygen() 35#' rawpubkey <- sodium::sig_pubkey(rawkey) 36#' key <- read_ed25519_key(rawkey) 37#' pubkey <- read_ed25519_pubkey(rawpubkey) 38#' 39#' # To get the raw key data back for use in sodium 40#' as.list(key)$data 41#' as.list(pubkey)$data 42#' } 43read_ed25519_key <- function(x){ 44 stopifnot(is.raw(x)) 45 if(length(x) == 64) 46 x <- utils::head(x, 32L) 47 stopifnot(length(x) == 32) 48 structure(read_raw_key_ed25519(x), class = c("key", "ed25519")) 49} 50 51#' @export 52#' @rdname curve25519 53read_ed25519_pubkey <- function(x){ 54 stopifnot(is.raw(x)) 55 stopifnot(length(x) == 32) 56 structure(read_raw_pubkey_ed25519(x), class = c("pubkey", "ed25519")) 57} 58 59#' @export 60#' @rdname curve25519 61read_x25519_key <- function(x){ 62 stopifnot(is.raw(x)) 63 if(length(x) == 64) 64 x <- utils::head(x, 32L) 65 stopifnot(length(x) == 32) 66 structure(read_raw_key_x25519(x), class = c("key", "x25519")) 67} 68 69#' @export 70#' @rdname curve25519 71read_x25519_pubkey <- function(x){ 72 stopifnot(is.raw(x)) 73 stopifnot(length(x) == 32) 74 structure(read_raw_pubkey_x25519(x), class = c("pubkey", "x25519")) 75} 76 77#' @export 78#' @rdname curve25519 79#' @param key private key as returned by \code{read_ed25519_key} or \code{ed25519_keygen} 80ed25519_sign <- function(data, key){ 81 stopifnot(is.raw(data)) 82 key <- read_key(key) 83 stopifnot(inherits(key, 'ed25519')) 84 data_sign(data, key) 85} 86 87#' @export 88#' @rdname curve25519 89#' @param data raw vector with data to sign or verify 90#' @param sig raw vector of length 64 with signature as returned by \code{ed25519_sign} 91#' @param pubkey public key as returned by \code{read_ed25519_pubkey} or \code{key$pubkey} 92ed25519_verify <- function(data, sig, pubkey){ 93 stopifnot(is.raw(data)) 94 stopifnot(is.raw(sig)) 95 if(length(sig) != 64) 96 stop("Signature must have length 64") 97 pubkey <- read_pubkey(pubkey) 98 stopifnot(inherits(pubkey, 'ed25519')) 99 data_verify(data, sig, pubkey) 100} 101 102#' @export 103#' @rdname curve25519 104x25519_diffie_hellman <- function(key, pubkey){ 105 key <- read_key(key) 106 pubkey <- read_pubkey(pubkey) 107 stopifnot(inherits(key, 'x25519')) 108 stopifnot(inherits(pubkey, 'x25519')) 109 ec_dh(key, pubkey) 110} 111 112#' @useDynLib openssl R_read_raw_key_ed25519 113read_raw_key_ed25519 <- function(x){ 114 .Call(R_read_raw_key_ed25519, x) 115} 116 117#' @useDynLib openssl R_read_raw_pubkey_ed25519 118read_raw_pubkey_ed25519 <- function(x){ 119 .Call(R_read_raw_pubkey_ed25519, x) 120} 121 122#' @useDynLib openssl R_read_raw_key_x25519 123read_raw_key_x25519 <- function(x){ 124 .Call(R_read_raw_key_x25519, x) 125} 126 127#' @useDynLib openssl R_read_raw_pubkey_x25519 128read_raw_pubkey_x25519 <- function(x){ 129 .Call(R_read_raw_pubkey_x25519, x) 130} 131 132#' @useDynLib openssl R_write_raw_key 133write_raw_key <- function(x){ 134 .Call(R_write_raw_key, x) 135} 136 137#' @useDynLib openssl R_write_raw_pubkey 138write_raw_pubkey <- function(x){ 139 .Call(R_write_raw_pubkey, x) 140} 141 142#' @useDynLib openssl R_data_sign 143data_sign <- function(data, key){ 144 .Call(R_data_sign, data, key) 145} 146 147#' @useDynLib openssl R_data_verify 148data_verify <- function(data, sig, pubkey){ 149 .Call(R_data_verify, data, sig, pubkey) 150} 151