Skip to content

williamstaffordparsons/orbithash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 

Repository files navigation

OrbitHash

OrbitHash Logo

Description

OrbitHash is a 256-bit, cryptographic hashing algorithm.

It was created only to assist advanced pattern recognition algorithm development for Eightomic.

License

OrbitHash is subject to the software licensing terms from the LICENSE file.

Reference

orbithash()

This is the hashing function that accepts the 3 following arguments.

input_count is the count of elements in input.

input is the null-terminated int8_t string to hash.

entropy is an array with 8 32-bit unsigned integers. This becomes the 256-bit hash digest result.

The return value data type is void.

Usage

#include "orbithash.h"

int main(void) {
  const char *input = "message";
  uint32_t entropy[8];

  orbithash(8, (int8_t *) input, entropy);
  return 0;
}

Walkthrough

OrbitHash is designed as a 256-bit secure hashing algorithm without additive prime number constants as a faster and more-secure alternative to SHA-256.

Its name derives from hashing multiple surrounding bytes with a low probability of collisions, similar to a moon orbiting a planet and avoiding collisions.

It hashes input data 1 signed byte at a time without padding using low-cost CPU instructions to meet compliance, portability and security requirements.

It avoids common bottlenecks found in other secure hashing algorithms, including 2048-bit additive constants, input padding and using the input length as an additive integer.

It’s infeasible to either reverse a hash digest into a message or find 2 different messages with the same hash digest.

The burden of cryptographic security proof is satisfied by a minimal, unusual design with the following security properties.

Instead of padding the input bytes with a minimum size, the initialization loop with 8 iterations chains together each of the 8 32-bit entropy segments with input-based values to avoid causing trivial collisions from small input sizes.

entropy[0] = 1111111111;

while (
  i != 7 &&
  i != input_count
) {
  i++;
  entropy[i] = input[i - 1] + entropy[i - 1];
  entropy[i] += (entropy[i] + 111111111) << 9;
}

while (i != 7) {
  i++;
  entropy[i] = entropy[i - 1] + 111111111;
  entropy[i] += (entropy[i] + 111111111) << 9;
}

state[0] = entropy[0];
state[1] = entropy[1];
state[2] = entropy[2];
state[3] = entropy[3];
state[4] = entropy[4];
state[5] = entropy[5];
state[6] = entropy[6];
state[7] = entropy[7];

After initializing the 8 32-bit state segments with the result, the input bytes are hashed into 8 32-bit digests in a round-robin sequence with collision resistance derived from chaining each input byte.

i = 0;

while (i != input_count) {
  entropy[i & 7] += input[i] + entropy[(i + 1) & 7] + 111111111;
  i++;
}

This loop sums each unknown input byte with a 32-bit entropy segment at a forward-moving index, which contributes heavily to preimage security since an attacker doesn’t know the value of either input[i] or entropy[i & 7] after each reverse iteration.

Without considering the security properties of the finalization sequence, attempting to reverse the aforementioned hashing loop requires 256ⁱ brute-force combinations where i is the length of input and 256 is the number of possible signed byte values.

Message bytes are processed one-at-a-time to increase dispersion and reduce collisions across the 256 bits of entropy.

Using parallelism or multi-byte processing risks higher collisions while relying on 256-bit collision probability as "too big to collide".

The summed 111111111 constant shifted by 9 on each iteration creates a significant distribution of bits at a low cost with emulated multiplication, even when all message bits are 0.

After each input byte is processed, randomized bits are distributed further with a significant avalanche effect using the following cryptographic finalization sequence.

while (i < 7) {
  entropy[i] += entropy[i + 1] + 111111111;
  entropy[i] += (entropy[i] + 111111111) << 9;
  i++;
}

state[0] += entropy[0];
state[1] += entropy[1];
state[2] += entropy[2];
state[3] += entropy[3];
state[4] += entropy[4];
state[5] += entropy[5];
state[6] += entropy[6];
state[7] += entropy[7];
i = 0;

while (i != 10) {
  state[0] += (entropy[0] + state[1]) ^ state[0];
  state[1] += entropy[1] ^ (state[0] + state[2]);
  state[2] += (entropy[2] + state[3]) ^ state[1];
  state[3] += entropy[3] ^ (state[2] + state[4]);
  state[4] += (entropy[4] + state[5]) ^ state[2];
  state[5] += entropy[5] ^ (state[4] + state[6]);
  state[6] += (entropy[6] + state[7]) ^ state[3];
  state[7] += ((entropy[1] ^ entropy[2] ^ entropy[3]) << 16) | ((entropy[4] ^ entropy[5] ^ entropy[6]) >> 16) + entropy[7];
  entropy[7] += ((entropy[(entropy[3] ^ state[7]) & 7] + (entropy[4] ^ state[0]) + state[1]) >> i) + (entropy[0] ^ state[2]);
  entropy[6] += ((entropy[(entropy[2] ^ state[0]) & 7] + (entropy[3] ^ state[1]) + state[2]) << i) + (entropy[7] ^ state[3]);
  entropy[5] += ((entropy[(entropy[1] ^ state[1]) & 7] + (entropy[2] ^ state[2]) + state[3]) >> i) + (entropy[6] ^ state[4]);
  entropy[4] += ((entropy[(entropy[0] ^ state[2]) & 7] + (entropy[1] ^ state[3]) + state[4]) << i) + (entropy[5] ^ state[5]);
  entropy[3] += ((entropy[(entropy[7] ^ state[3]) & 7] + (entropy[0] ^ state[4]) + state[5]) >> i) + (entropy[4] ^ state[6]);
  entropy[2] += ((entropy[(entropy[6] ^ state[4]) & 7] + (entropy[7] ^ state[5]) + state[6]) << i) + (entropy[3] ^ state[7]);
  entropy[1] += ((entropy[(entropy[5] ^ state[5]) & 7] + (entropy[6] ^ state[6]) + state[7]) >> i) + (entropy[2] ^ state[0]);
  entropy[0] += ((entropy[(entropy[4] ^ state[6]) & 7] + (entropy[5] ^ state[7]) + state[0]) << i) + (entropy[1] ^ state[1]);
  i += 2;
}

It’s infeasible to predict either the input characters or the input length from a hash digest without knowing each of the 8 32-bit state segments.

