diff --git a/NAMESPACE b/NAMESPACE index ab0c16c..d43854e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,6 +27,7 @@ export(sig_sign) export(sig_verify) export(simple_decrypt) export(simple_encrypt) +export(xchacha20) export(xsalsa20) useDynLib(sodium,R_auth_sha256) useDynLib(sodium,R_auth_sha512) @@ -58,5 +59,6 @@ useDynLib(sodium,R_sodium_bin2hex) useDynLib(sodium,R_sodium_hex2bin) useDynLib(sodium,R_stream_chacha20) useDynLib(sodium,R_stream_salsa20) +useDynLib(sodium,R_stream_xchacha20) useDynLib(sodium,R_stream_xsalsa20) useDynLib(sodium,R_xor) diff --git a/R/stream.R b/R/stream.R index c8abbea..65a2f2b 100644 --- a/R/stream.R +++ b/R/stream.R @@ -48,6 +48,7 @@ #' # Other stream ciphers #' stream <- salsa20(10000, key, nonce8) #' stream <- xsalsa20(10000, key, random(24)) +#' stream <- xchacha20(10000, key, random(24)) #' chacha20 <- function(size, key, nonce){ stopifnot(is.numeric(size)) @@ -56,6 +57,16 @@ chacha20 <- function(size, key, nonce){ .Call(R_stream_chacha20, size, key, nonce) } +#' @export +#' @useDynLib sodium R_stream_xchacha20 +#' @rdname stream +xchacha20 <- function(size, key, nonce){ + stopifnot(is.numeric(size)) + stopifnot(is.raw(key)) + stopifnot(is.raw(nonce)) + .Call(R_stream_xchacha20, size, key, nonce) +} + #' @export #' @useDynLib sodium R_stream_salsa20 #' @rdname stream diff --git a/man/stream.Rd b/man/stream.Rd index 37ededa..e28bbbf 100644 --- a/man/stream.Rd +++ b/man/stream.Rd @@ -4,12 +4,15 @@ \alias{Stream ciphers} \alias{chacha20} \alias{stream} +\alias{xchacha20} \alias{salsa20} \alias{xsalsa20} \title{Stream Ciphers} \usage{ chacha20(size, key, nonce) +xchacha20(size, key, nonce) + salsa20(size, key, nonce) xsalsa20(size, key, nonce) @@ -63,6 +66,7 @@ stopifnot(identical(out, message)) # Other stream ciphers stream <- salsa20(10000, key, nonce8) stream <- xsalsa20(10000, key, random(24)) +stream <- xchacha20(10000, key, random(24)) } \references{ diff --git a/src/stream.c b/src/stream.c index d0adebd..291ad8a 100644 --- a/src/stream.c +++ b/src/stream.c @@ -12,6 +12,17 @@ SEXP R_stream_chacha20(SEXP n, SEXP key, SEXP nonce){ return res; } +SEXP R_stream_xchacha20(SEXP n, SEXP key, SEXP nonce){ + if(LENGTH(key) != crypto_stream_xchacha20_KEYBYTES) + Rf_error("Invalid key, must be exactly %d bytes", crypto_stream_xchacha20_KEYBYTES); + if(LENGTH(nonce) != crypto_stream_xchacha20_NONCEBYTES) + Rf_error("Invalid nonce, must be exactly %d bytes", crypto_stream_xchacha20_NONCEBYTES); + unsigned long long clen = (unsigned long long) asReal(n); + SEXP res = allocVector(RAWSXP, clen); + crypto_stream_xchacha20(RAW(res), clen, RAW(nonce), RAW(key)); + return res; +} + SEXP R_stream_salsa20(SEXP n, SEXP key, SEXP nonce){ if(LENGTH(key) != crypto_stream_salsa20_KEYBYTES) Rf_error("Invalid key, must be exactly %d bytes", crypto_stream_salsa20_KEYBYTES);