Algorithm Overview
A compressed "library file" of prime numbers is created and
retained.
It allows any-time rapid access to any of 203,280,221 primes (all that
fit in 32 bits).
Background
Information
The arithmetic process of division often yields a fraction that
can be expressed as a repeating
series of digits. (If "repeating series" includes "000000...",
then that is always
true.) A repeating
series often contains different digits, such as "423432432..." or even
"115115115..." -- both of
those sequences has a "period" of 3 digits-that-repeat. If the
divisor happens to be a prime
number P, the length of the period is often P-1
digits-that-repeat. (When different bases than
the common Base Ten are used, every
prime divisor P has in some Base a period of length
P-1. Meanwhile, no composite divisor C ever has in any Base a
period of length C-1.) This
means that a large prime divisor -- for example greater than
100,000,000 -- can easily generate
100,000,000 digits before the sequence begins to repeat. While
the digits within that sequence
do not quite qualify as being "pseudorandom", they are irregular enough
that if combined with
the sequences of other prime divisors, the result can qualify as being pseudorandom
enough
for encryption purposes. This division and combination process is
also computationally simple
and fast., and the more sequences are involved, the higher-level the
encryption will be.
Part One:
Bootstrap Preparation
A "key file" of any type (graphic, executable, audio, zipped, etc.) is
chosen by the user.
It is opened in Binary
Mode for reading only.
The key file is given a "minimal randomness" test.
If 90 different values can be derived via "exclusive-or" (XOR), the key
file is
not rejected.
The 90 different values are pseudorandomized, per defaults built into
the program.
(See Part Two for a description of the pseudorandomizer.)
Some of the resulting values are used to select Nth primes from the
library.
(If N is greater than 203,280,221, it is halved until it is small
enough for the library.)
The selected primes replace the four default values built into the
program.
Next, 8 data bytes at a time from the key file are pseudorandomized.
Pairs of the scrambled bytes are combined using OR (not XOR).
They make a 32-bit N to select a (biased large) prime from the library.
The longer the key file, the more primes can be chosen, up to
65,536 of them.
Duplicate primes are mostly prevented (allowed among first 1/50 of
selected primes).
The primes are placed within an array of "division scratchpads" in the
memory.
They are left in the array as placed, in unsorted order.
(Examination of the source code will reveal a sorting section.)
(It exists to pull many primes from the library fast and efficiently.)
(The primes will still end up out-of-order in the main scratchpad
array.)
Division by one of the initial 4 primes yields 8 more OR'd bytes.
They become a scratchpad "dividend" to be divided by a prime.
The minimum key file length is 8300 bytes (for approx. 1000 primes).
Toward the end of the key file, 108 bytes are reserved.
A minimum-length 8300-byte file can yield 1024 primes if no duplicates
occur.
When as many scratchpads are filled as the file-length allows,
the 108 reserved bytes are pseudorandomized and used to
again replace the 4 initial
primes.
File encryption or decryption may now begin.
Part Two: The Pseudorandomizer
As indicated above, everything depends on divisions performed in
"scratchpads".
In Base Two, division consists of doubling the dividend and subtracting
the divisor.
A one-bit output results if the bit-shifted (doubled) dividend is
larger than the divisor.
A zero-bit output results if the dividend is smaller than the divisor.
The result of the subtraction becomes the dividend for the next
division operation.
A "divide" subfunction exists to obtain N quotient bits from one
scratchpad.
The divide function can operate on any (pseudorandomly) specified
scratchpad.
The first time a scratchpad
is divided, a "random" dividend may be larger than divisor.
If so, the dividend is halved multiple times, until it becomes smaller
than the divisor.
Then the doubling (via bit-shift) and subtraction process begins, for N
quotient bits.
Every scratchpad retains its last dividend result for use when
called-upon again.
(The saved dividend is always smaller than the divisor, so initial
halving never recurs.)
At the start of the process, each byte we want to scramble is copied to
a holding variable.
The 4 initial primes built into the program allow some divisions to
occur "at once".
These scratchpads control the combining of quotient-data for
pseudorandomization.
One specifies how many times an overall scrambling loop will be
performed on our byte.
Two data bits from it yield 0,1,2, or 3 -- modified to cause 1,2,3, or
2 overall loops.
Inside each overall loop, another initial scratchpad provides two more
bits of data.
Values 0,1,2, or 3 are modified to cause 2,3,4, or 5 individual
scrambling operations.
For each operation, the third initial scratchpad provides 16 bits of
data.
The quantity N of scratchpads in the main array is now an important
factor.
If N is zero, then 8 bits of those 16 are going to be used as scramble
data.
Otherwise Modulus N of the 16-bit data yields a main-array index value.
(That is, as soon as any
main-array scratchpads are filled in, they start getting used.)
The scratchpad at that index is tapped to provide 8 bits of scramble
data.
For each scramble operation, the fourth initial scratchpad provides 3
bits of data.
The complete group of scrambling-data is saved in two local arrays.
The "Encryption" process pulls/uses the data from these arrays
first-to-last.
The "Decryption" process pulls/uses the data from these arrays
last-to-first.
At the start of each actual-scrambling operation, Modulus 7 of
the 8-bit data is saved.
For the "Encryption" process:
The 3 bits of data specify one of the following scrambling operations
to our data-byte:
0 - Use the saved Modulus 7 number to perform 1,2,3,4,5,6 or 7 LEFT
bit-rotations.
1 - Same as 0, but also perform a NOT (flip all bits) operation
afterward.
2 - Add the 8-bit scramble-data. (If result exceeds 255, byte
"odometerizes".)
3 - Add the 8-bit scramble-data, and then perform a NOT operation.
4 - Subtract the 8-bit scramble-data. (Yes, this can odometerize
backwards.)
5 - Subtract and then perform NOT.
6 - Combine the 8-bit scramble-data using XOR.
7 - Combine using XOR, and follow with NOT.
For the "Decryption" process:
The 3 bits of data specify one of the following scrambling operations
to our data-byte:
0 - Use the saved Modulus 7 number to perform 1,2,3,4,5,6 or 7 RIGHT
bit-rotations.
1 - Same as 0, except also perform a NOT (flip all bits) operation before the rotation.
2 - Subtract the 8-bit scramble-data.
3 - Perform a NOT operation, then subtract the 8-bit scramble-data.
4 - Add the 8-bit scramble-data.
5 - Perform NOT, and then Add.
6 - Combine the 8-bit scramble-data using XOR.
7 - Perform a NOT, then combine using XOR.
As previously indicated, every data byte receives two-to-five
scrambling operations.
Only very rarely will a
single scratchpad provide two consecutively-used scramble bytes.
This makes it very difficult to deduce what dividends/primes yielded
scrambling-data.
There is also no clue as to how many scratchpads were used, from
one-to-65 thousand.
(And how many different ways can one select thousands of primes from
200 million?)
All those different ways to multiply-scramble a byte don't help the
cryptanalyst, either.
The overall scrambling loop is now done for the first time.
If that loop is about to repeat, then the holding variable is used to
restore our data byte.
Only the last overall
scrambling loop actually provides the scrambled byte that we save.
The deliberate purpose: It
breaks up the actually-used sequence of quotient-bits.
About half of all quotient-bits are pseudorandomly "wasted".
It becomes even more difficult to determine the dividends/primes used
to
encrypt data.
When thousands of bytes are to be encrypted, every scratchpad in the
main array is
probably going to be pseudorandomly selected to help provide
scramble-bytes. It is
currently thought that an encrypted file will provide nearly zero
insight into what key
file data was used to bootstrap itself to provide the primes that were
used to encrypt
the file. Thus the likeliest way to break this encryption scheme
appears to be the
brute-force method of trying all possible key files. That is
where the "Extra Randomizer"
mentioned elsewhere comes into play. It allows the user to
specify that up to ten million
scramble-events will take place, wastefully, before any are actually used to encrypt
data.
This means that every possible key file must be tested up to ten
million times, before
the next key file can be tested. And that can work only if the
encrypted file was the first
one specified to be encrypted by "cryption.exe". Instead it could
have easily been the
second or the hundredth file of a single session; it could be multiply
encrypted in a
single session (or in separate sessions with different key files), and equally large
Extra Randomizers could have been specified in-between every
file-to-encrypt of a
single session. Finally, there may be more than a trillion files
accessible via the
Internet, to be used as keys. Enjoy! Because so far, it
looks like the cryptanalysts
probably won't.