These values are hidden by summing with 3-bit masks and shifting bits, meaning an attacker must brute-force a minimum of 2²⁵⁶ possible combinations to begin reversing a hash digest.

When considering the aforementioned core hashing algorithm loop, this number increases to 2²⁵⁶ * 256ⁱ where i is the length of input.

Compared to optimized SHA-256, it's up to 6x faster as shown in the following benchmarking table with average processing times.

100k * 10-Byte Inputs
SHA-256                0m0.190s
OrbitHash              0m0.067s

100k * 60-Byte Inputs
SHA-256                0m0.332s
OrbitHash              0m0.091s

100k * 1k-Byte Inputs
SHA-256                0m3.120s
OrbitHash              0m0.594s

100k * 10k-Byte Inputs
SHA-256                0m32.875s
OrbitHash              0m5.668s

All speed tests were performed locally on a Lenovo Chromebook AMD A4–9120C Radeon R4.

As with every cryptographic hashing algorithm, collisions are statistically-possible and OrbitHash isn't 100% collision-proof.

The following code outputs a test vector with sequential 4-byte inputs.

#include <stdio.h>
#include "orbithash.h"

int main(void) {
  int8_t input[4] = {49, 48, 48, 48};
  uint32_t entropy[8];
  unsigned char i = 48;

  printf("Input         OrbitHash\n\n");

  while (i != 58) {
    printf("%d %d %d %d   ", input[0], input[1], input[2], input[3]);
    orbithash(4, input, entropy);
    printf("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", entropy[0], entropy[1], entropy[2], entropy[3], entropy[4], entropy[5], entropy[6], entropy[7]);
    input[3]++;
    i++;
  }

  input[2] = 49;
  input[3] = 48;

  while (i != 68) {
    printf("%d %d %d %d   ", input[0], input[1], input[2], input[3]);
    orbithash(4, input, entropy);
    printf("0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", entropy[0], entropy[1], entropy[2], entropy[3], entropy[4], entropy[5], entropy[6], entropy[7]);
    input[3]++;
    i++;
  }

  return 0;
}

A secure avalanche distribution effect in sequential hash digests is demonstrated with the following test vector.

Input         OrbitHash

49 48 48 48   0xded14065 0x10a11eaf 0x3a6e61fb 0x90f63893 0xec6904a0 0x50c2c29d 0x906f7bc9 0x5950c05f
49 48 48 49   0xbb10473b 0x5e589cdf 0xcd05b399 0xae2b7fc7 0xff621727 0xfa3d06a4 0xf1f9bbff 0x680a889b
49 48 48 50   0x0e2e2b0c 0xa5e03e33 0x97c5b3ae 0x6c0c1c5a 0x65273069 0x1f40720d 0x6e68a303 0xc0beddcd
49 48 48 51   0xb9fa2a94 0xc4583c95 0xe15d687e 0x572e513e 0x8a03030a 0xa3b1abfa 0x82d8b296 0x662bfb1e
49 48 48 52   0xb99a19b6 0xd868d9d1 0xa3e0e8c9 0x93e0b5e2 0xab6bf55e 0xe6b3293f 0x7c204e98 0xc831622e
49 48 48 53   0xe2844e36 0x2f74e4ad 0xbadde5e4 0xbe00855a 0x1672ab0a 0xbcd1a48b 0xcac018c0 0x3ab34be5
49 48 48 54   0x3d098e88 0xec191438 0xa58159d2 0xa9254e7f 0x4efd3815 0x7f62689b 0x2057c49d 0xe44d703e
49 48 48 55   0xac2043df 0x2935fb27 0x1655a818 0xbb768fd6 0x3a619ce3 0x4db152f9 0xbb7f5581 0xc9b27540
49 48 48 56   0x3ec81fb5 0x7c20a290 0xdb2c44c4 0xa3116b61 0x87446378 0x005ce25e 0x32a5e20d 0xb2acf7b8
49 48 48 57   0x4e132633 0x8953d2de 0x9933b43b 0x2f64170e 0x7c69ad26 0xa749a1f4 0xc6b88e0b 0xe828ca4f
49 48 49 48   0x5fc2e171 0x9d8bd8ed 0xd77a1a16 0x5dcc2d81 0x13b87a7e 0x7ef637ac 0x11bbcdcc 0x8633f44a
49 48 49 49   0x18ad39e2 0x668476e0 0xa604e017 0x7be2e336 0xa4b42302 0xf77497e6 0x32984813 0xefbb1cba
49 48 49 50   0x214f73c8 0x8a7a20ba 0x0c399978 0x2ae1666e 0x85c62755 0x2e4281c7 0x0f693fb4 0x3946c07a
49 48 49 51   0xe1acbb7b 0x10451ac4 0x8cdd0e4b 0x8f5e67ad 0x72260aef 0x36835660 0xfa90c207 0x711e6847
49 48 49 52   0x85fab95e 0x5a570a74 0xa9e97c22 0xb8d15787 0x72dba843 0xdfcdd962 0xd5e79589 0x5b8e111a
49 48 49 53   0x33665aa8 0x392d4fb1 0xbbb9c349 0xac72102a 0x1fe03bef 0x030b160c 0x3648eace 0xb3705a63
49 48 49 54   0x214fb72c 0xea54e328 0x4f984c2c 0x28742fa9 0x14050e9c 0x517391c6 0x36422ef7 0x0ca1d20a
49 48 49 55   0x898fbea4 0xea0ca6f8 0x9edab81f 0x54251792 0x4add3046 0x5105a94b 0x2227bcc4 0x3c95bd60
49 48 49 56   0x79b00a87 0x45b67d91 0x98ca0964 0xac50d4ee 0x8c79646a 0x9509268e 0x03d4f32b 0x7994c37e
49 48 49 57   0x3497c154 0x3850859e 0x24c8905d 0x064bc3a3 0x304e4bf3 0xe7a3f245 0xf768c64e 0x00658436

Here’s the output test vector with the first byte flipped.

Input          OrbitHash

