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