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
3 changes: 3 additions & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ jobs:
- name: Testing Arithmos Calculus (Matrix Algebra Operations -- mat_iterate_elements)
run: ./helper-scripts/ci-cd/test-electrostatic.sh "calculus/test_matrix_iteration.c" "test_mat_traversal"

- name: Testing LCG Number Randomizer
run: ./helper-scripts/ci-cd/test-electrostatic.sh "hello_lcg_random.c" "hello_lcg_random"

- name: Compiling electrostatic4j Java Binding API
run: ./helper-scripts/ci-cd/compile-e4j.sh

Expand Down
17 changes: 17 additions & 0 deletions sdk/core/src/include/electronetsoft/util/number/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ 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

// if the number (hash) is less than (limit)
// the result (hash/limit) integer division
// is less than 1; then the result of compression will reveal
// the (hash) code unchanged.

// if the number (hash) is larger than (limit)
// the result (hash/limit) integer division
// is larger than 1; then the result of compression will reveal
// the remainder which is the number of times
// by which the number (hash) trips over the (limit)

// if the number (hash) is equal to the (limit)
// the result (hash/limit) integer division
// is equal to 1; then the result of compression will reveal
// ZERO; as the remainder which is the number of times
// by which the number (hash) trips over the (limit)
return hash - (((uint64_t) (hash/limit)) * limit);
}

Expand Down
164 changes: 164 additions & 0 deletions sdk/core/src/include/electronetsoft/util/number/decimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <electronetsoft/util/types.h>
#include <electronetsoft/util/number/crypto.h>

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

struct linear_congruent_seq {
uint64_t multiplier;
uint64_t increment;
uint64_t initial_value;
uint64_t modulus;
uint64_t *rand;
uint64_t *k;
};

/**
* @brief Subtracts the last (n) digits from the input (in) of base 10
* and stores the result into the output (out) buffer.
Expand Down Expand Up @@ -74,6 +86,158 @@ static inline uint64_t dec_generate_next_odd(uint64_t n) {
return (n * 2) + 1;
}

static inline status_code dec_is_n_digit_b10(uint64_t in, uint8_t n) {
if (0 == in || 0 == n) {
return EINCOMPATTYPE;
}
// use the scientific notation to reduce the entire ZEROTH
uint64_t redux = in * pow(10, - (n - 1));
if (redux > 0 && redux < 10) {
return ASSERTION_SUCCESS;
}
return ASSERTION_FAILURE;
}

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

if (dec_is_n_digit_b10(in, n) != ASSERTION_SUCCESS) {
return EINCOMPATTYPE;
}

if (((uint8_t) (n/2)) == 0) {
return EBUFFERTURNCATION;
}

// square the number
in *= in;
// subtract the least significant digits
status_code __code = dec_subtract_last_digits_b10(in, out, n / 2);
if (PASS != __code) {
return __code;
}
// extract the middle digits
__code = dec_extract_last_digits_b10(in, out, n);
if (PASS != __code) {
return __code;
}

return PASS;
}

/**
* @brief Generates a random number using a modified version of the linear congruential sequence
* algorithm; the first dispatch to this algorithm will generate a pseudorandom number from
* the given initial value to the modulus value; both the initial value and the value of the
* modulus are included, and a linear subsequence of kth degree (k = (1, 2)).
*
* @param lcs a linear congruential sequence structure.
*/
static inline status_code dec_lcg_random(linear_congruent_seq lcs) {
if (NULL == lcs.rand) {
return EUNDEFINEDBUFFER;
}
if (lcs.multiplier > lcs.modulus
|| lcs.increment > lcs.modulus
|| lcs.initial_value > lcs.modulus) {
return EINCOMPATTYPE;
}
if (lcs.multiplier < 2) {
return EINCOMPATTYPE;
}
if (0 == *lcs.k) {
*lcs.k = 1;
}
if (0 == *lcs.rand) {
*lcs.rand = lcs.initial_value;
}

// calculate the increment as a variable of the multiplier and the kth term
// the multiplier is a constant 64-bit number less than the modulus
// the (k) is an index of the sub-sequence of the current random number
// the subsequence lifetime is resettled each
uint64_t __inc = ((pow(lcs.multiplier, *lcs.k) - 1) * lcs.increment) /
(lcs.multiplier - 1);

// [((ax + c) mod m) | x] is the general equation for the
// linear congruential sequence between two values (minima and maxima)
// where; x = the initial value of the sequence; a = multiplier; c = increment; m = modulus
// (a < m & a > 2) & c < m & x < m
// if (c) is another structure of (ax + c); it follows
// that a subsequence of the original sequence is generated
// By reverse engineering; one may convert (ax + c) into its polynomial form of kth degree:
// (a^k.x + b^(k-j).x + c)
// Now (c) may be even broken down into its variable form to even maximize entropy
// let; c = ((a^k - 1) * c_0)/(a - 1)
// = [a^k/(a - 1)].c_0 + [- c_0/(a - 1)]
*lcs.rand = ((uint64_t) (pow(lcs.multiplier, *lcs.k) * *(lcs.rand) + __inc)) % (lcs.modulus + 1);

// add the bits distribution of the initial value to the rand output
// CASE 01: adding the bits of the initial value to any number in the sequence range
// will not change the output.
// CASE 02: adding the bits of the initial value to any number out of the
// sequence range below minima; will give a decimal result of their
// summation.
if (*lcs.rand < lcs.initial_value) {
*lcs.rand |= lcs.initial_value;
}

// advances the subsequence of the initial LCQ
// reset kth terms when reaching the power of 3
*lcs.k = (*lcs.k * 2 + 1) % 2;

return PASS;
}