-50 48 48 48   0x8fd3b573 0x2a2f3401 0xbc3d06bf 0x8d58bb5b 0x537a81dc 0x889f5ddd 0xd8a04f6a 0x6bea5ec7
-50 48 48 49   0xacda7385 0xc68a7051 0xc31a756d 0xe9f6a7f1 0xe7f63f0c 0xe5d42786 0xdb648bbd 0xda4d01b3
-50 48 48 50   0x9761eefc 0xe4c92977 0xba0837c6 0x04593c1e 0x33245c96 0xc7a733d4 0xf7eb1cdf 0x8d44f548
-50 48 48 51   0x17e5085f 0xd0db54c3 0x3496bf96 0x48a12cd4 0xbe1eafd2 0x5602d75e 0x107c66a1 0x51c43eff
-50 48 48 52   0x7a085f60 0x66c2eead 0xb32eeffe 0xff151fb7 0x6bbee37a 0x8540fb4c 0x1928bb9d 0xad19d9f4
-50 48 48 53   0x9692028d 0x889cce14 0x031af9f0 0x629895dd 0x303f3735 0x1fe726bf 0xf11dee19 0x59f92e00
-50 48 48 54   0xc64faea9 0x112cdd26 0x75dfc9c3 0x11060a37 0x56caac9b 0xbe36e711 0xff1e49c2 0xd5eeb375
-50 48 48 55   0x484d137b 0x76bc8b68 0x9218b4cc 0xe824cb0c 0xaf70337d 0x5d5e44ec 0x62c7d291 0x80ae6f1d
-50 48 48 56   0x716cbb56 0xfdafff91 0xb4bfdb09 0x2d53ca93 0x34b86916 0xe3aea4ec 0xe41ba4b4 0x7523ceec
-50 48 48 57   0xe1a9936f 0x9b882231 0x254fcefd 0xe24f17cb 0x310206f4 0xa4dce3cb 0x2975452f 0x2bdd4bed
-50 48 49 48   0xe985d0a7 0x747a5eca 0x2654939d 0x34bcf83f 0x07d9f6a3 0xee8fecae 0xd058712e 0x2666698e
-50 48 49 49   0xf12c78f7 0xa72a5150 0xbddc9872 0xcf2a0ad1 0x0cb3b38c 0x1328619d 0x1cae10e8 0xc4fd4676
-50 48 49 50   0x4e119e6f 0xced71183 0xb07d9014 0xe9c6e58e 0x73b13dec 0xba0bbdac 0x8b70fef9 0xc3932d94
-50 48 49 51   0x95afd792 0x24cb7cf1 0x25ec2c0a 0xaef84551 0x6d258329 0xbe9c728e 0xadc86c86 0xbf0af02a
-50 48 49 52   0xfd57e753 0x53c03f96 0xd1ac2784 0x25dc2e13 0x35229a87 0xcc285e36 0x48765088 0x1724a797
-50 48 49 53   0x6a0e2436 0x3c85e6d9 0x25e79149 0x03f8fc7e 0xae9e38a3 0xc3b41240 0xd75532e1 0xc2bc5d07
-50 48 49 54   0x733a511e 0xdd98348f 0x37a2671e 0xdcd7429c 0x746455b0 0xde2b9565 0xdc1e41bf 0x88dda462
-50 48 49 55   0xb15fd7bb 0x5f888bd0 0x20c6bcef 0x3cffcabd 0xfc228200 0x510f0525 0xd7b1119f 0xa60a7b68
-50 48 49 56   0x1e05ab1c 0x28840b57 0xeaff795f 0xf431a7f1 0x16c46971 0x75712e05 0x4242c38a 0xfff05a7e
-50 48 49 57   0x64c9a699 0x58832a09 0x503de785 0x1f732547 0x4fd6c4c4 0xbd7dd48d 0xf092e221 0xd3694ce8

Here’s the output test vector with the second byte flipped.

Input          OrbitHash

49 -49 48 48   0x9c5155c7 0xaf66894c 0xbd58556f 0x79ad2a02 0xc1a4371d 0xddb512c6 0xa5538ea8 0x43c39b30
49 -49 48 49   0x8797c96d 0xc768ca00 0xb04467ec 0xf8b74912 0xf574ed7c 0x93c7a96b 0xb8d37bca 0x41fe2b77
49 -49 48 50   0x109d461d 0xf0c56022 0x033063a4 0x78e63e7c 0x2c90a28c 0xe035261e 0x2c6e8417 0x9727359f
49 -49 48 51   0x7faebd48 0xf643675f 0x8f733d78 0x29268852 0x4dcf8d7d 0xf2426281 0xe603f050 0x6de0dc0d
49 -49 48 52   0xd2fe4383 0x529197bf 0x7936e450 0x0381f039 0x8a9cbc91 0x850307cb 0xa6aaaf20 0x026337e6
49 -49 48 53   0x419eb27c 0xfae158d9 0x1a4c0671 0xa66d5724 0x61150c17 0xb32e92c5 0xc8bde23c 0x6ec0aa93
49 -49 48 54   0x0be0b417 0x554eee95 0x9aa2da89 0x1462cfcf 0x6fa75e65 0x773ff3db 0x69cadc3d 0x52883621
49 -49 48 55   0xf4d5b8dd 0x8379a62e 0xd7bd7bdf 0x4167b7e8 0x8b1608ed 0x75d4205e 0x75fa3063 0xf62480c4
49 -49 48 56   0x3d7e9264 0xa45ead26 0x773cf792 0x53c0f48a 0x075e56a1 0xcf00bb4e 0xe8303872 0x2bd5b12b
49 -49 48 57   0x0f87417b 0x0c45ccec 0x5e874574 0x8cbfda6d 0xb582f9f6 0xa58f9bb2 0xa323a61c 0x7a41bb89
49 -49 49 48   0xae7bc1e1 0x764be2aa 0x0d4f9b93 0xa1a65ff5 0x862aad00 0x019abc4c 0x734a46ce 0x478a773a
49 -49 49 49   0x1e2c6dfc 0x7cec0685 0x242a025c 0xc5633105 0xeaa78bf8 0x3855d3a7 0xeac99837 0xd1112d6f
49 -49 49 50   0xc23698c8 0xdbb7db79 0x54b471c2 0x938df0a8 0x024d143f 0xf1b0ae34 0xacac6867 0xada886a6
49 -49 49 51   0x21ed1240 0xa4f315e8 0x67e4a97c 0x799ef44a 0xad2937e7 0xc7746cde 0x1aa2f0fd 0x81c40122
49 -49 49 52   0x8de2afac 0x9d34d27f 0xdbc6866b 0x9f3972bc 0x3a669d5c 0x787407e9 0x8baa7fc1 0x82b6b96c
49 -49 49 53   0x12c1d567 0x9589b438 0xde81f7d8 0xc3482e2d 0x3ed85875 0xa7686233 0x71d01ba8 0xd3d7d72f
49 -49 49 54   0xa1c25849 0x1945a0b9 0xf1e7bccc 0xa0d20966 0xb5e51709 0xf920824d 0xc3093f7c 0x42a6a878
49 -49 49 55   0x26db3ff3 0x16b811cb 0x51b9ea61 0x3ec027bd 0x71ba676c 0x3c0c7163 0x4e9636d4 0x90c49e30
49 -49 49 56   0x71c55247 0x37d46751 0x7a307137 0x6dbf067b 0x9731de87 0x736e2424 0xab405c6f 0xd1b3189a
49 -49 49 57   0x29344894 0xc8d7b8bd 0xd39f0f09 0xae1c9f4f 0x1264012b 0x7328d772 0xb7faf05f 0x3ddca50f

