Skip to content

Commit

Permalink
Librhash: Refactoring of generic functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rhash committed Oct 13, 2024
1 parent f8030ea commit 1400e12
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 62 deletions.
32 changes: 30 additions & 2 deletions librhash/algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ void rhash_init_algorithms(unsigned mask)
{
(void)mask; /* unused now */

/* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
/* check RHASH_HASH_COUNT */
assert(rhash_popcount(RHASH_ALL_HASHES) == RHASH_HASH_COUNT);

#ifdef GENERATE_GOST94_LOOKUP_TABLE
rhash_gost94_init_table();
Expand All @@ -183,6 +183,34 @@ const rhash_info* rhash_info_by_id(unsigned hash_id)
return rhash_info_table[rhash_ctz(hash_id)].info;
}

/**
* Return array of hash identifiers of supported hash functions.
* If the all_id is different from RHASH_ALL_HASHES,
* then return hash identifiers of legacy hash functions
* to support old library clients.
*
* @param all_id constant used to get all hash identifiers
* @param count pointer to store the number of returned ids to
* @return array of hash identifiers
*/
const unsigned* rhash_get_all_hash_ids(size_t* count)
{
static const unsigned all_ids[] = {
RHASH_CRC32, RHASH_MD4, RHASH_MD5, RHASH_SHA1,
RHASH_TIGER, RHASH_TTH, RHASH_BTIH, RHASH_ED2K,
RHASH_AICH, RHASH_WHIRLPOOL, RHASH_RIPEMD160,
RHASH_GOST94, RHASH_GOST94_CRYPTOPRO, RHASH_HAS160,
RHASH_GOST12_256, RHASH_GOST12_512,
RHASH_SHA224, RHASH_SHA256, RHASH_SHA384, RHASH_SHA512,
RHASH_EDONR256, RHASH_EDONR512,
RHASH_SHA3_224, RHASH_SHA3_256, RHASH_SHA3_384, RHASH_SHA3_512,
RHASH_CRC32C, RHASH_SNEFRU128, RHASH_SNEFRU256,
RHASH_BLAKE2S, RHASH_BLAKE2B
};
*count = RHASH_HASH_COUNT;
return all_ids;
}

/* CRC32 helper functions */

/**
Expand Down
1 change: 1 addition & 0 deletions librhash/algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ extern rhash_info info_edr512;

void rhash_init_algorithms(unsigned mask);
const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
const unsigned* rhash_get_all_hash_ids(size_t* count);

#if !defined(NO_IMPORT_EXPORT)
size_t rhash_export_alg(unsigned hash_id, const void* ctx, void* out, size_t size);
Expand Down
94 changes: 44 additions & 50 deletions librhash/rhash.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ static rhash_context_ext* rhash_alloc_multi(size_t count, const unsigned hash_id
errno = EINVAL;
return NULL;
}
if (count == 1 && hash_ids[0] == RHASH_ALL_HASHES)
hash_ids = rhash_get_all_hash_ids(&count);
for (i = 0; i < count; i++) {
unsigned hash_index;
if (!IS_VALID_HASH_ID(hash_ids[i])) {
Expand Down Expand Up @@ -156,6 +158,11 @@ RHASH_API rhash rhash_init_multi(size_t count, const unsigned hash_ids[])

RHASH_API rhash rhash_init(unsigned hash_id)
{
if (hash_id == RHASH_ALL_HASHES) {
size_t count;
const unsigned* hash_ids = rhash_get_all_hash_ids(&count);
return rhash_init_multi(count, hash_ids);
}
if (!IS_VALID_HASH_MASK(hash_id)) {
errno = EINVAL;
return NULL;
Expand Down Expand Up @@ -478,7 +485,6 @@ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* ca
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
{
rhash ctx;
hash_id &= RHASH_ALL_HASHES;
ctx = rhash_init(hash_id);
if (ctx == NULL) return -1;
rhash_update(ctx, message, length);
Expand Down Expand Up @@ -536,19 +542,13 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char*
rhash ctx;
int res;

hash_id &= RHASH_ALL_HASHES;
if (hash_id == 0) {
errno = EINVAL;
ctx = rhash_init(hash_id);
if (!ctx) {
return -1;
}

fd = fopen(filepath, FOPEN_MODE);
if (!fd)
return -1;

ctx = rhash_init(hash_id);
if (!ctx) {
fclose(fd);
if (!fd) {
rhash_free(ctx);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
Expand All @@ -568,19 +568,13 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch
rhash ctx;
int res;

hash_id &= RHASH_ALL_HASHES;
if (hash_id == 0) {
errno = EINVAL;
ctx = rhash_init(hash_id);
if (!ctx) {
return -1;
}

fd = _wfsopen(filepath, L"rbS", _SH_DENYWR);
if (!fd)
return -1;

ctx = rhash_init(hash_id);
if (!ctx) {
fclose(fd);
if (!fd) {
rhash_free(ctx);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
Expand Down Expand Up @@ -627,18 +621,18 @@ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
}

static size_t rhash_get_magnet_url_size(const char* filepath,
rhash context, unsigned hash_mask, int flags)
rhash_context_ext* ectx, unsigned hash_mask, int flags)
{
size_t size = 0; /* count terminating '\0' */
unsigned bit, hash = context->hash_id & hash_mask;
unsigned bit;

/* RHPR_NO_MAGNET, RHPR_FILESIZE */
if ((flags & RHPR_NO_MAGNET) == 0) {
size += 8;
}