static inline status_code dec_clock_lcg_random(linear_congruent_seq *lcs) {
if (NULL == lcs) {
return EUNDEFINEDBUFFER;
}

lcs->increment = ((clock() >> 4) + 1) % lcs->modulus;
lcs->multiplier = ((clock() ^ (clock() >> (lcs->increment % 8))) + 1) % lcs->modulus;

if (lcs->multiplier < 2) {
lcs->multiplier = 2;
}

status_code __code = dec_lcg_random(*lcs);
if (PASS != __code) {
return __code;
}

// postprocessing automata -- hash the output random number
// to increase entropy.

typed_pointer p = {
.address.id = lcs->rand,
.type = TYPE_ID
};

__code = crypto_hashkey_compress64((hash_component) {
.key = p,
.hash = lcs->rand,
.user_key = (UINT32_MAX << 8) | (UINT32_MAX >> ((sizeof(uint32_t) * 8) - 8))
}, (lcs->modulus + 1));
if (PASS != __code) {
return __code;
}

// postprocessing automata -- append the initial value to the final
// value
// Appending the initial value will ensure the sequence value
// doesn't fall to below the initial value by appending its bits to the result
// thus we would have a random number in the range (initial_value, modulus)
if (*lcs->rand < lcs->initial_value) {
*lcs->rand |= lcs->initial_value;
}
return __code;
}

#ifdef __cplusplus
};
#endif
Expand Down
7 changes: 7 additions & 0 deletions sdk/core/src/include/electronetsoft/util/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,18 @@ typedef struct automaton_input (automaton_input);
typedef struct automaton_zeta (automaton_zeta);
typedef struct automaton_component (automaton_component);

typedef struct linear_congruent_seq (linear_congruent_seq);

typedef enum {
ELEMENT_LIST = MAP_TYPE_TREEMAP - 1,
ELEMENT_MAP_ITEM = ELEMENT_LIST - 1,
} element_type;

typedef struct eca (eca);
typedef struct eca_function_table (eca_function_table);
typedef struct eca_system (eca_system);
typedef struct eca_component (eca_component);

#ifdef __cplusplus
};
#endif
Expand Down
30 changes: 30 additions & 0 deletions sdk/examples/src/hello_lcg_random.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <electronetsoft/util/number/decimal.h>
#include <electronetsoft/util/number/crypto.h>
#include <stdio.h>
#include <time.h>

int main() {

uint64_t k = 0;
uint64_t rand = 0;
linear_congruent_seq lcs = {
.initial_value = 50,
.modulus = 200,
.rand = &rand,
.k = &k
};

status_code __code;

for (int i = 0; i < 20; i++) {
__code = dec_clock_lcg_random(&lcs);
if (PASS != __code) {
fprintf(stdout, "Failed with error code = %d\n", __code);
return __code;
}

fprintf(stdout, "The random number = %ld, %lu\n", clock(), *lcs.rand);
}

return 0;
}
Loading