diff --git a/DESCRIPTION b/DESCRIPTION
index 9446a97..900b74e 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,7 +1,7 @@
Package: secretbase
Type: Package
Title: Cryptographic Hash and Extendable-Output Functions
-Version: 0.3.0.9007
+Version: 0.3.0.9008
Description: Fast and memory-efficient streaming hash functions. Performs direct
hashing of strings, raw bytes, and files potentially larger than memory, as
well as hashing in-memory objects through R's serialization mechanism,
diff --git a/NAMESPACE b/NAMESPACE
index 586a474..0be9c2c 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -3,5 +3,4 @@
export(sha256)
export(sha3)
export(siphash13)
-export(siphash24)
useDynLib(secretbase, .registration = TRUE)
diff --git a/NEWS.md b/NEWS.md
index 3d61ab0..36ea353 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,4 +1,4 @@
-# secretbase 0.3.0.9007 (development)
+# secretbase 0.3.0.9008 (development)
* Adds HMAC generation to `sha256()`.
* Adds SipHash pseudo-random function (PRF) as a fast, cryptographically-strong keyed hash.
diff --git a/R/base.R b/R/base.R
index 931409a..0e5750a 100644
--- a/R/base.R
+++ b/R/base.R
@@ -147,9 +147,8 @@ sha256 <- function(x, key = NULL, convert = TRUE, file)
#' SipHash Pseudorandom Function
#'
#' Returns a fast, cryptographically-strong SipHash keyed hash of the supplied
-#' object or file. SipHash-1-3 is optimised for performance, whereas
-#' SipHash-2-4 is recommended for security. Note: SipHash is not a
-#' cryptographic hash algorithm.
+#' object or file. SipHash-1-3 is optimised for performance. Note: SipHash
+#' is not a cryptographic hash algorithm.
#'
#' @inheritParams sha3
#' @param key [default NULL] a character string or raw vector comprising the 16
@@ -179,11 +178,11 @@ sha256 <- function(x, key = NULL, convert = TRUE, file)
#' # SipHash-1-3 hash as raw vector:
#' siphash13("secret base", convert = FALSE)
#'
-#' # SipHash-2-4 hash using a character string key:
-#' siphash24("secret", key = "base")
+#' # SipHash-1-3 hash using a character string key:
+#' siphash13("secret", key = "base")
#'
-#' # SipHash-2-4 hash using a raw vector key:
-#' siphash24("secret", key = charToRaw("base"))
+#' # SipHash-1-3 hash using a raw vector key:
+#' siphash13("secret", key = charToRaw("base"))
#'
#' # SipHash-1-3 hash a file:
#' file <- tempfile(); cat("secret base", file = file)
@@ -195,10 +194,3 @@ sha256 <- function(x, key = NULL, convert = TRUE, file)
siphash13 <- function(x, key = NULL, convert = TRUE, file)
if (missing(file)) .Call(secretbase_siphash13, x, key, convert) else
.Call(secretbase_siphash13_file, file, key, convert)
-
-#' @rdname siphash13
-#' @export
-#'
-siphash24 <- function(x, key = NULL, convert = TRUE, file)
- if (missing(file)) .Call(secretbase_siphash24, x, key, convert) else
- .Call(secretbase_siphash24_file, file, key, convert)
diff --git a/README.Rmd b/README.Rmd
index 4613d66..868b1e0 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -47,14 +47,16 @@ install.packages("secretbase", repos = "https://shikokuchuo.r-universe.dev")
### Quick Start
-#### SHA-3 and XOF usage:
+```{r secretbase}
+library(secretbase)
+```
+
+#### SHA-3
- For the SHA-3 cryptographic hash algorithm, specify 'bits' as `224`, `256`, `384` or `512`
- For the SHAKE256 extendable-output function (XOF), specify any other bit length
-```{r secretbase}
-library(secretbase)
-
+```{r sha3}
sha3("secret base")
sha3("secret base", convert = FALSE)
@@ -63,9 +65,10 @@ sha3("秘密の基地の中", bits = 512)
```
-#### Hash arbitrary R objects:
+#### Hash arbitrary R objects
- - Uses memory-efficient 'streaming' serialization, without allocation of the serialized object
+ - Character strings and raw vectors (without attributes) are hashed 'as is'
+ - Other objects are hashed using memory-efficient 'streaming' serialization, without allocation of the serialized object
- Portable as always uses R serialization version 3 big-endian representation, skipping headers (which contain R version and native encoding information)
```{r streaming}
@@ -74,7 +77,7 @@ sha3(data.frame(a = 1, b = 2), bits = 160)
sha3(NULL)
```
-#### Hash files:
+#### Hash files
- Performed in a streaming fashion, accepting files larger than memory
@@ -86,7 +89,7 @@ sha3(file = file)
unlink(file)
```
-#### Hash to integer:
+#### Hash to integer
- Specify 'convert' as `NA` (and 'bits' as `32` for a single integer value)
- May be supplied as deterministic random seeds for R's pseudo random number generators (RNGs)
@@ -99,24 +102,25 @@ sha3("秘密の基地の中", bits = 32, convert = NA)
For use in parallel computing, this is a valid method for reducing to a negligible probability that RNGs in each process may overlap. This may be especially suitable when first-best alternatives such as using recursive streams are too expensive or unable to preserve reproducibility. [2]
-#### Generating a SHA-256 HMAC:
+#### SHA-256
-- Use `sha256()` passing a character string or raw vector to 'key'.
+```{r sha256}
+sha256("secret base")
+```
+
+- For a SHA-256 HMAC, pass a character string or raw vector to 'key'
```{r hmac}
sha256("secret base", key = "秘密の基地の中")
```
-#### Using SipHash:
+#### SipHash
-- SipHash is a fast, cryptographically-strong keyed hash.
-- Pass a character string or raw vector to 'key'. Up to 16 bytes (128 bits) of the key data is used.
-- SipHash-1-3 is optimized for performance; SipHash-2-4 recommended for security.
+- SipHash-1-3 is optimized for performance
+- Pass a character string or raw vector to 'key' - up to 16 bytes (128 bits) of the key data is used
```{r siphash}
siphash13("secret base", key = charToRaw("秘密の基地の中"))
-
-siphash24("secret base", key = charToRaw("秘密の基地の中"))
```
### References
diff --git a/README.md b/README.md
index 0f23bbf..c4f218e 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,11 @@ install.packages("secretbase", repos = "https://shikokuchuo.r-universe.dev")
### Quick Start
-#### SHA-3 and XOF usage:
+``` r
+library(secretbase)
+```
+
+#### SHA-3
- For the SHA-3 cryptographic hash algorithm, specify ‘bits’ as `224`,
`256`, `384` or `512`
@@ -65,8 +69,6 @@ install.packages("secretbase", repos = "https://shikokuchuo.r-universe.dev")
bit length
``` r
-library(secretbase)
-
sha3("secret base")
#> [1] "a721d57570e7ce366adee2fccbe9770723c6e3622549c31c7cab9dbb4a795520"
@@ -78,10 +80,12 @@ sha3("秘密の基地の中", bits = 512)
#> [1] "e30cdc73f6575c40d55b5edc8eb4f97940f5ca491640b41612e02a05f3e59dd9c6c33f601d8d7a8e2ca0504b8c22f7bc69fa8f10d7c01aab392781ff4ae1e610"
```
-#### Hash arbitrary R objects:
+#### Hash arbitrary R objects
-- Uses memory-efficient ‘streaming’ serialization, without allocation of
- the serialized object
+- Character strings and raw vectors (without attributes) are hashed ‘as
+ is’
+- Other objects are hashed using memory-efficient ‘streaming’
+ serialization, without allocation of the serialized object
- Portable as always uses R serialization version 3 big-endian
representation, skipping headers (which contain R version and native
encoding information)
@@ -94,7 +98,7 @@ sha3(NULL)
#> [1] "b3e37e4c5def1bfb2841b79ef8503b83d1fed46836b5b913d7c16de92966dcee"
```
-#### Hash files:
+#### Hash files
- Performed in a streaming fashion, accepting files larger than memory
@@ -104,7 +108,7 @@ sha3(file = file)
#> [1] "a721d57570e7ce366adee2fccbe9770723c6e3622549c31c7cab9dbb4a795520"
```
-#### Hash to integer:
+#### Hash to integer
- Specify ‘convert’ as `NA` (and ‘bits’ as `32` for a single integer
value)
@@ -126,29 +130,29 @@ be especially suitable when first-best alternatives such as using
recursive streams are too expensive or unable to preserve
reproducibility. \[2\]
-#### Generating a SHA-256 HMAC:
+#### SHA-256
-- Use `sha256()` passing a character string or raw vector to ‘key’.
+``` r
+sha256("secret base")
+#> [1] "1951c1ca3d50e95e6ede2b1c26fefd0f0e8eba1e51a837f8ccefb583a2b686fe"
+```
+
+- For a SHA-256 HMAC, pass a character string or raw vector to ‘key’
``` r
sha256("secret base", key = "秘密の基地の中")
#> [1] "ec58099ab21325e792bef8f1aafc0a70e1a7227463cfc410931112705d753392"
```
-#### Using SipHash:
+#### SipHash
-- SipHash is a fast, cryptographically-strong keyed hash.
-- Pass a character string or raw vector to ‘key’. Up to 16 bytes (128
- bits) of the key data is used.
-- SipHash-1-3 is optimized for performance; SipHash-2-4 recommended for
- security.
+- SipHash-1-3 is optimized for performance
+- Pass a character string or raw vector to ‘key’ - up to 16 bytes (128
+ bits) of the key data is used
``` r
siphash13("secret base", key = charToRaw("秘密の基地の中"))
#> [1] "a1f0a751892cc7dd"
-
-siphash24("secret base", key = charToRaw("秘密の基地の中"))
-#> [1] "1bedfe817cac0562"
```
### References
diff --git a/man/siphash13.Rd b/man/siphash13.Rd
index 9899b51..fd73a78 100644
--- a/man/siphash13.Rd
+++ b/man/siphash13.Rd
@@ -2,12 +2,9 @@
% Please edit documentation in R/base.R
\name{siphash13}
\alias{siphash13}
-\alias{siphash24}
\title{SipHash Pseudorandom Function}
\usage{
siphash13(x, key = NULL, convert = TRUE, file)
-
-siphash24(x, key = NULL, convert = TRUE, file)
}
\arguments{
\item{x}{object to hash. A character string or raw vector (without
@@ -35,9 +32,8 @@ A character string, raw or integer vector depending on 'convert'.
}
\description{
Returns a fast, cryptographically-strong SipHash keyed hash of the supplied
- object or file. SipHash-1-3 is optimised for performance, whereas
- SipHash-2-4 is recommended for security. Note: SipHash is not a
- cryptographic hash algorithm.
+ object or file. SipHash-1-3 is optimised for performance. Note: SipHash
+ is not a cryptographic hash algorithm.
}
\details{
The SipHash family of cryptographically-strong pseudorandom
@@ -59,11 +55,11 @@ siphash13("secret base")
# SipHash-1-3 hash as raw vector:
siphash13("secret base", convert = FALSE)
-# SipHash-2-4 hash using a character string key:
-siphash24("secret", key = "base")
+# SipHash-1-3 hash using a character string key:
+siphash13("secret", key = "base")
-# SipHash-2-4 hash using a raw vector key:
-siphash24("secret", key = charToRaw("base"))
+# SipHash-1-3 hash using a raw vector key:
+siphash13("secret", key = charToRaw("base"))
# SipHash-1-3 hash a file:
file <- tempfile(); cat("secret base", file = file)
diff --git a/src/init.c b/src/init.c
index 412f5eb..c5031ad 100644
--- a/src/init.c
+++ b/src/init.c
@@ -25,8 +25,6 @@ static const R_CallMethodDef callMethods[] = {
{"secretbase_sha256_file", (DL_FUNC) &secretbase_sha256_file, 3},
{"secretbase_siphash13", (DL_FUNC) &secretbase_siphash13, 3},
{"secretbase_siphash13_file", (DL_FUNC) &secretbase_siphash13_file, 3},
- {"secretbase_siphash24", (DL_FUNC) &secretbase_siphash24, 3},
- {"secretbase_siphash24_file", (DL_FUNC) &secretbase_siphash24_file, 3},
{NULL, NULL, 0}
};
diff --git a/src/secret.h b/src/secret.h
index a865eda..752d211 100644
--- a/src/secret.h
+++ b/src/secret.h
@@ -93,7 +93,6 @@ typedef struct secretbase_sha256_context {
typedef struct secretbase_siphash_context {
int skip;
- unsigned N;
CSipHash *ctx;
} secretbase_siphash_context;
diff --git a/src/secret3.c b/src/secret3.c
index 758c4d4..a534102 100644
--- a/src/secret3.c
+++ b/src/secret3.c
@@ -107,7 +107,7 @@ void c_siphash_init_nokey(CSipHash *state) {
}
-static inline void c_siphash_append_N(CSipHash *state, const uint8_t *bytes, size_t n_bytes, unsigned N) {
+static inline void c_siphash_append(CSipHash *state, const uint8_t *bytes, size_t n_bytes) {
const uint8_t *end = bytes + n_bytes;
size_t left = state->n_bytes & 7;
@@ -123,8 +123,7 @@ static inline void c_siphash_append_N(CSipHash *state, const uint8_t *bytes, siz
return;
state->v3 ^= state->padding;
- for (unsigned i = 0; i < N; i++)
- c_siphash_sipround(state);
+ c_siphash_sipround(state);
state->v0 ^= state->padding;
state->padding = 0;
@@ -136,8 +135,7 @@ static inline void c_siphash_append_N(CSipHash *state, const uint8_t *bytes, siz
m = c_siphash_read_le64(bytes);
state->v3 ^= m;
- for (unsigned i = 0; i < N; i++)
- c_siphash_sipround(state);
+ c_siphash_sipround(state);
state->v0 ^= m;
}
@@ -163,20 +161,19 @@ static inline void c_siphash_append_N(CSipHash *state, const uint8_t *bytes, siz
}
-static inline uint64_t c_siphash_finalize_NM(CSipHash *state, unsigned N, unsigned M) {
+static inline uint64_t c_siphash_finalize(CSipHash *state) {
uint64_t b;
b = state->padding | (((uint64_t) state->n_bytes) << 56);
state->v3 ^= b;
- for (unsigned i = 0; i < N; i++)
- c_siphash_sipround(state);
+ c_siphash_sipround(state);
state->v0 ^= b;
state->v2 ^= 0xff;
- for (unsigned i = 0; i < M; i++)
+ for (unsigned i = 0; i < 3; i++)
c_siphash_sipround(state);
return state->v0 ^ state->v1 ^ state->v2 ^ state->v3;
@@ -188,11 +185,11 @@ static inline uint64_t c_siphash_finalize_NM(CSipHash *state, unsigned N, unsign
static void hash_bytes(R_outpstream_t stream, void *src, int len) {
secretbase_siphash_context *sctx = (secretbase_siphash_context *) stream->data;
- sctx->skip ? (void) sctx->skip-- : c_siphash_append_N(sctx->ctx, (uint8_t *) src, (size_t) len, sctx->N);
+ sctx->skip ? (void) sctx->skip-- : c_siphash_append(sctx->ctx, (uint8_t *) src, (size_t) len);
}
-static void hash_file(CSipHash *ctx, const SEXP x, const unsigned N) {
+static void hash_file(CSipHash *ctx, const SEXP x) {
if (TYPEOF(x) != STRSXP)
Rf_error("'file' must be specified as a character string");
@@ -204,10 +201,8 @@ static void hash_file(CSipHash *ctx, const SEXP x, const unsigned N) {
if ((f = fopen(file, "rb")) == NULL)
Rf_error("file not found or no read permission at '%s'", file);
- setbuf(f, NULL);
-
while ((cur = fread(buf, sizeof(char), SB_BUF_SIZE, f))) {
- c_siphash_append_N(ctx, buf, cur, N);
+ c_siphash_append(ctx, buf, cur);
}
if (ferror(f)) {
@@ -218,19 +213,19 @@ static void hash_file(CSipHash *ctx, const SEXP x, const unsigned N) {
}
-static void hash_object(CSipHash *ctx, const SEXP x, const unsigned N) {
+static void hash_object(CSipHash *ctx, const SEXP x) {
switch (TYPEOF(x)) {
case STRSXP:
if (XLENGTH(x) == 1 && ATTRIB(x) == R_NilValue) {
const char *s = CHAR(STRING_ELT(x, 0));
- c_siphash_append_N(ctx, (uint8_t *) s, strlen(s), N);
+ c_siphash_append(ctx, (uint8_t *) s, strlen(s));
return;
}
break;
case RAWSXP:
if (ATTRIB(x) == R_NilValue) {
- c_siphash_append_N(ctx, (uint8_t *) STDVEC_DATAPTR(x), (size_t) XLENGTH(x), N);
+ c_siphash_append(ctx, (uint8_t *) STDVEC_DATAPTR(x), (size_t) XLENGTH(x));
return;
}
break;
@@ -238,7 +233,6 @@ static void hash_object(CSipHash *ctx, const SEXP x, const unsigned N) {
secretbase_siphash_context sctx;
sctx.skip = SB_SERIAL_HEADERS;
- sctx.N = N;
sctx.ctx = ctx;
struct R_outpstream_st output_stream;
@@ -257,8 +251,7 @@ static void hash_object(CSipHash *ctx, const SEXP x, const unsigned N) {
}
static SEXP secretbase_siphash_impl(const SEXP x, const SEXP key, const SEXP convert,
- void (*const hash_func)(CSipHash *, SEXP, unsigned),
- const unsigned N, const unsigned M) {
+ void (*const hash_func)(CSipHash *, SEXP)) {
const int conv = LOGICAL(convert)[0];
uint64_t hash;
@@ -286,9 +279,8 @@ static SEXP secretbase_siphash_impl(const SEXP x, const SEXP key, const SEXP con
memcpy(seed, data, klen < SB_SKEY_SIZE ? klen : SB_SKEY_SIZE);
c_siphash_init(&ctx, seed);
}
- hash_func(&ctx, x, N);
- hash = c_siphash_finalize_NM(&ctx, N, M);
- clear_buffer(&ctx, sizeof(CSipHash));
+ hash_func(&ctx, x);
+ hash = c_siphash_finalize(&ctx);
return hash_to_sexp((unsigned char *) &hash, SB_SIPH_SIZE, conv);
@@ -298,24 +290,12 @@ static SEXP secretbase_siphash_impl(const SEXP x, const SEXP key, const SEXP con
SEXP secretbase_siphash13(SEXP x, SEXP key, SEXP convert) {
- return secretbase_siphash_impl(x, key, convert, hash_object, 1u, 3u);
+ return secretbase_siphash_impl(x, key, convert, hash_object);
}
SEXP secretbase_siphash13_file(SEXP x, SEXP key, SEXP convert) {
- return secretbase_siphash_impl(x, key, convert, hash_file, 1u, 3u);
-
-}
-
-SEXP secretbase_siphash24(SEXP x, SEXP key, SEXP convert) {
-
- return secretbase_siphash_impl(x, key, convert, hash_object, 2u, 4u);
-
-}
-
-SEXP secretbase_siphash24_file(SEXP x, SEXP key, SEXP convert) {
-
- return secretbase_siphash_impl(x, key, convert, hash_file, 2u, 4u);
+ return secretbase_siphash_impl(x, key, convert, hash_file);
}
diff --git a/tests/tests.R b/tests/tests.R
index 7b821ff..f2168d0 100644
--- a/tests/tests.R
+++ b/tests/tests.R
@@ -70,11 +70,9 @@ test_equal(sha256("secret base", key = character()), "6bc4693e2025baadf345dd0b13
test_error(sha256("secret base", key = list()), "'key' must be a character string, raw vector or NULL")
# SipHash tests:
test_equal(siphash13(""), "2c530c1562a7fbd1")
-test_equal(siphash24(""), "d70077739d4b921e")
test_equal(siphash13("", key = ""), "2c530c1562a7fbd1")
test_equal(siphash13("", key = character()), "2c530c1562a7fbd1")
test_equal(siphash13("secret base"), "48c60a316babef0e")
-test_equal(siphash24("secret base"), "bdb6899a934fdf5a")
test_equal(siphash13("secret base", key = "secret base"), "2cf27a8f22f02e59")
test_equal(siphash13("secret base", key = c("secret base", "more")), "2cf27a8f22f02e59")
test_equal(siphash13("secret base", key = as.raw(1L)), "5ecd894f7d269521")
@@ -88,14 +86,12 @@ test_equal(siphash13(NULL), "08d5f59e833de599")
test_equal(siphash13(substitute()), "c8cadc1ab377142a")
test_equal(siphash13(`class<-`(siphash13(character(), convert = FALSE), "hash")), "39124d8b9643418a")
test_error(siphash13(file = NULL), "'file' must be specified as a character string")
-hash_func <- function(file, string, func) {
+hash_func <- function(file, string) {
on.exit(unlink(file))
cat(string, file = file)
- func(file = file)
+ siphash13(file = file)
}
-test_equal(hash_func(tempfile(), "secret base", siphash13), "48c60a316babef0e")
-test_equal(hash_func(tempfile(), "secret base", siphash24), "bdb6899a934fdf5a")
-test_error(hash_func("", "", siphash13), "file not found or no read permission")
-test_error(hash_func("", "", siphash24), "file not found or no read permission")
+test_equal(hash_func(tempfile(), "secret base"), "48c60a316babef0e")
+test_error(hash_func("", ""), "file not found or no read permission")
if (.Platform[["OS.type"]] == "unix") test_error(siphash13(file = "~/"), "file read error")
test_equal(siphash13(paste(1:888, collapse = "")), "8337f50b05209c40")