if ((flags & RHPR_FILESIZE) != 0) {
uint64_t num = context->msg_size;
uint64_t num = ectx->rc.msg_size;

size += 4;
if (num == 0) size++;
Expand All @@ -650,15 +644,18 @@ static size_t rhash_get_magnet_url_size(const char* filepath,
if (filepath) {
size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0);
}
if (!hash_mask) {
return size;
}

/* loop through hash values */
for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) {
for (bit = hash_mask & -(int)hash_mask; bit <= hash_mask; bit <<= 1) {
const char* name;
if ((bit & hash) == 0) continue;
if ((bit & hash_mask) == 0) continue;
if ((name = rhash_get_magnet_name(bit)) == 0) continue;

size += (7 + 2) + strlen(name);
size += rhash_print(NULL, context, bit,
size += rhash_print(NULL, &ectx->rc, bit,
(bit & RHASH_SHA1 ? RHPR_BASE32 : 0));
}

Expand All @@ -668,11 +665,12 @@ static size_t rhash_get_magnet_url_size(const char* filepath,
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
rhash context, unsigned hash_mask, int flags)
{
rhash_context_ext* const ectx = (rhash_context_ext*)context;
int i;
const char* begin = output;

if (output == NULL)
return rhash_get_magnet_url_size(filepath, context, hash_mask, flags);
return rhash_get_magnet_url_size(filepath, ectx, hash_mask, flags);

/* RHPR_NO_MAGNET, RHPR_FILESIZE */
if ((flags & RHPR_NO_MAGNET) == 0) {
Expand All @@ -695,12 +693,12 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
*(output++) = '&';
}

for (i = 0; i < 2; i++) {
for (i = 0; i <= 1; i++) {
unsigned bit;
unsigned hash = context->hash_id & hash_mask;
hash = (i == 0 ? hash & (RHASH_ED2K | RHASH_AICH)
: hash & ~(RHASH_ED2K | RHASH_AICH));
if (!hash) continue;
static const unsigned print_first = (RHASH_ED2K | RHASH_AICH);
unsigned hash = (!i ? hash_mask & print_first : hash_mask & ~print_first);
if (!hash)
continue;

/* loop through hash values */
for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) {
Expand Down Expand Up @@ -836,25 +834,15 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
/* Helper macro */
#define ENSURE_THAT(condition) while(!(condition)) { return RHASH_ERROR; }

static rhash_uptr_t rhash_get_algorithms_impl(const rhash_context_ext* ctx, size_t count, void* ptr)
static rhash_uptr_t rhash_get_algorithms_impl(const rhash_context_ext* ctx, size_t count, unsigned* data)
{
unsigned* buffer = (unsigned*)(ptr);
size_t i;
if (ctx != 0) {
if (count != 0 && buffer != 0) {
ENSURE_THAT(ctx->hash_vector_size <= count);
for (i = 0; i < ctx->hash_vector_size; i++)
buffer[i] = ctx->vector[i].hash_info->info->hash_id;
}
return ctx->hash_vector_size;
} else {
if (count != 0 && buffer != 0) {
ENSURE_THAT((size_t)RHASH_HASH_COUNT <= count);
for (i = 0; i < (size_t)RHASH_HASH_COUNT; i++)
buffer[i] = 1 << i;
}
return (rhash_uptr_t)RHASH_HASH_COUNT;
if (count != 0 && data != 0) {
ENSURE_THAT(ctx->hash_vector_size <= count);
for (i = 0; i < ctx->hash_vector_size; i++)
data[i] = ctx->vector[i].hash_info->info->hash_id;
}
return ctx->hash_vector_size;
}

static size_t hash_bitmask_to_array(unsigned bitmask, size_t count, unsigned* data)
Expand Down Expand Up @@ -918,7 +906,13 @@ RHASH_API size_t rhash_ctrl(rhash context, int cmd, size_t size, void* data)
break;

case RMSG_GET_ALL_ALGORITHMS:
return rhash_get_algorithms_impl(NULL, size, (unsigned*)data);
if (data && size) {
const unsigned* hash_ids;
ENSURE_THAT(size >= RHASH_HASH_COUNT);
hash_ids = rhash_get_all_hash_ids(&size);
memcpy(data, hash_ids, size * sizeof(*hash_ids));
}
return RHASH_HASH_COUNT;
case RMSG_GET_CTX_ALGORITHMS:
ENSURE_THAT(ctx);
return rhash_get_algorithms_impl(ctx, size, (unsigned*)data);
Expand Down
21 changes: 11 additions & 10 deletions librhash/rhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,19 @@ enum rhash_ids
RHASH_BLAKE2S = 0x20000000,
RHASH_BLAKE2B = 0x40000000,

/**
* The number of supported hash functions.
*/
RHASH_HASH_COUNT = 31,

/* bit-flag for extra hash identifiers */
RHASH_EXTENDED_BIT = (int)0x80000000,

/**
* The bit-mask containing all supported hash functions.
*/
RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
RHASH_ALL_HASHES =
RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |
RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |
RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
Expand All @@ -67,15 +76,7 @@ enum rhash_ids
RHASH_EDONR256 | RHASH_EDONR512 | RHASH_BLAKE2S | RHASH_BLAKE2B,

RHASH_GOST = RHASH_GOST94, /* deprecated constant name */
RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */

/* bit-flag for extra hash identifiers */
RHASH_EXTENDED_BIT = (int)0x80000000,

/**
* The number of supported hash functions.
*/
RHASH_HASH_COUNT = 31
RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO /* deprecated constant name */
};

/**
Expand Down

0 comments on commit 1400e12

Please sign in to comment.