> <
omni...@gmail.com> wrote:
> Hi Chris, Thanx for the English language explanation. I understand
> most of it on first reading. Is the ciphertext the same size as
> the plaintext?
No! Its pretty bad. I can store around 40 bits in a complex number
with doubles. However, somebody over on seems to be able to store
40-bits with floats:
http://www.fractalforums.com/fractals-in-nature/encrypted-fractal-root-storage/
(here is the relevant comment):
_____________________________
“effie” wrote:
Yep I hit the 40 bit limit right away as I was wondering if this can
do compression. You can use arbitrary precision but the complex
number will have more bits than what is encrypted. (2x32 bit floats
to 40 bits) No compression there - but IF there is a formula that works
with integers to create the same +/- encoding then you could compress
an arbitrary length string of bits into 2 integers (no fear of losing
precision). Seems impossible on the face of it, but fun to try.
_____________________________
Keep in mind the the more intricate the Julia set wrt the secret key (c)
the more bits it can store before forward iteration escapes. There are
some ways around involving amortizing the number of complex numbers
sent I am tinkering around with.
This is not all that practical for large plaintexts quite yet. However,
IMVHO, the idea can be very useful indeed, especially when I combine it
with my existing fractal encryption based on forward iteration only.
There is quite a bit on entropy inside of the overall process.
> > Is the count of iterations the result or is a complex number the
> > result of the loop? or both?
> > > The count of iterations in this scheme directly corresponds to
> > > how many bits are being stored.
> How can sections be parsed for decryption without knowing when
> a recursive subroutine has completed?
FWIW, I am not using recursion, but iteration. Either way, one would
have a limit to halt an infinite process. So, lets say each complex
number in the ciphertext corresponds to 40-bits of plaintext. This means
we iterate 40 times for encryption, and 40 times for decryption on a per
complex number basis.. However, if arbitrary precision is used, then we
can use a single complex number with many digits, and the number of
iterations would be the total number of bits in the plaintext. There is
a way to halt forward iteration for the last ciphertext complex number
that may have less than 40-bits because the plaintext bit count is not a
multiple of 40. The forward iteration will go to the origin of z when the
number of bits stored is decoded. So, I mentioned setting z to zero in
my previous reply. Well, forward iteration will get very close to zero.
I say close because there is a damn precision loss going on here, and
the result is usually an escape condition because z get very large, or
it goes very small. Z can go into an infinite condition. It's a barrier
that limits me to 40 bits without using arbitrary precision.
> Without a loop count, the
> end of a recursive activity could continue for too long. Is the
> recursive loop always used the same number of times?
So far, basically yes, except for the last block that might be less
than 40-bits. So for 40 bit blocks we forward iterate 40 times to decrypt,
or until the origin of z used during encryption is encountered.
> It seems
> unclear how a string of a million ciphertext bits will be separated
> into bits with a length equal to a variable loop count. I did not
> read your ideas thoroughly, yet as C++. Your English is more
> helpful than C++ codes, but both are being read and studied.
> I like it.
Okay, I showed you how to store a byte, or encrypt if you will. Lets
say a plaintext byte has 8 bits and each bit in the byte is represented
by a simple array (pt_bits) of Boolean values:
bool pt_bits[8] = { true, false bit pattern };
Lets encrypt this thing using the secret key (c) of { -0.75, 0.09 },
and an origin (z) of {0.0, 0.0}. We are going to loop 8 times using
the (reverse_pow2) function I posted in my reply:
Where the encryption, or reverse iteration function is:
_____________________________
complex_t reverse_pow2(complex_t z, complex_t c, bool bit)
{
0: complex_t d = z – c;
1: float_t l = abs(d);
2: float_t s = sqrt(l);
3: float_t a = atan2(d.imag(), d.real()) / 2.0;
4: complex_t pr = { s * cos(a), s * sin(a) };
5: complex_t nr = { -1 * s * cos(a), -1 * s * sin(a) };
6: complex_t nz = (bit) ? pr : nr;
7: return nz;
}
_____________________________
So, another function is in order. Lets call it (encrypt_byte), it
takes an origin point (z), a secret key point (c), and an array of
bits that represent a byte (bits). The function returns a new point
that contains, or encodes the byte (b):
_____________________________
complex_t encrypt_byte(complex_t z, complex_t c, bool bits[8])
{
[...]
}
_____________________________
Fine... Lets fill this in:
We need to loop 8 times to store a bit, so line 0 is the condition
of the loop where (I) is an integer interval from [0...7]:
0: for (I = 0; I < 8; ++I)
{
//[body of loop];
}
For each iteration, we need to store the corresponding bit in (bits).
So, line 1 would be inside the loop body as where (bits[I]) is the
current bit we are encrypting:
1: z = reverse_pow2(z, c, bits[I]);
Now, we need to return the updated value of (z), therefore line 2,
outside the loop body will be:
3: return z;
To put it all together, we have:
_____________________________
complex_t encrypt_byte(complex_t z, complex_t c, bool bits[8])
{
0: for (I = 0; I < 8; ++I)
{
1: z = reverse_pow2(z, c, bits[I]);
}
2: return z;
}
_____________________________
Now, we need a way to get these bits back... well, forward iteration
to the rescue! Lets build a simple function called (forward_pow2) that
takes two parameters, an origin point (z), and a secret key (c). It
returns the updated result of a single forward iteration of z=z^2+c
(z) with (c), simple... It has only one line:
_____________________________
complex_t forward_pow2(complex_t z, complex_t c)
{
0: return z * z + c;
}
_____________________________
Perfect! Okay, now we need to create a function called (decrypt_byte).
It takes two parameters, an origin point (z) and a secret key (c).
It returns an array of 8 boolean values that represent a plaintext
byte. It looks like:
_____________________________
bool[8] decrypt_byte(complex_t z, complex_t c)
{
[…];
}
_____________________________
Let's create each line of code in this (decrypt_byte) function. First
we need to create an array of (bits) set to all false. Line 0 would be:
0: bool bits[8] = { false, false, ect... };
Now, we need to iterate 8 times, so line 1 would be a loop condition of:
1: for (I = 0; I < 8; ++i)
{
[loop body];
}
The first thing we do is take a look at the sign of the real part of
(z), and see if its positive or negative, then set the corresponding
bit. We can do this in a single line of code using the ternary operator.
Line 2, inside the loop body looks like:
2: bits[(8 – (I + 1)] = (z.real() > 0.0) ? true : false;
Now, we need to perform the actual forward iteration on (z) wrt (c).
So, line 3 would be inside the loop as:
3: z = forward_pow2(z, c);
Fine... Now, we need to return the array (bits) to the caller, so
line 4 outside of the loop looks like:
4: return bits;
Putting the (decrypt_byte) function all together looks like:
_____________________________
bool[8] decrypt_byte(complex_t z, complex_t c)
{
0: bool bits[8] = { false, false, ect... };
1: for (I = 0; I < 8; ++i)
{
2: bits[(8 – (I + 1)] = (z.real() > 0.0) ? true : false;
3: z = forward_pow2(z, c);
}
4: return bits;
}
_____________________________
So, finally to take a byte through the encrypt, decrypt cycle would
look something like:
_____________________________
0: complex_t c = { -0.75, 0.09 }; // the secret key
1: complex_t z = { 0.0, 0.0 }; // the origin point
2: bool[8] plaintext_byte = { a plaintext byte bit pattern };
3: complex_t ciphertext_byte = encrypt_byte(z, c, bits);
4: bool[8] plaintext_decoded = decrypt_byte(ciphertext_byte, c);
5: assert(plaintext == plaintext_decoded);
_____________________________
Line 3 encrypts the (plaintext_byte) into (ciphertext_byte). Line 4
decrypts the (ciphertext_byte) into (plaintext_decoded). Line 5 makes
sure that (plaintext_byte) is equal to (plaintext_decoded).
There is a way to store more than 8 bits in a complex number, but I
thought that showing you how to do 8 is a good start...
Can you grok this? Thanks.
:^)