Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions sdk/core/src/include/electronetsoft/arithmos/adt/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ extern "C" {
#endif

struct map_element {
char *key;
typed_pointer key;
list_element *value;
};

struct map_processors {
status_code (*on_initialization)(map *);
status_code (*on_deinitialization)(map *);
status_code (*on_insertion)(map *, map_element *, uint64_t);
status_code (*on_resize_dispatch)(map *, list_element **);
status_code (*on_rehash_dispatch)(map *, list_element **);
status_code (*on_removal)(map *, list *, uint64_t);
status_code (*on_collision)(list *,
uint64_t,
Expand All @@ -41,12 +41,12 @@ struct map {
struct map_function_table {
status_code (*insert)(map *, map_element *);
status_code (*insert_all)(map *, map_element **);
status_code (*remove)(map *, const char *);
status_code (*remove_all)(map *, const char **);
status_code (*resize)(map *, uint64_t);
status_code (*contains)(map *, const char *);
status_code (*contains_all)(map *, const char **);
status_code (*get)(map *, const char *key, map_element *);
status_code (*remove)(map *, typed_pointer);
status_code (*remove_all)(map *, typed_pointer **);
status_code (*rehash)(map *, uint64_t);
status_code (*contains)(map *, typed_pointer);
status_code (*contains_all)(map *, typed_pointer **);
status_code (*get)(map *, typed_pointer key, map_element *);
status_code (*iterator)(map *, status_code (*callback)(map *, map_element *));
};

Expand Down
132 changes: 132 additions & 0 deletions sdk/core/src/include/electronetsoft/util/number/bitwise.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#ifndef __NUM_BITWISE_H_
#define __NUM_BITWISE_H_

#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <electronetsoft/util/types.h>

#ifdef __cplusplus
extern "C" { // disable C++ name mangling by declaring function prototypes
// a C externally linked space
#endif

/**
* @brief Extracts a byte of base 2 from a 64-bit input
* structure into an 8-bit output structure.
*
* @param in the input 64-bit structure.
* @param out the output 8-bit structure.
* @param i the index of the byte to extract out of the input structure.
* @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated
* PASS if the operation has passed successfully.
*/
static inline status_code bitwise_extract_byte(uint64_t in,
uint8_t *out,
uint8_t i) {
if (NULL == out) {
return EUNDEFINEDBUFFER;
}

*out = (in >> (8 * i)) ^ 0b00000000;

return PASS;
}

/**
* @brief Pushes a byte of base 2 into position of index (i)
* into the (out) structure leaving the rest of bytes unchanged.
*
* @param in the input byte of base 2 to push.
* @param out the output 64-bit structure to push the byte into.
* @param i the destined position or index of the byte.
* @return EUNDEFINEDBUFFER if the (out) is not allocated.
* ENOELEMENT if the index is out of bounds.
* PASS if the operation has passed successfully without errors.
*/
static inline status_code bitwise_push_byte(uint8_t in,
uint64_t *out,
uint8_t i) {
if (NULL == out) {
return EUNDEFINEDBUFFER;
}

if (i >= 8) {
return ENOELEMENT;
}

*(((uint8_t *) out) + i) = in;
return PASS;
}

/**
* @brief Exchanges 2 bytes together inside the (in) 64-bit structure
* without changing the rest of the bytes.
*
* @param in the input 64-bit structure.
* @param out the output structure with changed bytes.
* @param i0 the index of the first byte to exchange.
* @param i1 the index of the second byte to exchange.
* @return EUNDEFINEDBUFFER if the (out) buffer is not pre-allocated
* ENOELEMENT if the indexes are out of bounds or equal.
* PASS otherwise.
*/
static inline status_code bitwise_exchange_bytes(uint64_t in,
uint64_t *out,
uint8_t i0,
uint8_t i1) {
if (NULL == out) {
return EUNDEFINEDBUFFER;
}

if (i0 >= 8 || i1 >= 8 || i0 == i1) {
return ENOELEMENT;
}

uint8_t byte_0 = ((uint8_t *) &in)[i0];
uint8_t byte_1 = ((uint8_t *) &in)[i1];
*(((uint8_t *) out) + i0) = byte_1;
*(((uint8_t *) out) + i1) = byte_0;
return PASS;
}

static inline status_code bitwise_left_cyclic_shift(uint64_t in,
uint64_t *out,
uint8_t bits) {
if (NULL == out) {
return EUNDEFINEDBUFFER;
}

if (bits >= (sizeof (in) * 8)) {
return EINCOMPATTYPE;
}

*out = (in << bits) | (in >> (sizeof (in) * 8 - bits));

return PASS;
}

static inline status_code bitwise_right_cyclic_shift(uint64_t in,
uint64_t *out,
uint8_t bits) {
if (NULL == out) {
return EUNDEFINEDBUFFER;
}

if (bits >= (sizeof (in) * 8)) {
return EINCOMPATTYPE;
}

*out = (in >> bits) | (in << (sizeof (in) * 8 - bits));

return PASS;
}

#ifdef __cplusplus
};
#endif

#endif
153 changes: 153 additions & 0 deletions sdk/core/src/include/electronetsoft/util/number/crypto.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#ifndef __NUM_CRYPTO_H_
#define __NUM_CRYPTO_H_

#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <electronetsoft/util/types.h>
#include <electronetsoft/util/utilities.h>
#include <electronetsoft/util/number/bitwise.h>

#ifdef __cplusplus
extern "C" { // disable C++ name mangling by declaring function prototypes
// a C externally linked space
#endif

struct hash_component {
typed_pointer key;
uint64_t *hash;
uint64_t user_key;
};

static inline status_code crypto_spread_64(uint64_t in, uint64_t *out) {
if (rvalue(out) == NULL) {
return EUNDEFINEDBUFFER;
}

in = in ^ ((in ^ (in >> 32)) >> 32);
*out = in;

return PASS;
}

static inline status_code crypto_hash_str(hash_component hasher) {
if (NULL == hasher.key.address.str || NULL == hasher.hash) {
return EUNDEFINEDBUFFER;
}

if (TYPE_STR != hasher.key.type) {
return EINCOMPATTYPE;
}

// Use a large prime constant to initialize (FNV-1a style)
uint64_t h = 0xcbf29ce484222325ULL;
status_code __code;

// Process every character
// Algorithm for polynomial hashing using Horner's rule
for (const char *address = hasher.key.address.str; *address != '\0'; address++) {
// use reverse Horner's Rule to compute the hash
// 1. XOR the character into the hash
h ^= (*address);
// 2. Multiply by 2^5 (aka 32) which is the same as left-shifting by
// 5 bits using Cyclic Shift Hashcode
__code = bitwise_left_cyclic_shift(h, &h, 5);
if (PASS != __code) {
return __code;
}
// 4. Combine MSB Component with LSB Component
h = (h >> 32) ^ h;
}

// Apply your spread_64 as a finalizer to ensure high entropy
return crypto_spread_64(h ^ hasher.user_key, hasher.hash);
}

static inline status_code crypto_hash_long(hash_component hasher) {
if (NULL == hasher.key.address.id || NULL == hasher.hash) {
return EUNDEFINEDBUFFER;
}

if (TYPE_ID != hasher.key.type) {
return EINCOMPATTYPE;
}

status_code __code;
uint64_t in = *(hasher.key.address.id);

for (int i = 0; i < 4; i += 2) {
__code = bitwise_exchange_bytes(in, hasher.hash, i, i + 1);
if (PASS != __code) {

return __code;
}

__code = bitwise_exchange_bytes(in, hasher.hash,
7 - i, 7 - (i + 1));
if (PASS != __code) {
return __code;
}
}

*hasher.hash ^= in;

return crypto_spread_64(*hasher.hash ^ hasher.user_key, hasher.hash);
}

static inline status_code crypto_hash_key(hash_component hasher) {
if (NULL == hasher.key.address.str ||
NULL == hasher.key.address.id ||
NULL == hasher.hash) {
return EUNDEFINEDBUFFER;
}

if (TYPE_ID != hasher.key.type &&
TYPE_STR != hasher.key.type) {
return EINCOMPATTYPE;
}

// TYPE LONG ID
if (TYPE_ID == hasher.key.type) {
return crypto_hash_long(hasher);
}

// TYPE_STR
return crypto_hash_str(hasher);
}

static inline uint64_t crypto_hash_compress(uint64_t hash,
uint64_t limit) {
// the equivalent of modulus operation
// finds the remainder of an integer division operation
return hash - (((uint64_t) (hash/limit)) * limit);
}

/**
* @brief Hashes a key in a string or long identifier format and
* then compresses it using modular arithmetics.
* @details Typical hashing algorithms; include Polynomial hashing
* for string keys using Horner's Rule, and bytes exchange and random
* spreading for unsigned long identifiers.
*
* @param hasher the hasher component structure with generic pointer.
* @param limit the limit of the compression algorithm.
*/
static inline status_code crypto_hashkey_compress64(hash_component hasher,
uint64_t limit) {
status_code __code = crypto_hash_key(hasher);
if (PASS != __code) {
return __code;
}
*(hasher.hash) = crypto_hash_compress(*(hasher.hash), limit);

return PASS;
}

#ifdef __cplusplus
};
#endif

#endif
Loading
Loading