All input with repeating-character length extension creates a significant avalanche effect on the output as demonstrated with the following test vector.

Input           OrbitHash

"00"            0xe6ee769c 0x1cc3235f 0x0f987c3a 0x78dffd75 0x3687efc3 0x6500e872 0xd39f3152 0x2eedd0c9
"000"           0x9f526b96 0x3828e9d5 0x040254fa 0x0d435985 0xa5a58b90 0x1cf9c41d 0x41189705 0x308ab790
"0000"          0xa143dd8a 0x756bd8c7 0x2869cde8 0x470cdc29 0x3881b7ec 0xcee796c0 0x7d417cea 0x7dc6df21
"00000"         0x255a3ba1 0x2d14af22 0x81698644 0xae4cd7f3 0x796a1d55 0xadbf6148 0x911d28b1 0x13d6bd61
"000000"        0x7dab6555 0x24117534 0xb5077c90 0x0442001b 0xd408cc21 0xfdc8d926 0x854d8f18 0xb227a4f2
"0000000"       0xb1603f94 0xd52dac25 0x0ecd3adc 0xe61ee505 0xcc9fe45b 0x1fa670f4 0x62c6c693 0xfc8acec0
"00000000"      0xf12d4b2e 0xc1b96cab 0xf9f1daf1 0x3b0db5b1 0xdef7f0ca 0xb43a39d2 0x08e53355 0x07aecbbb
"000000000"     0x5562004f 0xdd22fb18 0x9550d8e2 0x87193ad6 0xdf300e7e 0xb48c8f74 0xdec880f7 0x6e5acb77
"0000000000"    0xd816a358 0xaa4a436d 0x17ed5cbc 0xbfd12d2b 0x31be79b0 0x5a95f556 0x7acc72f4 0x9137252e
"00000000000"   0xba91c31e 0x08bb25f7 0xcb9d20a0 0x691b1e69 0x2c49bcd9 0xbf64429a 0x8b28b5cb 0x4142ecfa

"11"            0xa53148e2 0x9130e1c4 0xeccac86c 0x91d2bd21 0xecc8af90 0x4df606cb 0xda441aa4 0xdf136690
"111"           0x428ace4b 0xbc2582f1 0x16fa4635 0x426b1710 0xe1364d67 0xa007a75f 0x4efdb5ce 0x40a142a3
"1111"          0xd7739f16 0xb3b44b55 0xed16a253 0xcb031e03 0xf04cdbe3 0x32756c90 0xffa7616d 0xa15e1c7c
"11111"         0xd8d80468 0xe915313c 0x1f619a84 0xd31ba902 0xb86be7e8 0x9ea56abb 0xf30d3491 0x17b72c30
"111111"        0x28bdf1c2 0x4482f582 0x84fa4446 0xebb3dc70 0x7fd367f7 0xc158bc4a 0xb1ebb8a4 0x7409efaa
"1111111"       0xf5ed7e0d 0x2a3171ca 0x446fb7e6 0x0191ed97 0x6917ad53 0xa93e9e35 0x923cb7ff 0x682507ac
"11111111"      0x40143417 0xdc0b0220 0xd8e60e78 0x94e455bd 0xfdd05df7 0x446f150c 0x0f060ef5 0x677803b8
"111111111"     0x1d96279d 0xe52d504b 0xb766b9f3 0xd5e343f2 0xf5850c0a 0xf1866703 0x67b7281f 0x2b5b334e
"1111111111"    0x8cd54166 0x8b0afc50 0xb461a775 0xd589d578 0x4a926abc 0x7dbc52b3 0xda5af64f 0xb588f6a9
"11111111111"   0x8bce8895 0x25ec384f 0xa8a2451f 0xb3eb9a43 0x25cf5c29 0x1bb422ca 0x3c044271 0x51c0db07

All single-byte input create a significant avalanche effect on the output as demonstrated with the following test vector.

Input   OrbitHash

