Skip to content

Commit

Permalink
clean up function pointer defs; simplify by stack allocating XXH64 state
Browse files Browse the repository at this point in the history
  • Loading branch information
shikokuchuo committed Feb 17, 2024
1 parent daf8b0c commit edd34e5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 67 deletions.
37 changes: 30 additions & 7 deletions src/secret.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,23 +205,45 @@ static void clear_buffer(void *buf, size_t sz) {
static void hash_bytes(R_outpstream_t stream, void *src, int len) {

secretbase_context *sctx = (secretbase_context *) stream->data;
sctx->skip ? (void) sctx->skip-- : sctx->func(sctx->ctx, (uint8_t *) src, (size_t) len);
sctx->skip ? (void) sctx->skip-- : sctx->update(sctx->ctx, (uint8_t *) src, (size_t) len);

}

void hash_object(update_func update, void *ctx, const SEXP x) {
void hash_file(const update_func update, void *ctx, const SEXP x) {

const char *file = R_ExpandFileName(CHAR(STRING_ELT(x, 0)));
unsigned char buf[SB_BUF_SIZE];
FILE *fp;
size_t cur;

if ((fp = fopen(file, "rb")) == NULL)
Rf_error("file not found or no read permission at '%s'", file);

while ((cur = fread(buf, sizeof(char), SB_BUF_SIZE, fp))) {
update(ctx, buf, cur);
}

if (ferror(fp)) {
fclose(fp);
Rf_error("file read error at '%s'", file);
}
fclose(fp);

}

void hash_object(const update_func update, void *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));
update(ctx, (const uint8_t *) s, strlen(s));
update(ctx, (uint8_t *) s, strlen(s));
return;
}
break;
case RAWSXP:
if (ATTRIB(x) == R_NilValue) {
update(ctx, (const uint8_t *) STDVEC_DATAPTR(x), (size_t) XLENGTH(x));
update(ctx, (uint8_t *) STDVEC_DATAPTR(x), (size_t) XLENGTH(x));
return;
}
break;
Expand All @@ -230,7 +252,7 @@ void hash_object(update_func update, void *ctx, const SEXP x) {
secretbase_context sctx;
sctx.skip = SB_SERIAL_HEADERS;
sctx.ctx = ctx;
sctx.func = update;
sctx.update = update;

struct R_outpstream_st output_stream;
R_InitOutPStream(
Expand Down Expand Up @@ -270,7 +292,8 @@ SEXP hash_to_sexp(unsigned char *buf, size_t sz, int conv) {

}

static SEXP secretbase_sha3_impl(const SEXP x, const SEXP bits, const SEXP convert, hash_func func) {
static SEXP secretbase_sha3_impl(const SEXP x, const SEXP bits, const SEXP convert,
const hash_func hfunc) {

const int conv = LOGICAL(convert)[0];
const int bt = Rf_asInteger(bits);
Expand All @@ -288,7 +311,7 @@ static SEXP secretbase_sha3_impl(const SEXP x, const SEXP bits, const SEXP conve
mbedtls_sha3_context ctx;
mbedtls_sha3_init(&ctx);
mbedtls_sha3_starts(&ctx, id);
func((update_func) mbedtls_sha3_update, &ctx, x);
hfunc((update_func) mbedtls_sha3_update, &ctx, x);
mbedtls_sha3_finish(&ctx, buf, sz);
clear_buffer(&ctx, sizeof(mbedtls_sha3_context));

Expand Down
12 changes: 6 additions & 6 deletions src/secret.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ typedef struct mbedtls_sha3_context {
uint16_t max_block_size;
} mbedtls_sha3_context;

typedef void (*update_func)(void *, const uint8_t *, size_t);
typedef void (*hash_func)(const update_func, void *, SEXP);

typedef struct secretbase_context {
int skip;
void *ctx;
void (*func)(void *, const uint8_t *, size_t);
update_func update;
} secretbase_context;

typedef void (*const update_func)(void *, const uint8_t *, size_t);
typedef void (*const hash_func)(update_func, void *, SEXP);

void hash_object(update_func, void *, const SEXP);
void hash_file(update_func, void *, const SEXP);
void hash_object(const update_func, void *, const SEXP);
void hash_file(const update_func, void *, const SEXP);
SEXP hash_to_sexp(unsigned char *, size_t, int);

SEXP secretbase_sha3(SEXP, SEXP, SEXP);
Expand Down
61 changes: 7 additions & 54 deletions src/secret2.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,11 @@
#if defined (__GNUC__)
# define XXH_CONSTF __attribute__((const))
# define XXH_PUREF __attribute__((pure))
# define XXH_MALLOCF __attribute__((malloc))
#else
# define XXH_CONSTF /* disable */
# define XXH_PUREF
# define XXH_MALLOCF
#endif

typedef enum {
XXH_OK = 0, /*!< OK */
XXH_ERROR /*!< Error */
} XXH_errorcode;

#ifdef __has_attribute
# define XXH_HAS_ATTRIBUTE(x) __has_attribute(x)
#else
Expand Down Expand Up @@ -104,10 +97,6 @@ typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
# define XXH_FORCE_MEMORY_ACCESS 1
#endif

static XXH_MALLOCF void* XXH_malloc(size_t s) { return malloc(s); }

static void XXH_free(void* p) { free(p); }

static void* XXH_memcpy(void* dest, const void* src, size_t size)
{
return memcpy(dest,src,size);
Expand Down Expand Up @@ -317,26 +306,14 @@ XXH64_finalize(xxh_u64 hash, const xxh_u8* ptr, size_t len)
return XXH64_avalanche(hash);
}

XXH64_state_t* XXH64_createState(void)
{
return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
}

XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
{
XXH_free(statePtr);
return XXH_OK;
}

XXH_errorcode XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed)
void XXH64_reset(XXH_NOESCAPE XXH64_state_t* statePtr, XXH64_hash_t seed)
{
XXH_ASSERT(statePtr != NULL);
memset(statePtr, 0, sizeof(*statePtr));
statePtr->v[0] = seed + XXH_PRIME64_1 + XXH_PRIME64_2;
statePtr->v[1] = seed + XXH_PRIME64_2;
statePtr->v[2] = seed + 0;
statePtr->v[3] = seed - XXH_PRIME64_1;
return XXH_OK;
}

void XXH64_update (XXH_NOESCAPE XXH64_state_t* state, XXH_NOESCAPE const void* input, size_t len)
Expand Down Expand Up @@ -414,43 +391,19 @@ void XXH64_canonicalFromHash(XXH_NOESCAPE unsigned char* dst, XXH64_hash_t hash)

// secretbase - internals ------------------------------------------------------

void hash_file(update_func update, void *ctx, const SEXP x) {

const char *file = R_ExpandFileName(CHAR(STRING_ELT(x, 0)));
unsigned char buf[SB_BUF_SIZE];
FILE *fp;
size_t cur;

if ((fp = fopen(file, "rb")) == NULL) {
if (update == (update_func) XXH64_update) XXH64_freeState(ctx);
Rf_error("file not found or no read permission at '%s'", file);
}
while ((cur = fread(buf, sizeof(char), SB_BUF_SIZE, fp))) {
update(ctx, buf, cur);
}

if (ferror(fp)) {
fclose(fp);
if (update == (update_func) XXH64_update) XXH64_freeState(ctx);
Rf_error("file read error at '%s'", file);
}
fclose(fp);

}

SEXP secretbase_xxhash_impl(SEXP x, SEXP convert, hash_func func) {
SEXP secretbase_xxhash_impl(const SEXP x, const SEXP convert,
const hash_func hfunc) {

const int conv = LOGICAL(convert)[0];
const size_t sz = 8;
unsigned char buf[sz];
struct XXH64_state_s state;
XXH64_hash_t hash;

XXH64_state_t *state = XXH64_createState();
XXH64_reset(state, 0);
func((update_func) XXH64_update, state, x);
hash = XXH64_digest(state);
XXH64_reset(&state, 0);
hfunc((update_func) XXH64_update, &state, x);
hash = XXH64_digest(&state);
XXH64_canonicalFromHash(buf, hash);
XXH64_freeState(state);

return hash_to_sexp(buf, sz, conv);

Expand Down

0 comments on commit edd34e5

Please sign in to comment.