"0"     0xbe4f8299 0xff6bf703 0xc2d7e180 0xa9be10d7 0x956958b8 0x0d8dc405 0x4d9d319e 0x94a419f3
"1"     0xf9b59452 0xf250f705 0x3ec5213e 0x15aa4ca3 0x4c9ccd25 0xb663b619 0xd2452752 0x3768f0f4
"2"     0xf370cb25 0x35eb3e54 0x4dd37539 0x1c7c47eb 0x821b6474 0xcdd6c618 0x18435dcf 0xaae23ac0
"3"     0x4511d364 0xc9c30255 0xd5076c1b 0x2a2fa037 0x6c432651 0x63b82bef 0x273e297f 0xbe74d696
"4"     0x75c42ae4 0x8e04e356 0x4fd4d2a6 0x7458d846 0xab417a72 0x0a978890 0x5ded5be5 0xad34442f
"5"     0x0ab011b7 0xa2ab32b1 0xa52c72f0 0xf0246ad3 0x2f571a11 0x3e572180 0xc87d1508 0xde8598c3
"6"     0xb6f2c309 0x779d0683 0xfe7b2383 0xcd0188b8 0x57c8ad50 0xa60d3847 0xde439ec9 0x88c21726
"7"     0x8072621a 0xc3275f1c 0x09465c91 0xc123e9f2 0x2999bf9d 0x7b7429af 0xc0015f9c 0x68fd1067
"8"     0xb1fa6739 0x8e6e87c8 0xa70dcc8c 0x7cbf3474 0x1b11fc2d 0xb6eee23f 0x7d563254 0x7bad50cd
"9"     0xec516c15 0x9fc39a26 0xb790c791 0xc80788dd 0x47e0640f 0x4f9d0daa 0x1aeaf6a8 0x95341436
"a"     0xa3550a73 0x8eb3ce4e 0xa10d5f8f 0x6ddfe70e 0x3bd029ed 0x592f8a91 0xf68eb239 0x8381e270
"b"     0xf6e04f8f 0x1c404af3 0xf0c021f9 0xd9b8cbd6 0x4ff74ac9 0x6a84e17e 0xb516a3c7 0x5f397a6b
"c"     0xae1d71ac 0x04615e97 0x51a10766 0xa519455b 0x63f0855a 0x1dbb1db8 0xa3d6cabb 0xb3053abf
"d"     0x5e1892e1 0x559134ce 0xfec424bf 0xa904f4d5 0xc36df67e 0x4f039243 0x0afd5d3e 0x1f3e57fd
"e"     0x119ff723 0xe1611923 0xd6760c88 0x84c53d10 0xab6d4d64 0xf3b6d42c 0x709e67d8 0x153de8a8
"f"     0x8e9004ab 0xb71f403d 0x89137497 0x985396f0 0x61920b5c 0xe74dbbbf 0xbf9b70ee 0xde9b1401

All input with repeated 0 bytes creates a significant avalanche effect as shown in the following test vector.

Input                  OrbitHash

0 0 0 0 0 0 0 0 0 0    0xb09cda2a 0x834be581 0x5b15a211 0x3af6a315 0x5f801334 0xf0a90f3d 0x316f5761 0x38461689
0 0 0 0 0 0 0 0 0 1    0x16c4ed7d 0x441b8a19 0xa8d3dbab 0x82d242af 0x07bcf141 0x37312bc0 0x99e6e70c 0x982d5ed8
0 0 0 0 0 0 0 0 0 2    0x33a23839 0xb617e1e6 0xb72066e1 0xdfec91b3 0xd1333822 0x6df6787f 0x44118cd8 0xe18edff3
0 0 0 0 0 0 0 0 0 3    0x9d48d16c 0x9bae2087 0x4b866524 0xbb6e28e9 0x9cc743a5 0xc2b1d5ab 0x457ccfe8 0x3e150414
0 0 0 0 0 0 0 0 0 4    0x29eabfea 0x25507dcd 0x7148450c 0xcad0d4c4 0x035a8d71 0xe22b5095 0xaa40382f 0xc89770ed
0 0 0 0 0 0 0 0 0 5    0xdeca0026 0xd8a1a8b1 0xb0313b5a 0x73cce706 0x129db7dd 0x2836a6ca 0xa50e80de 0xdf5e37e8
0 0 0 0 0 0 0 0 0 6    0xd118ce0a 0xd86e9b48 0x5f2fe3c7 0xea7cd115 0x42b6c56e 0x4626ade6 0xa449b118 0xd801fc31
0 0 0 0 0 0 0 0 0 7    0x2c14f46d 0x2439de56 0xdd9fe580 0x072f7aa9 0x72108fa1 0x690250e5 0x4c7d6d97 0x13c45890
0 0 0 0 0 0 0 0 0 8    0xe64a08f5 0x1d61f450 0x6ea1f496 0xf46fef7d 0xbbb72c70 0xb1f2673f 0xd9e8afc4 0xf3e318d4
0 0 0 0 0 0 0 0 0 9    0x70d3d4f7 0xbd69caf1 0x0b6c1910 0x1f492501 0x490000a4 0x456faca1 0x4c09e06c 0x5ca8e886
0 0 0 0 0 0 0 0 0 10   0x36486732 0x39445767 0x15060b4c 0xf1804413 0x5b80a30d 0xf6ccc3f5 0x6caa7016 0x3e53f42f
0 0 0 0 0 0 0 0 0 11   0x96aaeb04 0x7d4d6213 0x25cb7784 0xd630221e 0x8801df41 0x11a48716 0xc34b400f 0xff9fdadb
0 0 0 0 0 0 0 0 0 12   0x73a1b5fd 0x3e2a0a11 0x36ce2833 0xd055c8f3 0x7a493f30 0x106e64ee 0x57d035bd 0xcc1d7fe4
0 0 0 0 0 0 0 0 0 13   0x29143774 0xd6417416 0x7a99f1fd 0x8e8049a7 0x44fc771a 0x27b589f6 0xd9bb853e 0xb0a87b0f
0 0 0 0 0 0 0 0 0 14   0x2bbd7b05 0x184b8a05 0x1e927784 0x76b83b15 0x147f4b92 0xe790e17b 0x0fe4789f 0x00c6932d
0 0 0 0 0 0 0 0 0 15   0xdc4180e8 0x90e35cc3 0x356457bf 0x5e1b2967 0x2d3f4cf9 0xe07b31fe 0x64a7da51 0x89e344d1
0 0 0 0 0 0 0 0 0 16   0x5c4beaba 0x779ebf03 0x0e4e87e0 0xd6d06a68 0x43eb24f3 0x0bb57626 0xcc08ac4a 0xdef17bef
0 0 0 0 0 0 0 0 0 17   0xe968a327 0x64b515ae 0xa0d34650 0x79239068 0x1b87c4d9 0x87109927 0x7dea85fa 0x807add8b
0 0 0 0 0 0 0 0 0 18   0x74236d96 0x636c1cc1 0xe5752adf 0xdee0c055 0x3d2a5f98 0xdd18bbbd 0x547d79a3 0xcf16b472
0 0 0 0 0 0 0 0 0 19   0x3a914fb8 0x867e88ca 0xa1efd44e 0xda812d1e 0x2b983253 0x00635cf4 0x96caea8f 0x55b1ca6d

0  0 0 0 0 0 0 0 0 0   0xb09cda2a 0x834be581 0x5b15a211 0x3af6a315 0x5f801334 0xf0a90f3d 0x316f5761 0x38461689
1  0 0 0 0 0 0 0 0 0   0x903522ea 0x999741e9 0xdebde08b 0xb9b9487c 0xbd9f3f0e 0x3c8e8812 0xd681a951 0x1b9935c3
2  0 0 0 0 0 0 0 0 0   0x95b3742a 0x4cd1da31 0xd46ecbbf 0x78fdb6c6 0x85f0eac8 0x1b001a1c 0xaff75ada 0xe474f4ec
3  0 0 0 0 0 0 0 0 0   0xd6614e36 0x99d86e6d 0x0ae18ff4 0x21261dde 0x1deba97b 0x7e17fd9c 0x2754e5e4 0xf074d23b
4  0 0 0 0 0 0 0 0 0   0xb1604bc4 0x13eccaf6 0x60890d53 0xb2b42efa 0x47857a3d 0x940fb2ca 0xc7a842ed 0x33430519
5  0 0 0 0 0 0 0 0 0   0x9c52b63f 0xac194a78 0x69e8ceac 0x1ef71f91 0x183388ce 0x44e34cab 0x42001032 0xbf46d6e0
6  0 0 0 0 0 0 0 0 0   0x171d1d9a 0x92a111a9 0x66bbe659 0xf11f3284 0x0d7e0079 0xc930ccc5 0xb7126512 0x73fd2571
7  0 0 0 0 0 0 0 0 0   0xc6ea4347 0x27c0932a 0x3ee637e0 0x6f03bef6 0x20efba17 0x0edb0419 0xca262eb5 0x706cfe4f
8  0 0 0 0 0 0 0 0 0   0xdc6f1514 0x9a1e7370 0x6ab8cc6c 0xa017e27d 0x79346ca9 0xd7560b1c 0x42593c6e 0x16fb9203
9  0 0 0 0 0 0 0 0 0   0x3002f164 0x1d7a8775 0xd478b218 0x05863ce6 0xf6455537 0x61f1d402 0xae4a0f54 0xec214aef
10 0 0 0 0 0 0 0 0 0   0xafca5b1c 0xa87b711a 0xff4d704e 0x689ce184 0x83a385db 0x9202e262 0x66531b2f 0x2cab2c3d
11 0 0 0 0 0 0 0 0 0   0x4a9244a1 0xab84a7d2 0x8cdab9da 0x3c08ecdd 0x1e69f01f 0x74c58739 0xb2b23509 0xaf8b123f
12 0 0 0 0 0 0 0 0 0   0x65de8c54 0xd6963af4 0x7c92852c 0x7f7fecca 0xb6f06add 0x58fab4a3 0x977f6501 0x258e4a4a
13 0 0 0 0 0 0 0 0 0   0x7ee34405 0xd0505071 0xa55406b8 0xc537eafe 0xa730be69 0xd649de97 0x50d0e7bc 0x01700ee3
14 0 0 0 0 0 0 0 0 0   0x4550edd7 0x788df8b0 0x35e8060f 0x7ea54add 0xc1fafa3a 0x0f4ef237 0x17cbfc8c 0xeaaa0c08
15 0 0 0 0 0 0 0 0 0   0xe694b785 0x88c8b304 0xa1a97f2c 0x5b5950c1 0x0f922790 0x45e8ac6d 0x9ce5c5a0 0xfbdfa9ef
16 0 0 0 0 0 0 0 0 0   0x0bd0538c 0x42f03bca 0xadfde996 0x7bed50e0 0x2fccc13e 0xbdb8dff0 0x9a52ad98 0x94287911
17 0 0 0 0 0 0 0 0 0   0x17d51d96 0x36cd08cb 0x5edf244f 0x28808f73 0x33cc4365 0x8d7619f0 0x93a3a781 0xd247e43a
18 0 0 0 0 0 0 0 0 0   0xf361a583 0xc2c3ec35 0x0695b327 0xec1552c7 0x5f36def3 0xe86b07fc 0x8b3934e8 0x8a050aba
19 0 0 0 0 0 0 0 0 0   0xd768e328 0xf30fad35 0xf2b0ffe1 0x093de032 0x6cfc2f65 0x7d8a481f 0x131f9fd8 0x708dd04c

0  0 0 0 0 0 0 0 0     0x48d721bc 0xcabc891b 0xb73b3a26 0x4d6a8d4e 0x513e7c50 0xcfaf9628 0x40077d03 0x0744dd68
1  0 0 0 0 0 0 0 0     0xed5b623a 0xb01b7058 0x912379bc 0x84dc3861 0xdfbc9f57 0x09c86783 0x5f321337 0xb3c43b6f
2  0 0 0 0 0 0 0 0     0x24b0dc1e 0x144a17ac 0xc3fc8a08 0x406a8d37 0xd8ee954c 0xc057f0ee 0xe9446be2 0x76d3e0c3
3  0 0 0 0 0 0 0 0     0x88640ec5 0xe0be0331 0x18ca5735 0x6b30a22a 0xb8c62683 0x4f23998f 0x5da72840 0x40c4d6e1
4  0 0 0 0 0 0 0 0     0xf3f19788 0xf164b088 0x73fb4ce6 0x8feb2a43 0x4af31dfe 0x39ace00c 0x5c5978cf 0x5289eabf
5  0 0 0 0 0 0 0 0     0x755ade0f 0x2a373ecf 0xd94f7a6b 0xdbc874a9 0x1600c90c 0xd5d734f6 0x2d6d186e 0x323fc09c
6  0 0 0 0 0 0 0 0     0x32fcec03 0x89336aae 0x6d9ffdcb 0xa4f9c21c 0x67ad6c11 0x49404921 0xc23ddc7d 0xa257b3a2
7  0 0 0 0 0 0 0 0     0xe4023b7a 0x88c979cf 0x34ed484f 0x780de0c8 0x77a7a356 0x38a248d7 0x32aaec96 0x55ac8534
8  0 0 0 0 0 0 0 0     0x747c8b40 0x6979c04d 0x571ef6f1 0xb4ff085e 0xa96c3b54 0x6edae4b5 0xc3b14599 0x96d3e5cc
9  0 0 0 0 0 0 0 0     0x8e9f5683 0x2d923437 0x11ddae67 0x2b0292eb 0x11fa9b97 0xe3fd87ce 0x6063799b 0xf44d64ef
10 0 0 0 0 0 0 0 0     0xcce06c4f 0x65a6fb03 0x689988da 0xb1748205 0x14685e26 0x25d368b5 0xb327c975 0x91d61550
11 0 0 0 0 0 0 0 0     0x3977b1aa 0xe02ce427 0xccce1e2f 0xa8cd3498 0xfaed90d5 0xd8a7bc5f 0x55eacf8c 0x497c6af2
12 0 0 0 0 0 0 0 0     0x3dc59b66 0x04de14fb 0x584d3bd7 0x9c05ec30 0xa5155d62 0x0532e94d 0x0c1d5bf3 0x73e85108
13 0 0 0 0 0 0 0 0     0x5f4c7b55 0x80737288 0x21e4be97 0x3f4a2642 0x41f01a37 0x8e1ea1ba 0xcc717bc3 0x85acd021
14 0 0 0 0 0 0 0 0     0xa0f957d4 0xa74c1b67 0x225344ab 0x4a8b6282 0x12d13380 0xd30d077b 0x0aae04a8 0x0819313d
15 0 0 0 0 0 0 0 0     0x88c48dc4 0xad91a04a 0x0f690f03 0x1280780b 0xfa4535a0 0x11365442 0x8ede28cb 0x4509bfc2
16 0 0 0 0 0 0 0 0     0x421d6590 0x68e55b9d 0x8d41471f 0x477131f3 0xefcd9c22 0xa5db683d 0x53069383 0xdb88cd3a
17 0 0 0 0 0 0 0 0     0xe172c228 0x209dcf46 0xe11bc13d 0xc6df4eb9 0xc845e03f 0xbf1669ae 0x09562a83 0xb558b6c4
18 0 0 0 0 0 0 0 0     0xb237d89c 0xca50f514 0xb09964cf 0x29783942 0x8537a1c7 0x705e7cd0 0x32b7bd92 0x75e8bcbc
19 0 0 0 0 0 0 0 0     0xae24a619 0xb70b2aa9 0xd8450a4e 0x7e60f709 0x09b3f332 0x020327b4 0x81083000 0x4b139963

Empty input with a length of 0 hashes to a non-empty digest.

Input   OrbitHash

""      0x27f860c0 0xde6ec4bf 0xffa5741d 0xf8527947 0xe8bcec20 0xf9d54ed8 0xbf652bbe 0x353fdbb3

OrbitHash was tested with the following file-based collision testing code to prove the absence of trivially-found collisions as a security vulnerability.

#include <stdio.h>
#include "orbithash.h"

int main(void) {
  FILE *file;
  int8_t input[5] = {0, 0, 0, 0, 0};
  uint32_t entropy[8];
  char digest[65];
  char i = -128;
  char j;
  char k;
  char l;

  while (i != 127) {
    j = -128;

    while (j != 127) {
      k = -128;

      while (k != 127) {
        l = -128;

        while (l != 127) {
          input[0] = i;
          input[1] = j;
          input[2] = k;
          input[3] = l;
          orbithash(input, entropy);
          sprintf(digest, "%08x%08x%08x%08x%08x%08x%08x%08x", entropy[0], entropy[1], entropy[2], entropy[3], entropy[4], entropy[5], entropy[6], entropy[7]);
          file = fopen(digest, "rb");

          if (file == NULL) {
            file = fopen(digest, "wb");

            if (file != NULL) {
              fclose(file);
            }
          } else {
            printf("Input %02x %02x %02x %02x %02x collides with another input at 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x.", input[0], input[1], input[2], input[3], input[4], entropy[0], entropy[1], entropy[2], entropy[3], entropy[4], entropy[5], entropy[6], entropy[7]);
            fclose(file);
          }

          l++;
          l += l == 0;
        }

        k++;
        k += k == 0;
      }

      j++;
      j += j == 0;
    }

    i++;
    i += i == 0;
  }

  return 0;
}

Each 32-bit segment in entropy passes both the first few PractRand tests and Diehard tests with the following birthday spacing permutation results from incrementing 4-byte inputs.

Segment      Permutation   Difference From Adjacent Segment

entropy[0]   0.95876641    0
entropy[1]   0.54330347    -0.41546294
entropy[2]   0.53131326    -0.01199021
entropy[3]   0.98595968    +0.45464642
entropy[4]   0.25063957    -0.73532011
entropy[5]   0.34755269    +0.09691312
entropy[6]   0.50468839    +0.1571357
entropy[7]   0.94082508    +0.43613669

Furthermore, when new prime number increment patterns are discovered, they have no effect on the cryptographic security properties of OrbitHash.

There's a pattern in prime numbers when any set of adjacent prime numbers span a gap sized at a multiple of 10.

In a set of 3 adjacent prime numbers a b c, and when a and c have the difference of 10, b is the result of incrementing by either 4 or 6.

The first occurrence of this pattern, starting from the first prime number in ascending order, is 19 23 29.

There are several other patterns, for example, in a set of adjacent prime numbers a b c d and when a and d have the difference of 10, the difference of b and c is 2.

The first occurrence of this pattern, starting from the first prime number in ascending order, is 7 11 13 17.

The following prime number generator code validates this for the first 20k primes.

#include <stdbool.h>
#include <stdio.h>

int main(void) {
  unsigned int primes[20000];
  unsigned int dividend = 3;
  unsigned int divisor;
  unsigned short count = 20000;
  unsigned short gaps_count = 0;
  unsigned short i = 1;
  bool is_prime;
  bool is_pattern = true;

  while (i != count) {
    divisor = 3;
    is_prime = true;

    while (
      dividend != divisor &&
      is_prime == true
    ) {
      if ((dividend % divisor) == 0) {
        is_prime = false;
      }

      divisor += 2;
    }

    if (is_prime == true) {
      primes[i] = divisor;
      i++;
    }

    dividend += 2;
  }

  while (i != 9) {
    i--;

    if ((primes[i] - 10) == primes[i - 2]) {
      gaps_count++;

      if (
        (primes[i - 1] + 4) != primes[i] &&
        (primes[i - 1] + 6) != primes[i]
      ) {
        is_pattern = false;
      }
    }
  }

  if (is_pattern == true) {
    printf("DungeonGap pattern is consistent among %u gaps.", gaps_count);
  } else {
    printf("DungeonGap pattern is inconsistent among %u gaps.", gaps_count);
  }

  return 0;
}

Of the 20k primes, there are 1120 occurrences of the aforementioned pattern.

The following is a visualization of the first 100 occurences and their increments.

19     +4   23     +6   29
31     +6   37     +4   41
43     +4   47     +6   53
61     +6   67     +4   71
73     +6   79     +4   83
79     +4   83     +6   89
127    +4   131    +6   137
157    +6   163    +4   167
163    +4   167    +6   173
229    +4   233    +6   239
271    +6   277    +4   281
349    +4   353    +6   359
373    +6   379    +4   383
379    +4   383    +6   389
433    +6   439    +4   443
439    +4   443    +6   449
499    +4   503    +6   509
607    +6   613    +4   617
643    +4   647    +6   653
673    +4   677    +6   683
733    +6   739    +4   743
751    +6   757    +4   761
937    +4   941    +6   947
967    +4   971    +6   977
1009   +4   1013   +6   1019
1093   +4   1097   +6   1103
1213   +4   1217   +6   1223
1279   +4   1283   +6   1289
1291   +6   1297   +4   1301
1429   +4   1433   +6   1439
1489   +4   1493   +6   1499
1543   +6   1549   +4   1553
1549   +4   1553   +6   1559
1597   +4   1601   +6   1607
1609   +4   1613   +6   1619
1657   +6   1663   +4   1667
1777   +6   1783   +4   1787
1861   +6   1867   +4   1871
1987   +6   1993   +4   1997
2131   +6   2137   +4   2141
2203   +4   2207   +6   2213
2287   +6   2293   +4   2297
2341   +6   2347   +4   2351
2347   +4   2351   +6   2357
2371   +6   2377   +4   2381
2383   +6   2389   +4   2393
2389   +4   2393   +6   2399
2437   +4   2441   +6   2447
2467   +6   2473   +4   2477
2539   +4   2543   +6   2549
2677   +6   2683   +4   2687
2689   +4   2693   +6   2699
2791   +6   2797   +4   2801
2833   +4   2837   +6   2843
2851   +6   2857   +4   2861
2953   +4   2957   +6   2963
3079   +4   3083   +6   3089
3181   +6   3187   +4   3191
3313   +6   3319   +4   3323
3319   +4   3323   +6   3329
3529   +4   3533   +6   3539
3607   +6   3613   +4   3617
3613   +4   3617   +6   3623
3691   +6   3697   +4   3701
3793   +4   3797   +6   3803
3907   +4   3911   +6   3917
3919   +4   3923   +6   3929
4003   +4   4007   +6   4013
4129   +4   4133   +6   4139
4441   +6   4447   +4   4451
4447   +4   4451   +6   4457
4507   +6   4513   +4   4517
4639   +4   4643   +6   4649
4723   +6   4729   +4   4733
4789   +4   4793   +6   4799
4933   +4   4937   +6   4943
4993   +6   4999   +4   5003
4999   +4   5003   +6   5009
5077   +4   5081   +6   5087
5407   +6   5413   +4   5417
5431   +6   5437   +4   5441
5521   +6   5527   +4   5531
5563   +6   5569   +4   5573
5641   +6   5647   +4   5651
5683   +6   5689   +4   5693
5839   +4   5843   +6   5849
5851   +6   5857   +4   5861
5857   +4   5861   +6   5867
6037   +6   6043   +4   6047
6043   +4   6047   +6   6053
6211   +6   6217   +4   6221
6571   +6   6577   +4   6581
6907   +4   6911   +6   6917
6961   +6   6967   +4   6971
6967   +4   6971   +6   6977
6991   +6   6997   +4   7001
7237   +6   7243   +4   7247
7243   +4   7247   +6   7253
7477   +4   7481   +6   7487
7537   +4   7541   +6   7547

Additional sub-patterns among these patterns could suggest the existence of undiscovered vulnerabilities in SHA-256 and other secure hashing algorithms relying on the security properties of prime number derivatives.

Further analyses of these patterns could result in a prime number increment formula to optimize primality testing computations and redefine the principles of cryptographic security and mathematics.

The lack of initialized additive prime-based constant arrays and fixed-length padding schemes present in other secure hashing algorithms reduces the possibility of digest patterns and decryption methods to weaken or break cryptographic security.

To support this notion, 32-bit digest segments in both OrbitHash and SHA-256 were tested for bit distribution quality with up to 16MB of input data using PractRand.

The following benchmarking template uses sequential 4-byte data inputs padded to segments divisible by 64.

The input values are incremented by either 4 or 6 and the padding integer is 10, all of which are numbers derived from the aforementioned pattern in prime numbers.

#include <stdio.h>
#include "orbithash.h"
#include "sha256.h"

int main(void) {
  static uint8_t input[512];
  uint32_t entropy[8];
  unsigned short i = 0;
  unsigned short j;
  unsigned short k;
  unsigned short l;
  unsigned short m;

  while (i != 512) {
    input[i] = 10;
    i++;
  }

  i = 0;

  while (i < 255) {
    j = 0;

    while (j < 255) {
      k = 0;

      while (k < 255) {
        l = 0;

        while (l < 255) {
          input[0] = l;
          input[1] = j;
          input[2] = k;
          input[3] = i;
          m = 512;

          while (m != 0) {
            hash(m, input, entropy);
            fwrite(&(entropy[0]), sizeof(uint32_t), 1, stdout);
            m -= 64;
          }

          l += 4;
        }

        k += 6;
      }

      j += 4;
    }

    i += 6;
  }

  return 0;
}

hash() should be replaced by the appropriate hash function when testing.

Of the 24 PractRand tests, there were 0 unusual pattern anomalies in OrbitHash and 7 unusual pattern anomalies in SHA-256.