Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reverse Iteration Fractal Encryption...

271 views
Skip to first unread message

Chris M. Thomasson

unread,
Feb 21, 2016, 4:39:03 PM2/21/16
to
Original idea by Juaquin Anderson in the comments of the
following thread:

https://plus.google.com/+JuaquinAnderson/posts/L9A3Da8ju3B


FWIW, here is the content of the comment:
_________________________________________________
“This has me thinking.. All the structure, in the reverse
iteration, and the sequence of roots, as well as the structure
of the level sets with the escape time algorithim.
Someone
suggested using fractals for encryption..

A method that would
actually work would be to choose an interesting value of c,
like this one, as the key.

1) If the message has length n bits,
choose a point in the n'th level set. The point can be chosen
by taking a starting point just outside the circle delimiting
the target set, and applying inverse iteration, choosing roots
by sign according to the bits in the sequence to be encoded.

2)
the result would be a point (x+yi) that is inside the nth level
set close to the Julia set.

3) encode that point accurately
enough to not confuse with points of a level deeper or further
out, and transmit that point.

4) receive that point.

5) decode
the point by applying forwards iteration with the key value c,
until the point lands in the target set. Tge decoded message
would have n bits determined by writing down the sign of the
imaginary component of the escape orbit for each iteration.



Sounds easy right?

:-)

The efficiency of the encrypted coding scheme has to do with
the fractal dimension of the Julia set, and the degree of
imbalance of the contractivity in the tree traversal of the
Julia set."
_________________________________________________


Juaquin Anderson has taken fractal encryption to another level
beyond the stuff I have been experiment with. He is basically
encoding a sequence of bytes inside a single complex number.
The reverse iteration method for a Julia set is being used to
store information. Lets say a byte. Well, a byte is made up of
a number of bits, on or off. These bits are used to decide which
root to choose for the square root of z during reverse iteration
of (z = z^2 + c). After this reverse iteration, one ends up with
an interesting point p. This point p can actually recreate the
bits of the byte when exposed to forward iteration. The number
of iterations for both forward and reverse iteration directly
corresponds to how many bits it stores. I can only do around 40
bits, but the little program I wrote just does 8 for clarity.

So, for encryption c is the secret key and the cipher text is a
list of complex numbers, or a single complex number if one uses
an arbitrary precision library to calculate both the reverse and
forward iterations.

Here is a simple proof of concept program in C++11 that encodes
a single byte:

http://pastebin.com/4Yu8uSKH


If one can encode a single byte, then one can encode multiple
bytes, and arbitrary binary files.

I know that this is going to work like a charm. I am working on
another proof of concept program that shows how to encode multiple
bytes in a single complex number, instead of the single byte
example shown here...


Any thoughts?

What do you think about the code? Is it crap?

;^)


Thank you all.

Chris M. Thomasson

unread,
Feb 21, 2016, 5:30:52 PM2/21/16
to
> "Chris M. Thomasson" wrote in message news:nadaph$pnu$1...@gioia.aioe.org...

> Original idea by Juaquin Anderson in the comments of the
> following thread:

> https://plus.google.com/+JuaquinAnderson/posts/L9A3Da8ju3B

[...]

FWIW, here is another c++11 proof of concept program
that can encrypt all byte values:

http://pastebin.com/VsvH3HdE

Some essential further context:

https://plus.google.com/101799841244447089430/posts/6hYWn1YPd2C

This makes sense because there are an infinite number of
different representations of the root tree wrt going down
a positive or negative root during reverse iteration...

example code:
__________________________________________________
/*
Original idea by: Juaquin Anderson, in the comments of the following thread:

https://plus.google.com/+JuaquinAnderson/posts/L9A3Da8ju3B

Implementation by: Chris M. Thomasson
______________________________________________________________________
*/

#include <iostream>
#include <complex>
#include <array>
#include <vector>
#include <climits>
#include <cassert>



#define ESP ((iim_float_t)0.000000001)


typedef double iim_float_t;
typedef std::complex<iim_float_t> complex_t;
typedef std::array<bool, CHAR_BIT> bitchar_t;


struct forward_ret
{
complex_t z;
bitchar_t bc;
};




static unsigned char
bitchar_get(
bitchar_t
);


static complex_t
iterate_reverse(
complex_t,
complex_t,
bitchar_t const&
);


static forward_ret
iterate_forward(
complex_t,
complex_t
);


unsigned char
bitchar_get(
bitchar_t bc
) {
assert(bc.size() == CHAR_BIT);

unsigned char r = 0;
unsigned int b = 1;

for (unsigned int i = 0; i < bc.size(); ++i)
{
if (bc[i]) r = r | b;
b = b << 1;
}

return r;
}


bitchar_t
bitchar_set(
unsigned char n
) {
bitchar_t r = { false };
unsigned int b = 1;

for (unsigned int i = 0; i < r.size(); ++i)
{
r[i] = (n & b) ? true : false;
b = b << 1;
}

return r;
}


complex_t
iterate_reverse(
complex_t z,
complex_t c,
bitchar_t const& bc
) {
assert(bc.size() == CHAR_BIT);

for (std::size_t i = 0; i < CHAR_BIT; ++i)
{
complex_t d = z - c;

iim_float_t l = std::abs(d);
iim_float_t s = std::sqrt(l);
iim_float_t a = std::atan2(d.imag(), d.real()) / 2.0;
iim_float_t r = 0;

if (bc[i]) { r = 1; }
else { r = -1; }

complex_t nz = { r * s * std::cos(a), r * s * std::sin(a) };

if (bc[i] == 1)
{
std::cout << "iterate_reverse:[" << i << "]:("
<< bc[i] << "):(+) = " << nz << std::endl;
}

else
{
std::cout << "iterate_reverse:[" << i << "]:("
<< bc[i] << "):(-) = " << nz << std::endl;
}

z = nz;
}

std::cout << "__________________________________________" << std::endl;

return z;
}


forward_ret
iterate_forward(
complex_t z,
complex_t c
) {
forward_ret ret = { { z },{ false } };

std::cout << "iterate_forward:(origin):" << z << std::endl;

for (std::size_t i = 0; i < CHAR_BIT; ++i)
{
complex_t pz = ret.z;
ret.z = ret.z * ret.z + c;

// check for bit on condition
if (pz.real() > 0.0)
{
// turn the proper bit on...
std::size_t bc_i = CHAR_BIT - (i + 1);
ret.bc[bc_i] = true;
}

iim_float_t l = std::abs(ret.z);

if (l < ESP)
{
std::cout << "iterate_forward:(term):[" << i << "]: " << ret.z
<< std::endl;
break;
}

std::cout << "iterate_forward:[" << i << "]: " << ret.z <<
std::endl;
}

std::cout << "__________________________________________" << std::endl;

return ret;
}




int main()
{
{
// the secret key c
complex_t c = { -0.75, 0.09 };

// the origin of iteration z
complex_t z = { 0.0, 0.0 };

// A bytes to encode, the plaintext pt
std::cout << std::endl <<
"**********************************************************"
<< std::endl;

for (std::size_t pt = 0; pt < UCHAR_MAX + 1; ++pt)
{
std::cout << "encoding pt:" << pt << std::endl;
std::cout << "__________________________________________" <<
std::endl;

// set pt to bitchar_t
bitchar_t pt_bits = bitchar_set(pt);

// Our encoded byte point origin, out ciphertext ct
complex_t ct = iterate_reverse(z, c, pt_bits);

// Our decoded bits and point origin db_z
forward_ret db_z = iterate_forward(ct, c);

// Our decoded byte db, should be equal to plaintext pt.
unsigned char db = bitchar_get(db_z.bc);

if (pt != db)
{
std::cout << "pt:" << pt << " != db:" << (int)db <<
std::endl;
std::cin.get();
assert(pt == db);
}

std::cout << "decoded: pt:" << pt << " == db:" << (int)db <<
std::endl;

std::cout <<
"**********************************************************"
<< std::endl;
}
}

std::cout << std::endl << "__________________________________________"
<< std::endl << "Program Complete!" << std::endl;

std::cin.get();

return 0;
}
__________________________________________________


What do you think of this?

Chris M. Thomasson

unread,
Feb 23, 2016, 2:32:45 PM2/23/16
to
This: https://plus.google.com/101799841244447089430/posts/TJ6ELo7qgFb

is related to:

https://plus.google.com/101799841244447089430/posts/1YKAJn1XKYd


I'm wondering, if Juaquin Anderson, creator of the wonderful idea,
of using the reverse iteration method to forward iteration Julia
set encryption would approve of this line of thought in a possible
short paper... The main idea is zone based encryption. I attached
a very crude diagram of a line and a curve encoding 4 bytes P[n],
n=4 where byte values p[0] = red, p[1] = green, p[2] = blue and
p[3] = yellow. Encrypting a byte P is accomplished by choosing
its corresponding color, or zone of a section of a given curve
length. The zone database, if you will, can be created on the
fly by using the secret key K which is comprised of settings that
describe the size of the zones, and the “path” that the zones are
partitioned across. Fractals are used for efficient zone partitioning
basically similar to measuring fractal dimension using “boxes”.

This
cannot be anything new, but I am trying to understand the creators
idea of using field lines to store information. Well, the field lines
in my calculations, are perfectly segmented on the scaled unit vector
level. This would provide all we need to create the zones needed to
encode/decode a given datum.

256 zones means a byte can be encrypted
on a given line/curve length basis.

Encoding relates the byte of the
plaintext to its zone and transmits that point.

Decoding relates the
encoded points to their zones, and gets the byte back based on the
“value” of the zone color, so to speak.


I just thought that instead of transmitting an encoded point across the
network, why not send an iteration count? This count would of course be
sufficient enough for a given plaintext byte to traverse the field line into
its
corresponding zone!

Well, what do you think? Is this crap?

;^o


I am going to work on a proof of concept. For the graphics,
I will use the Cairo C lib. This should work damn it!

Chris M. Thomasson

unread,
Feb 23, 2016, 3:42:17 PM2/23/16
to
FWIW, here are some field line examples on Julia set
points that can be used to encode a stream of bytes
via fractal based zone encoding scheme. Extra mass
points can be used int the secret key to bend the line
further, and basically radically distort the field...

https://plus.google.com/101799841244447089430/posts/cdJWGvgPMnd

https://plus.google.com/101799841244447089430/posts/5Jm2Q6APu8n

https://plus.google.com/101799841244447089430/posts/DRHeVATeG5K

https://plus.google.com/101799841244447089430/posts/fH3DcjNZuhX


any thoughts?

Fractal based field distortion wrt encoding along a given field
line would really scramble the shit out of the lines.

chris.m.t...@gmail.com

unread,
Jun 8, 2016, 6:17:35 PM6/8/16
to
Has anybody read this yet? FWIW, here is another discussion I started on the topic:

http://www.fractalforums.com/fractals-in-nature/encrypted-fractal-root-storage

This has more feedback. The technique is clearly outlined. Heck, I whipped up a C++ version in no time at all. This very clever method can be used to store up to 40 bits of data in a single complex number. Since I am using axes, comprised of two complex numbers in the IV for each ciphertext, well, why not use them to store data? There has to be MANY more exotic ways to use this in my own fractal encryption scheme.

Chris M. Thomasson

unread,
Jun 8, 2016, 6:26:02 PM6/8/16
to
The damn lines are not trimmed! DAMN.

Rich

unread,
Jun 8, 2016, 9:33:48 PM6/8/16
to
Chris M. Thomasson <nos...@nospam.com> wrote:
> The damn lines are not trimmed! DAMN.

This is usenet. You format and wordwrap (hard word wrap) the article
*before* you post it. Usenet does not do that function for you.

Chris M. Thomasson

unread,
Jun 8, 2016, 11:49:01 PM6/8/16
to
> "Rich" wrote in message news:njah1q$u0g$1...@dont-email.me...
Yeah. I posted from Google's interface and forgot to check.
Sorry about that, and butting in on the other thread from Karl Frank.

Anyway, what do you think of the idea of storing information in a
complex number? Is the explanation in:

http://www.fractalforums.com/fractals-in-nature/encrypted-fractal-root-storage

clear enough? FWIW, here is exactly how to do inverse iteration of
z = z^2 + c:

http://www.fractalforums.com/ifs-iterated-function-systems/julia-set-inverse-iteration

Polar form helps out quite a bit. The neat thing is that one can
use the bits of a plaintext to choose what root to use during this
inverse iteration. Bit on is positive, and off is a negative root.
At the end of encoding, one ends up with an interesting point z. The
sign of the real part of z during forward iteration can reconstruct
the bits stored during inverse iteration.

Here is a very simple C++version that stores 8 bits:

http://pastebin.com/VsvH3HdE


One more point, a single complex number with arbitrary precision can
encrypt N bits...


IMVVHO, this is pretty neat! :^)

Rich

unread,
Jun 9, 2016, 6:04:15 AM6/9/16
to
Chris M. Thomasson <nos...@nospam.com> wrote:
> > "Rich" wrote in message news:njah1q$u0g$1...@dont-email.me...

> > > Chris M. Thomasson <nos...@nospam.com> wrote:
> > > The damn lines are not trimmed! DAMN.

> > This is usenet. You format and wordwrap (hard word wrap) the
> > *article before* you post it. Usenet does not do that function for
> > *you.

> Yeah. I posted from Google's interface and forgot to check.

Do not *ever* use google's interface. Esp. do not *ever* use google's
interface for posting. It is an absolutely awful interface, and falls
far far short of google's normal reasonable web quality.

Register an Eternal September (http://www.eternal-september.org/)
account of use AIOE (http://news.aioe.org/, no registration) and a real
newsreader (https://en.wikipedia.org/wiki/List_of_Usenet_newsreaders).

Some of them will even take care of the hard wrapping automatically for
you.

> Sorry about that, and butting in on the other thread from Karl Frank.

> Anyway, what do you think of the idea of storing information in a
> complex number? Is the explanation in:

> http://www.fractalforums.com/fractals-in-nature/encrypted-fractal-root-storage

> clear enough?

For someone with very little knowledge of fractals beyond their
existence and the fact that there is a recursive nature to them, no,
not at all clear enough.

> FWIW, here is exactly how to do inverse iteration of z = z^2 + c:

> http://www.fractalforums.com/ifs-iterated-function-systems/julia-set-inverse-iteration

> Polar form helps out quite a bit. The neat thing is that one can
> use the bits of a plaintext to choose what root to use during this
> inverse iteration. Bit on is positive, and off is a negative root.
> At the end of encoding, one ends up with an interesting point z. The
> sign of the real part of z during forward iteration can reconstruct
> the bits stored during inverse iteration.

If I understand your long paragraph above, you are walking down a
fractal tree, and choosing a path to follow to a next lower 'node'
based upon bits from the input data.

If so, this sounds very similar to arithmetic or range coding systems
use to compress input data into a smaller output.

https://en.wikipedia.org/wiki/Arithmetic_coding
https://en.wikipedia.org/wiki/Range_encoding

omni...@gmail.com

unread,
Jun 9, 2016, 12:15:05 PM6/9/16
to
Hello Chris. You asked: "clear enough?"

Rich and I feel the same:

"For someone with very little knowledge of fractals beyond their
existence and the fact that there is a recursive nature to them, no,
not at all clear enough. "

I do not understand reverse iteration. Here is a description of my problem:

To make a Mandelbrot set colored image, the complex number z is put in as a seed. For each pixel in the xy rectangular color picture, calculate a recursive formula based on z to get the next z value. If the result has a magnitude greater than 2, stop iterating. Record the number of iterations N. That number N is mapped to a color. The pixel now has its color. Next pixel.

The key is c, used in the basic formula. The key is added in each iteration for each pixel.

forward iteration:

ret.z = ret.z * ret.z + c;

reverse iteration

complex_t d = z - c;

Reverse that iteration: I am given the iteration count N for a pixel at location xy. Calculate a complex number based on the iteration count using the reversed formula for "recursion". Except call it precursion. Keep doing iterations until the result is WHAT? How can I stop the precursion loop if I do not know the original complex number?

Dear Chris M. Thomasson, please make corrections and clarification at this basic level for Julia Set reverse iteration. What initial complex number does the encryptor use at each xy for the recursive formula? What complex numbers z does the decryptor use at each xy pixel for the precursive formula? Is the count of iterations the result or is a complex number the result of the loop? or both?

Chris M. Thomasson

unread,
Jun 10, 2016, 12:16:17 AM6/10/16
to
> <omni...@gmail.com> wrote:
[...]
> Hello Chris. You asked: "clear enough?"

> Rich and I feel the same:

> "For someone with very little knowledge of fractals beyond their
> existence and the fact that there is a recursive nature to them, no,
> not at all clear enough. "

Okay, before you read on, go ahead and see if the following
information can make things any clearer wrt reverse iteration
of z = z^2 + c:

https://en.wikipedia.org/wiki/Julia_set#Plotting_the_Julia_set


> Here is a description of my problem:

> To make a Mandelbrot
> set colored image, the complex number z is put in as a seed.

No, because there is no single seed in a Mandelbrot iteration.
This is based on Julia sets where the c is constant throughout
iteration. The MSet has multiple values of c, one for each pixel,
where the Julia set uses the same c for every pixel.

AFAICT, its practically impossible to do reverse iteration on a
Mandelbrot set, however, Julia's are a completely different story.

[...]


> forward iteration:
ret.z=ret.z*ret.z+c;

Right.




> reverse iteration
: complex_t d=z-c;

Not quite... We need to get at the two complex square roots. For
the square case, we have two roots to choose from +-sqrt(z-c), for
the cubic we have three roots, and on and on. Lets focus on the
square version for now, positive and negative. Okay, lets go through
a single reverse iteration:

Start with a secret key (c) that happens to create a fairly nice
looking Julia set. Now, create a value (z) and set it to zero, or
something not too far away from the origin. Let's do that:


complex_t c = { -0.75, 0.09 };
complex_t z = { 0, 0 };

Fine... For now, lets create a simple function (reverse_pow2), (C++'ish)
that returns the result of the iteration and takes two parameters z,
and c. This function will do a single iteration at a time:

// z = origin point
// c = secret key/Julia point
// returns the result of a power of two reverse iteration
complex_t reverse_pow2(complex_t z, complex_t c)
{
[…];
}

Okay, lets completely fill this sucker in; polar form will quickly
show its face! ;^D

The first thing we need to do is get the difference (d) between (z)
and (c), so line 0 would be:

0: complex_t d = z – c;

This gives us some very important information! For instance, we now
can get the length (l) of (d), so we take the absolute value of (d)
in line 1:

1: float_t l = abs(d);


Now, we need to take the square root (s) of the length (l) because
we are reversing a power of two, so line 2 is:

2: float_t s = sqrt(l);


Fine, all is well. Except, we now need the angle (a) of (d) divided
by two. We divide the angle by two because we are working with reversing
a power of two. So, line 3 would be:

3: float_t a = atan2(d.imag(), d.real()) / 2.0;

where (d.real()) and (d.imag()) are the real and imaginary components
of (d). Okay, now things get interesting! We have two complex roots to
choose from here, which path do we take? Well, we could use a random
number generator, or plot everything, or, perhaps, use the value of a
bit to choose...

Humm... Let's setup a simple coin toss. Imagine a function called
(random()) that returns a random number between 0 and 1, just like
(Math.random()) in JavaScript. Okay... Let's compute both roots, the
positive (pr), and the negative (nr) for fun. Let lines 4 and 5 be:

4: complex_t pr = { s * cos(a), s * sin(a) };
5: complex_t nr = { -1 * s * cos(a), -1 * s * sin(a) };

Now, notice how I simply multiplied by -1 to get (nr)? Well, I could
of also added PI to (a) in order to get the negative root. So, we are
basically ready to return either (pr), or (nz) to the caller of
(reverse_pow2). Lets flip a coin and store the resulting root in (nz);
line 6 shall be:

6: complex_t nz = (random() < 0.5) ? pr : nr;


Ahhh, now we can actually return a value! Let line 7 be:

7: return nz;


To put it all together, it looks like:



complex_t reverse_pow2(complex_t z, complex_t c)
{
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 = (random() < 0.5) ? pr : nr;
7: return nz;
}



Fine... This will allow one to plot a Julia set by repeatedly calling
(reverse_pow2) using its output as its next input wrt (z). Something
like:

complex_t c = { ... }; // a Julia point
complex_t z = { 0, 0 }; // origin point

for (i = 0; i < N; ++i)
{
z = reverse_pow2(z, c);
}


Its usually better to plot both roots and follow one in order to get a
richer, denser plot. But, this is using a (random()) to choose the
roots... What if we used the value of a bit? Lets alter the function
(reverse_pow2) by adding another parameter (bit) so that it can store
actual information:


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;
}


This is perfect! Believe it or not, we can store a byte just by doing
something like:

complex_t c = { ... }; // a Julia/secret key point
complex_t z = { 0, 0 }; // origin point
bool bits[CHAR_BIT] = { false, true, true, [ect...] }; // bits of a byte

for (i = 0; i < N; ++i)
{
z = reverse_pow2(z, c, bits[i]);
}



where (bits) represent the bits of an arbitrary byte. The final value of
(z) after the iteration above takes place will be a complex number (z)
that uniquely represents the (bits) with respect to the secret key (c).
This (z) can be sent across the wire where the recipient can use (c) to
decode it back to the original (bits). I do not really know how to crack
without (c)! Anyway, before I go on to show you exactly how to decode this
using forward information, can you understand any of that at all? How far
are you with me here? BTW, I thank you so much for your interest, and I
hope I did not make any mistakes in my feeble attempt at a step by step
explanation.



> Reverse that iteration: I am given the iteration count N for a
> pixel at location xy. Calculate a complex number based on the
> iteration count using the reversed formula for "recursion". Except
> call it precursion. Keep doing iterations until the result is WHAT?
> How can I stop the precursion loop if I do not know the original
> complex number?

> Dear Chris M. Thomasson, please make corrections and
> clarification at this basic level for Julia Set reverse iteration.

> What initial complex number does the encryptor use at each xy for
> the recursive formula?

The encryptor, which would be the (reverse_pow2) function above does not
rely on testing a pixel to see if its close to the set. Instead, it
generates pixels that are close to the set!


> What complex numbers z does the decryptor
> use at each xy pixel for the precursive formula?

I will explain the decryptor function, or forward iteration in my next
post. FWIW, the decryptor uses the complex number result of the encryptor
to recreate the (bits). The sign of the real component of z under iteration
actually corresponds to the bits, but in reverse order. It's actually quite
simple to get them back. All of this is already implemented in C++ here:

http://pastebin.com/4Yu8uSKH
(stores a single byte)

http://pastebin.com/VsvH3HdE
(stores every bit pattern in a byte)


> 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.


I hope you can understand some of this! I am sorry if its comes across as
total non-sense. I just know it works, and I have implemented it several
times. Anyway, I have to go now. I will have some more time tomorrow to
tell you exactly how to implement the forward iteration that reconstructed
the stored bytes.


Enjoy! ? ;^o

omni...@gmail.com

unread,
Jun 10, 2016, 10:52:04 AM6/10/16
to
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?

> > 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? 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? 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.

Chris M. Thomasson

unread,
Jun 10, 2016, 2:43:15 PM6/10/16
to
> "Rich" wrote in message news:njbeut$s0g$1...@dont-email.me...
Yes. This tree branching left and right, directly corresponds to what root
is
being followed wrt the value of the bit at that level of the tree.


> If so, this sounds very similar to arithmetic or range coding systems
> use to compress input data into a smaller output.

> https://en.wikipedia.org/wiki/Arithmetic_coding
> https://en.wikipedia.org/wiki/Range_encoding

Ahhhh... Humm, I think it’s a bit different, but I need to refresh my mind.

Thank you for the links Rich!

:^D

FromTheRafters

unread,
Jun 10, 2016, 3:43:39 PM6/10/16
to
Rich presented the following explanation :

[...]

> If I understand your long paragraph above, you are walking down a
> fractal tree, and choosing a path to follow to a next lower 'node'
> based upon bits from the input data.
>
> If so, this sounds very similar to arithmetic or range coding systems
> use to compress input data into a smaller output.
>
> https://en.wikipedia.org/wiki/Arithmetic_coding
> https://en.wikipedia.org/wiki/Range_encoding

That helps. So I'm guessing it is a little like prefix encoding except
the 'windswept' tree aspect is left out and uses a key instead for the
binary decisions.

Chris M. Thomasson

unread,
Jun 10, 2016, 7:13:23 PM6/10/16
to
> <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.

:^)

Chris M. Thomasson

unread,
Jun 10, 2016, 8:19:04 PM6/10/16
to
"Chris M. Thomasson" wrote in message news:njfhie$1jl6$1...@gioia.aioe.org...

[...]
> Now, we need to return the updated value of (z), therefore line 2,
> outside the loop body will be:

> 3: return z;
^^^^^^^^^^^^^

That should be line 2.

> 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 above should read as:

3: complex_t ciphertext_byte = encrypt_byte(z, c, plaintext_byte);


Sorry about these typos! ;^o

Chris M. Thomasson

unread,
Jun 10, 2016, 10:15:13 PM6/10/16
to
> <omni...@gmail.com> wrote:
> in message news:a7ccc0ae-69dc-4d2b...@googlegroups.com...

> 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?

FWIW, the size of the plaintext in my fractal encryption adds
on 256 bits of information. This is in the form of an IV comprised
of two double precision complex numbers that represent offset axes
into the secret key axes. Entropy from forward iteration is used
to encrypt each plaintext byte.

Here is the C command line version code:

http://pastebin.com/D7N4vBWa

and instructions on exactly how to use it:

https://groups.google.com/forum/#!original/sci.crypt/h4lSsDswVbU/NAD_xXJXBwAJ


Also, I made a version of this and put it online:

http://funwithfractals.atspace.cc/ffe

;^)

Chris M. Thomasson

unread,
Jun 12, 2016, 4:05:21 PM6/12/16
to
> "FromTheRafters" wrote in message news:njf596$10ld$1...@gioia.aioe.org...
FWIW, I am still not sure how its related to anything that
uses a probability factor. This is just choosing 2 roots to
follow from the bits comprising a deterministic source: the
plaintext. Humm, I do wonder if this can be cleverly/exotically
combined with range and/or arithmetic encoding scheme.

Humm... I think it can.

Chris M. Thomasson

unread,
Jun 15, 2016, 3:07:29 PM6/15/16
to
On 6/9/2016 3:04 AM, Rich wrote:
> Chris M. Thomasson <nos...@nospam.com> wrote:
>>> "Rich" wrote in message news:njah1q$u0g$1...@dont-email.me...
> [...]
>>> If I understand your long paragraph above, you are walking down a
>>> fractal tree, and choosing a path to follow to a next lower 'node'
>>> based upon bits from the input data.
>>>
>>> If so, this sounds very similar to arithmetic or range coding systems
>>> use to compress input data into a smaller output.
>>>
>>> https://en.wikipedia.org/wiki/Arithmetic_coding
>>> https://en.wikipedia.org/wiki/Range_encoding

IMVHO, Arithmetic coding is very fractal wrt zooming in on those
probability ranges. I think this can be applied to Iterated Function
Systems and the probability ranges they use.

https://en.wikipedia.org/wiki/Iterated_function_system

Heck, Arithmetic coding can come into play wrt the Chaos game as well:

https://en.wikipedia.org/wiki/Chaos_game

And can be applied and used within Fractal Encryption.

Thanks again for the links Rich!

:^D

Chris M. Thomasson

unread,
Jun 15, 2016, 3:14:10 PM6/15/16
to
On 6/15/2016 12:07 PM, Chris M. Thomasson wrote:
> Chris M. Thomasson <nos...@nospam.com> wrote:
[...]
> IMVHO, Arithmetic coding is very fractal wrt zooming in on those
> probability ranges. I think this can be applied to Iterated Function
> Systems and the probability ranges they use.
>
> https://en.wikipedia.org/wiki/Iterated_function_system

FWIW, the probability range for an IFS can be something like:

http://www.fractalforums.com/ifs-iterated-function-systems/simple-2d-forest-setting-non-linear-ifs

Where `rn' is a random number from 0...1:
____________________________
if (rn < 0.0108)
{
px = px - tan(px) + (cos(px) / 2.0);
py = py + abs(cos(px * 1.618));
}

else if (rn < 0.068)
{
px = cos(px - 0.01);
py = sin(py + 0.4);
}


else
{
px = cos(px + 0.6);
py = sin(py / 1.168);
}
____________________________

Here is a very crude rendering I made a while back:

https://plus.google.com/101799841244447089430/posts/jfpsXNaRc3x

BTW, toes this IFS work for you? Also, I posted it to sci.math, and it
was referred to as "cute"! ;^)

https://groups.google.com/d/topic/sci.math/A0O7CEcgCXg/discussion


Notice the probability range in there? Perhaps any IFS can store data
wrt Arithmetic coding idea...

Need to think! Why should fractal encryption be limited to Julia sets?

Chris M. Thomasson

unread,
Jun 15, 2016, 3:15:44 PM6/15/16
to
On 6/15/2016 12:13 PM, Chris M. Thomasson wrote:
[...]
> Here is a very crude rendering I made a while back:
>
> https://plus.google.com/101799841244447089430/posts/jfpsXNaRc3x
>
> BTW, toes this IFS work for you?
^^^^^

Ummm, that should read:

BTW, does this IFS work for you?

;^o

austin...@hotmail.com

unread,
Jun 21, 2016, 5:40:51 AM6/21/16
to
> I've been following your development work on "Reverse Iteration Fractal Encryption" and would like to make this comment. From my own experience of having developed "ShuttlePads" along similar lines I think I can say with impunity that there must not be any functional relationship between the elements i.e. the elemental fractals.

Is there more to come?

adacrypt

Chris M. Thomasson

unread,
Jun 21, 2016, 4:35:27 PM6/21/16
to
Can you please drill down a bit more on what you mean by “the elemental
fractals”? I am having some trouble identifying your statement, sorry
about that Austin! ;^o

Do the “elements” you are referring to have to do with each node in the
square root tree that is created during reverse iteration of (z=z^2+c)?


> Is there more to come?

Yes! I have almost completed a little webpage that shows exactly whats
going on here, and allows a user to visualize the encryption/decryption
process. The problem is that I am doing this for fun, on my free time,
which is rather limited at the moment.

;^(

Chris M. Thomasson

unread,
Jun 21, 2016, 6:50:23 PM6/21/16
to
On 6/9/2016 3:04 AM, Rich wrote:
>> Chris M. Thomasson <nos...@nospam.com> wrote:
[...]
>> Polar form helps out quite a bit. The neat thing is that one can
>> use the bits of a plaintext to choose what root to use during this
>> inverse iteration. Bit on is positive, and off is a negative root.
>> At the end of encoding, one ends up with an interesting point z. The
>> sign of the real part of z during forward iteration can reconstruct
>> the bits stored during inverse iteration.

> If I understand your long paragraph above, you are walking down a
> fractal tree, and choosing a path to follow to a next lower 'node'
> based upon bits from the input data.
>
> If so, this sounds very similar to arithmetic or range coding systems
> use to compress input data into a smaller output.
>
> https://en.wikipedia.org/wiki/Arithmetic_coding
> https://en.wikipedia.org/wiki/Range_encoding

Actually, using Arithmetic Coding is a bit similar wrt using it to store
bits. The probability range would be for two symbols, on and off. Going
to the left and right side of the range is similar to choosing the
positive and negative roots during encoding. However, there are radical
differences wrt how the encoding/decoding procedure actually works. For
instance, during decoding, I do not need place a number in the range in
order to find out what bit was encoded. I just need to look at the sign
of the real part during each step of forward iteration to get at the
bits. Also, I am working in the complex plane with real and imaginary
parts...

austin...@hotmail.com

unread,
Jun 22, 2016, 3:19:57 AM6/22/16
to
I have been assuming that a plaintext would somehow be mapped to a fractal during encryption and again reverse-mapped during decryption?

Good luck - Austin

MM

unread,
Jun 22, 2016, 3:40:20 AM6/22/16
to
On Wednesday, 22 June 2016 08:19:57 UTC+1, austin...@hotmail.com wrote:
> > > I've been following your development work on "Reverse Iteration Fractal
> > > Encryption" and would like to make this comment. From my own experience
> > > of having developed "ShuttlePads" along similar lines I think I can say
> > > with impunity that there must not be any functional relationship between
> > > the elements i.e. the elemental fractals.
> >
> > Can you please drill down a bit more on what you mean by “the elemental
> > fractals”? I am having some trouble identifying your statement, sorry
> > about that Austin! ;^o
> >
> > Do the “elements” you are referring to have to do with each node in the
> > square root tree that is created during reverse iteration of (z=z^2+c)?
:
> I have been assuming that a plaintext would somehow be mapped to a fractal
> during encryption and again reverse-mapped during decryption?

This doesn't address his question.

M
--

austin...@hotmail.com

unread,
Jun 22, 2016, 3:49:16 AM6/22/16
to
In the broadest of terms your cryptography (rather like my own) takes cryptology back to where it should have been since the inception of computer science 50 years ago - i.e.in the heart of mathematics and computer science.

- Good luck again - Austin

austin...@hotmail.com

unread,
Jun 22, 2016, 4:41:29 AM6/22/16
to
On Tuesday, June 21, 2016 at 11:50:23 PM UTC+1, Chris M. Thomasson wrote:
Sounds a bit like an adaptation of Tree Sort ?
Austin

Chris M. Thomasson

unread,
Jun 23, 2016, 2:01:50 AM6/23/16
to
Humm, well, its not really like a binary tree. In this case, the
decisions of insertion do not depend on whether or not a value is
greater or less than any existing nodes values.

Chris M. Thomasson

unread,
Jun 23, 2016, 3:18:54 AM6/23/16
to
FWIW, this is the way I did it before using forward iteration. Each
plaintext byte is treated as a pixel. Each pixel is converted to a point
on the complex plane and run through the fractal formula using forward
iteration. They are encrypted using the escape time, elements from an
orbit trap, and the complex number results themselves. Here is a rather
crude example of it online:

http://funwithfractals.atspace.cc/ffe

And some further information on a command line version in C:

https://groups.google.com/forum/#!original/sci.crypt/h4lSsDswVbU/NAD_xXJXBwAJ


However, the reverse iteration technique is a bit different. Each
plaintext byte is encoded using reverse iteration by using the value of
the bits comprising the byte to choose what root to ultimately follow.
This is different that converting the plaintext into axes into the
complex plane. FWIW, I am in the process of integrating the reverse
iteration into my existing fractal encryption.

Chris M. Thomasson

unread,
Jun 23, 2016, 3:54:50 PM6/23/16
to
You are correct. FWIW, I think Austin might be referring to each element
as the complex numbers that are mapped to each plaintext byte. This is
basically correct for my original, forward iteration based fractal
encryption scheme.

austin...@hotmail.com

unread,
Jun 24, 2016, 7:23:52 PM6/24/16
to
Hi Chris,

The very nature of cipher research impies to me that you are probably way down some road that is alien to me on the back of my possessing only a very hands-on Engineers' practical knowledge of complex numbers.

The Argand diagram on a presumed XY plane is as far as I normally go and the dynamics of fractals generation in computer graphics is over my head at the moment.

*I am very pleased at the reality of your work in taking cryptology back into mathematics and computer science where it should always have been since the inception of computers and computer science dome fifty years ago.

Could I ask you to spell out thoroughly the finer points of your eventual encryption model so that we can all go forward with confidence and with mutual understanding all round - a dedicated model from you is still expected by me at least and I'm sure by others also -(don't worry about patronising).

Lots of Good luck.

Austin

Chris M. Thomasson

unread,
Jun 25, 2016, 3:43:07 PM6/25/16
to
Hey now: That's a great start! The Argand diagram is actually very
important here. You can plot any complex number onto the Cartesian plane
where real part is x, imaginary part is y. This is what we do in
Buddhabrot's:

http://paulbourke.net/fractals/buddhabrot

Take a complex number (c), and a origin (z). Run them through an iteration:
______________________________________
loop N times
{
0: z = z^2 + c
1: plot z onto the pixel based screen
}
______________________________________

Buddhabrots plot every iteration, or orbit if you will, and can reap
renderings like:

http://www.fractalforums.com/index.php?action=gallery;sa=view;id=17279
(this was my first try at a Buddhabrot...)

Are you having trouble with step (0) and/or (1)? Can you add, subtract
or raise a complex number to a power?: what about multiply them? IMVHO,
you should not have that much trouble with step (1) if you can create an
Argand diagram. If not, I can help you out here. Think of the plaintext
bytes as pixels in a bitmap... Each pixel has a unique complex number
mapped to it. This complex number is run through forward iteration (z =
z^2 + c), and every (z) is plotted. Well, this is virtually identical to
plotting a fractal on the screen. Except, the resolution of the screen
(xmax, ymax) wrt my initial version of fractal encryption is dictated by
the number of bytes in the plaintext.

Think of the Argand diagram as the screen, and you are mapping complex
numbers z[n] to it, and each z[n] is a point in the diagram
corresponding to a specific plaintext byte. Each plaintext byte has a
unique point in the Argand diagram.

FWIW, here is some fairly simple javascript code for complex numbers, as
cheat sheet if you will, where the parameters for the functions are arrays:

The [0] index is the real part, and the [1] index is the imaginary part.

https://groups.google.com/d/topic/comp.lang.javascript/dgakiMzhgv0/discussion


The link above contains all the functionality one needs to do the
complex number calculations required for both forward, and reverse
iteration fractal encryption. Humm... This does use polar coordinates.
Can you convert a complex number into polar form? It's quite apparent on
the Argand diagram, that radius and angle are an integral property wrt
complex numbers...


> *I am very pleased at the reality of your work in taking cryptology
> back into mathematics and computer science where it should always
> have been since the inception of computers and computer science
> dome fifty years ago.

Math is the KEY here! :^D


> Could I ask you to spell out thoroughly the finer points of your
> eventual encryption model so that we can all go forward with confidence
> and with mutual understanding all round - a dedicated model from you
> is still expected by me at least and I'm sure by others also -(don't
> worry about patronising).

As of now, I am not quite sure what the long term goals are as I am
still in the process of integrating reverse iteration into my existing
scheme. Basically, I just want somebody to be able to crack the crap out
of fractal encryption in general. This would be very important, and
interesting to me because the crack gives one a deeper, more important
insight into the nature of fractals themselves.

I am doing this for fun. If something that works for protecting bank
accounts actually arises, well I would be stunned, and pleased at the
same time. For now, I have limited time to work on it. In my heart of
hearts, I think this has some fairly decent promise that fractal
encryption can be very good, or at least its methods might be able to be
used to improve existing encryption schemes.



> Lots of Good luck.

Thank you very much for the kind comment Austin!

:^)

Peter Fairbrother

unread,
Jun 26, 2016, 11:52:58 AM6/26/16
to
On 21/02/16 21:38, Chris M. Thomasson wrote:
> Original idea by Juaquin Anderson in the comments of the
> following thread:
>
> https://plus.google.com/+JuaquinAnderson/posts/L9A3Da8ju3B
>
>
> FWIW, here is the content of the comment:
> _________________________________________________
> “This has me thinking.. All the structure, in the reverse
> iteration, and the sequence of roots, as well as the structure
> of the level sets with the escape time algorithim.
> Someone
> suggested using fractals for encryption..
>
> A method that would
> actually work would be to choose an interesting value of c,
> like this one, as the key.
>
> 1) If the message has length n bits,
> choose a point in the n'th level set. The point can be chosen
> by taking a starting point just outside the circle delimiting
> the target set,

I don't get this bit. I am not a chaos theorist, and I do not understand
_exactly_ what is being proposed. Could you explain further?

Please try and be as precise as you can.


For example, what is the n-th level set? Is it the same thing as the
target set? (if so, please don't call it by two different names... )

I initially thought it was the set of points which remain less than some
value after n iterations (presumably of x -> x^2 + c) - or possibly that
set minus the set for n-1 iterations - but I don't see how that would be
delimited by a circle.


Can c be freely chosen from some large range?


> and applying inverse iteration, choosing roots
> by sign according to the bits in the sequence to be encoded.

Is that the actual encryption operation?

>
> 2)
> the result would be a point (x+yi) that is inside the nth level
> set close to the Julia set.


> 3) encode that point accurately
> enough to not confuse with points of a level deeper or further
> out, and transmit that point.
>
> 4) receive that point.
>
> 5) decode
> the point by applying forwards iteration with the key value c,
> until the point lands in the target set. The decoded message
> would have n bits determined by writing down the sign of the
> imaginary component of the escape orbit for each iteration.


This last part 5, decode by repeatedly iterating and taking the sign of
the imaginary parts as plaintext bits, seems like it would work.

but oh oh, what is an escape orbit? for each iteration?

If you/he means the imaginary part of x, then it seems to make some sense.

But what is the imaginary component of the escape orbit of an iteration?



I still don't see how you get the initial ciphertext.

Repeated reverse iterations and choosing which root to use, OK, I get
that. But how do you choose the starting point, given some
arbitrarily-chosen c?




Assuming you can do that, as a cipher it seems to have several
disadvantages: first, it is computationally expensive.

Second, the ciphertext is somewhat longer than the plaintext. For cipher
purposes, you need too be able to encrypt say 128 bits in a block -
there are some 64-bit block ciphers still around, but they are
deprecated, and some people say you need 256 bits in a block nowadays.

As a corollary to the above, the actual length needed for the ciphertext
is ... variable, which is a bit disconcerting.

Another corollary, you might have to check whether each block decrypts
correctly, so as to tell whether you have enough precision ..

So in general it isn't that useful as a cipher.

except ..

it *may* have a slightly interesting security property, ie a strong
proof of security.

This is kinda a holy grail for some cryptologists, and if I am right
about that, it may have some limited use.



> Sounds easy right?

Maybe if you are a chaos theorist ..

- Peter Fairbrother

ps ignore anything austinobyrne has to say - he is a well-known idiot.

>
> :-)
>
> The efficiency of the encrypted coding scheme has to do with
> the fractal dimension of the Julia set, and the degree of
> imbalance of the contractivity in the tree traversal of the
> Julia set."

ps nope, that makes no sense to me either ..



Gordon Burditt

unread,
Jun 27, 2016, 2:34:03 AM6/27/16
to
> Take a complex number (c), and a origin (z). Run them through an iteration:
> ______________________________________
> loop N times
> {
> 0: z = z^2 + c
> 1: plot z onto the pixel based screen
> }
> ______________________________________

You can do this calculation mathematically, but can you do this
exactly with a computer? Do you need to do the calculation exactly?

What's bothering me here is that computer arithmetic is done with
finite precision, and you will rapidly end up with irrational numbers
and numbers that require too much storage to store exactly (e.g.
128GB per complex number, to go to a ridiculous extreme). You will
probably run into problems that two standards-compliant arithmetic
units will not produce the exact same results (e.g. they sometimes
round in opposite directions), so, for example, your code running
on a PC and a MAC or ARM will not interoperate, and you might have
problems finding a bignum package that will get around differences
in hardware and always produce the exact same results.

I am unclear on how you go from a message to a complex number (and
back), and how much precision is needed to do that, and what happens
if the calculations are not exact.

Try it with a manual calculation, for example, where you use a
calculator and round off to 2 significant decimal digits after each
addition, subtraction, multiplication, division, and trig function
lookup.

> Buddhabrots plot every iteration, or orbit if you will, and can reap
> renderings like:
>
> http://www.fractalforums.com/index.php?action=gallery;sa=view;id=17279
> (this was my first try at a Buddhabrot...)
>
> Are you having trouble with step (0) and/or (1)? Can you add, subtract
> or raise a complex number to a power?: what about multiply them? IMVHO,
> you should not have that much trouble with step (1) if you can create an
> Argand diagram. If not, I can help you out here. Think of the plaintext
> bytes as pixels in a bitmap... Each pixel has a unique complex number
> mapped to it.

Approximate math will not yield a single unique complex number. It
might be close enough to map into the same "pixel".

> This complex number is run through forward iteration (z =
> z^2 + c), and every (z) is plotted. Well, this is virtually identical to
> plotting a fractal on the screen. Except, the resolution of the screen
> (xmax, ymax) wrt my initial version of fractal encryption is dictated by
> the number of bytes in the plaintext.
>
> Think of the Argand diagram as the screen, and you are mapping complex
> numbers z[n] to it, and each z[n] is a point in the diagram
> corresponding to a specific plaintext byte. Each plaintext byte has a
> unique point in the Argand diagram.
>
> FWIW, here is some fairly simple javascript code for complex numbers, as
> cheat sheet if you will, where the parameters for the functions are arrays:
>
> The [0] index is the real part, and the [1] index is the imaginary part.
>
> https://groups.google.com/d/topic/comp.lang.javascript/dgakiMzhgv0/discussion
>
>
> The link above contains all the functionality one needs to do the
> complex number calculations required for both forward, and reverse
> iteration fractal encryption. Humm... This does use polar coordinates.
> Can you convert a complex number into polar form? It's quite apparent on
> the Argand diagram, that radius and angle are an integral property wrt
> complex numbers...
>
> Math is the KEY here! :^D

And if the math is approximate, will the key still fit?

> As of now, I am not quite sure what the long term goals are as I am
> still in the process of integrating reverse iteration into my existing
> scheme. Basically, I just want somebody to be able to crack the crap out
> of fractal encryption in general. This would be very important, and
> interesting to me because the crack gives one a deeper, more important
> insight into the nature of fractals themselves.

I'm particularly concerned that reverse iterations won't exactly
undo forward iterations (and note that you round ON EACH ITERATION),
similar to dividing by the square root of 2, then taking that result
and multiplying the square root of 2, in finite-precision arithmetic.

austin...@hotmail.com

unread,
Jun 27, 2016, 3:21:13 AM6/27/16
to
Well said Gordon.

adacrypt

austin...@hotmail.com

unread,
Jun 27, 2016, 4:07:55 AM6/27/16
to
On Monday, June 27, 2016 at 7:34:03 AM UTC+1, Gordon Burditt wrote:
Complex numbers and Calculus must surely be the mist unrewarding areas of research in crypto mathematics - the man himself has said it is a fun thing with him but I reckon this group deserves more respect.

Austin

austin...@hotmail.com

unread,
Jun 27, 2016, 5:18:07 AM6/27/16
to
On Monday, June 27, 2016 at 7:34:03 AM UTC+1, Gordon Burditt wrote:
I think it should be emphasised also that,

1) The trend is for personal cryptography by private home computer users being implemented on handheld devices.

2) Ciphers must be able to read in (by copy and paste say) and then immediately encrypt in the same action huge documents of in excess of 1 million characters as batch files of secured information.

3) Ciphers must be able to encrypt secured emails being implemented in real time.

4) Ciphers need to be able to run on usb flash memory sticks in suspect computers without leaving traces on hard drives.

I have two ciphers on the table that can do this.

Adacrypt

Austin O'Byrne

Rich

unread,
Jun 27, 2016, 6:41:54 AM6/27/16
to
austin...@hotmail.com wrote:
> I have two ciphers on the table that can do this.

You have two ciphers that can do "none" of the items you listed.

Also, for the same reason that we admonished Chris to stop being an
arse and hijacking other threads to bring up his encryption, the same
goes for you. This thread's subject has nothing to do about your
broken ineffective crypto algorithms.

If the only thing you have to bring up in *another* thread is your
broken algorithms, then do not reply to that *other* thread. Post
about your broken algorithms only in threads that are about your broken
algorithms.

MM

unread,
Jun 27, 2016, 1:50:35 PM6/27/16
to
On Monday, 27 June 2016 09:07:55 UTC+1, austin...@hotmail.com wrote:
> Complex numbers and Calculus must surely be the mist unrewarding areas of research in
> crypto mathematics - the man himself has said it is a fun thing with him but I reckon this
> group deserves more respect.

Surely you need to know sufficient maths to have an opinion like this taken seriously?

Show some respect, yourself. Start by learning something.

M
--

Chris M. Thomasson

unread,
Jun 27, 2016, 4:17:08 PM6/27/16
to
On 6/26/2016 8:52 AM, Peter Fairbrother wrote:
> On 21/02/16 21:38, Chris M. Thomasson wrote:
>> Original idea by Juaquin Anderson in the comments of the
>> following thread:
[...]
>> 5) decode
>> the point by applying forwards iteration with the key value c,
>> until the point lands in the target set. The decoded message
>> would have n bits determined by writing down the sign of the
>> imaginary component of the escape orbit for each iteration.
>
>
> This last part 5, decode by repeatedly iterating and taking the sign of
> the imaginary parts as plaintext bits, seems like it would work.
>
> but oh oh, what is an escape orbit? for each iteration?
>
> If you/he means the imaginary part of x, then it seems to make some sense.

FWIW, my experiments say its the sign of the (real) part, during forward
iteration that can recreate the bits stored during reverse iteration:

http://pastebin.com/VsvH3HdE

Juaquin must have made a mistake here. Or, I created another version
accidentally that works with real. I will ask him. I need to go right
now, I have fairly limited time to work on this.

Your question is very great; insightful indeed! I will get back to you
later on tonight, or tomorrow morning. Also, take a close look at these
two threads:

https://groups.google.com/forum/#!original/sci.crypt/mycXj0ViYaw/hVFJ3vE4BAAJ

https://groups.google.com/forum/#!original/sci.crypt/mycXj0ViYaw/lS28y_52BAAJ

All of the required math can be found here:

https://groups.google.com/d/topic/comp.lang.javascript/dgakiMzhgv0/discussion

Sorry, got to go now.

;^o


[...]



Chris M. Thomasson

unread,
Jun 27, 2016, 4:21:16 PM6/27/16
to
On 6/26/2016 8:52 AM, Peter Fairbrother wrote:
> On 21/02/16 21:38, Chris M. Thomasson wrote:
>> Original idea by Juaquin Anderson in the comments of the
[...]

Read this as well:

https://plus.google.com/101799841244447089430/posts/1YKAJn1XKYd


Peter Fairbrother

unread,
Jun 28, 2016, 6:19:54 PM6/28/16
to
On 27/06/16 07:33, Gordon Burditt wrote:
>> Take a complex number (c), and a origin (z). Run them through an iteration:
>> ______________________________________
>> loop N times
>> {
>> 0: z = z^2 + c
>> 1: plot z onto the pixel based screen
>> }
>> ______________________________________
>
> You can do this calculation mathematically, but can you do this
> exactly with a computer? Do you need to do the calculation exactly?
>
> What's bothering me here is that computer arithmetic is done with
> finite precision, and you will rapidly end up with irrational numbers
> and numbers that require too much storage to store exactly (e.g.
> 128GB per complex number, to go to a ridiculous extreme). You will
> probably run into problems that two standards-compliant arithmetic
> units will not produce the exact same results (e.g. they sometimes
> round in opposite directions), so, for example, your code running
> on a PC and a MAC or ARM will not interoperate, and you might have
> problems finding a bignum package that will get around differences
> in hardware and always produce the exact same results.


Some thoughts here: first, perhaps the bignum package can/should be part
of the cipher code.

Second, if it is part of the cipher code, then the encrypter can use it
to trial-decrypt the ciphertext and check whether it decrypts correctly.
If not. he can (I think) just add some more bits.

Third, consider it as a block cipher - you would want maybe 128 or 256
bits in a block, and so 128 or 256 iterations, maximum.




I haven't thought this through completely - and people keep urging me to
read things instead, which is unlikely to happen - but it seems to me
that there must be a limit as to how far a single lowest-bit flip can
change the next iteration.

And thus how far a single lowest-bit flip can change the n-th iteration.

At a somewhat wild guess (well not really..) in this case, if you are
sticking to say 128 iterations/=128-bits-per-block, I think you can with
_100% reliability_ get by with 256 bits per component, so 512 bits in
total per complex number/ciphertext.

Anecdotal evidence of people semi-reliably getting 40 iterations with
64-bit precision would seem to support that idea.

Sensitive dependence on initial conditions - but not unduly sensitive.


So (if I am correct) ciphertext would be 4 times plaintext. And it is
expensive computationally. But it may have some nice security properties.




further thoughts:

fix one component of c at 0, +-1, +-2, +-3.

fix the last 128 bits of one/both components of c at zero.

do the math as integers modulo some prime.




-- Peter F


Chris M. Thomasson

unread,
Jun 29, 2016, 10:49:40 PM6/29/16
to
On 6/26/2016 8:52 AM, Peter Fairbrother wrote:
The n-th level set is the n-th node in the “tree” created by the bits in
the plaintext bytes. So, if we store a byte per complex number we go
down CHAR_BIT levels in the “root tree” where every left-right decision
is a bit in a byte during reverse iteration. The level sets are
basically the equipotential field lines of a Julia set. Here is an
example rendering:

https://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/Julia_set#/media/File:LCMJ_rabbit.jpg

If you keep zooming out, they converge into a circle. If you zoom in,
they start to flow around the highly intricate border structure of the
fractal.



> or possibly that
> set minus the set for n-1 iterations - but I don't see how that would be
> delimited by a circle.

I think he means plotting the target set represented by the secret key
(c), and taking the largest distance (z) gets from the origin during
iteration of (c) on random data. (r) is the radius for a circle that the
set is inscribed within. I will try to clarify this with Juaquin.


> Can c be freely chosen from some large range?

Well, kind of. Humm, these numbers are not going to be very large, but
they can be very small, and describe precise Julia set locations in the
Mandelbrot set. However, I have managed to store bytes in values of
(c)'s that are fairly far away as well. Here are some example points,
that are all valid secret key values of (c):

http://colinlmiller.com/fractals/gallery.htm

Many digits in these suckers, and there all VERY important! Basically,
values of (c) are restricted by the level of precision used to represent
them. This project would be really interesting with a bignum lib, but
its still fun to pack information into floats. Here are some lower
precision example points:

{-1.295189; 0.440936}
{-1.746695; 0.000037}
{-0.74543, 0.11301}
{0.0, 1.0}
{0.0, -1.0}

Yes, these points are mostly on the negative side of the real axes, but
they contain fine grain structure, and can store data: more than a
single byte. Also, you can get a finer grain point:

real part =
-1.985,540,371,654,130,485,531,439,267,191,269,851,811,165,434,636,382,820,704,394,766,801,377

imag part =
+0.000,000,000,000,000,000,000,000,000,001,565,120,217,211,466,101,983,496,092,509,512,479,178



>> and applying inverse iteration, choosing roots
>> by sign according to the bits in the sequence to be encoded.
>
> Is that the actual encryption operation?

Exactly yes. The ciphertext is the complex number result from reverse
iteration.


>
>>
>> 2)
>> the result would be a point (x+yi) that is inside the nth level
>> set close to the Julia set.
>
>
>> 3) encode that point accurately
>> enough to not confuse with points of a level deeper or further
>> out, and transmit that point.
>>
>> 4) receive that point.
>>
>> 5) decode
>> the point by applying forwards iteration with the key value c,
>> until the point lands in the target set. The decoded message
>> would have n bits determined by writing down the sign of the
>> imaginary component of the escape orbit for each iteration.
>
>
> This last part 5, decode by repeatedly iterating and taking the sign of
> the imaginary parts as plaintext bits, seems like it would work.

Actually, I found that Juaquin must have made an error here. So far, I
can only decrypt the bits by using the sign of the real part during
forward iteration. The imaginary part produces another byte value, that
is not part of the plaintext, yet its definitely related in some way. I
have not explored this “auxiliary” byte in any detail quite yet. Still,
imho, its quite interesting.



> but oh oh, what is an escape orbit? for each iteration?

The escape orbit is the actual value of (z) during forward iteration.
Actually, the signs and/or values of this number can be integrated into
an escape condition to create many wonderful things. Pickover stalks,
and my own field line escape condition work nicely:

http://www.fractalforums.com/new-theories-and-research/plotting-field-lines-during-iteration/
(read all...)

Ahh, well. Shi% hits the fan when one tries to store too many bits for
the current level of precision. The crap arises in the from of (z) going
extremely high, off to positive infinity. Or really low, if the secret
key (c) was inside the non-escaping region of the set. The precision
loss is apparent when you take a look at the digits of (z) during
forward iteration, and compare them to the results of reverse iteration.



> If you/he means the imaginary part of x, then it seems to make some sense.

Humm... All of my “proof of concept” experimental code uses the real part.



> But what is the imaginary component of the escape orbit of an iteration?

The imaginary component of an escape orbit is the imaginary part of (z)
of an iteration.




> I still don't see how you get the initial ciphertext.

Take a deep look at the (iterate_reverse) function in:

http://pastebin.com/VsvH3HdE



> Repeated reverse iterations and choosing which root to use, OK, I get
> that. But how do you choose the starting point, given some
> arbitrarily-chosen c?

Ahhh. The starting point (z) can be very fairly far away from the
origin, or it can be the origin itself. This point quickly converges
into the Julia set of (c), in CHAR_BIT iterations with large (z) will
still be fairly close to the set at the end. The origin point of (z) can
actually plot the equipotential field when its very far away. I used a
starting point of (0, 0) for my example code.

Interestingly, the starting point of (z) can be random.



> Assuming you can do that, as a cipher it seems to have several
> disadvantages: first, it is computationally expensive.

Agreed. The reverse formula is in polar form and uses square root and
trig under iteration. Pretty expensive!


> Second, the ciphertext is somewhat longer than the plaintext. For cipher
> purposes, you need too be able to encrypt say 128 bits in a block -
> there are some 64-bit block ciphers still around, but they are
> deprecated, and some people say you need 256 bits in a block nowadays.

Yeah. There are ways to pack more precision, but there is a limit... Go
to high, and they start going out of control wrt decryption.


> As a corollary to the above, the actual length needed for the ciphertext
> is ... variable, which is a bit disconcerting.
>
> Another corollary, you might have to check whether each block decrypts
> correctly, so as to tell whether you have enough precision ..
>
> So in general it isn't that useful as a cipher.
>
> except ..
>
> it *may* have a slightly interesting security property, ie a strong
> proof of security.
>
> This is kinda a holy grail for some cryptologists, and if I am right
> about that, it may have some limited use.

I was kind of thinking along the same lines here.



>> Sounds easy right?
>
> Maybe if you are a chaos theorist ..
>
> - Peter Fairbrother
>
> ps ignore anything austinobyrne has to say - he is a well-known idiot.

All that aside for a moment, well, it is still good to be friendly? :^o


>>
>> :-)
>>
>> The efficiency of the encrypted coding scheme has to do with
>> the fractal dimension of the Julia set, and the degree of
>> imbalance of the contractivity in the tree traversal of the
>> Julia set."
>
> ps nope, that makes no sense to me either ..

It has to do with how much data the scheme can contain in a single
complex number vs how big these darn things are going to actually be.
AFAICT, they are related to the dimension of the fractal:

https://en.wikipedia.org/wiki/Fractal_dimension

I kind of boils down to the fact that we are storing single bits from
basically one dimensional data (single number) into two dimensions
(single number, comprised of two parts). The imaginary part takes up
extra space in the ciphertext, the 2d point is bigger than the 1d point!



I really need more time to work on this damn it!

Chris M. Thomasson

unread,
Jun 29, 2016, 10:49:54 PM6/29/16
to
On 6/28/2016 3:19 PM, Peter Fairbrother wrote:
> On 27/06/16 07:33, Gordon Burditt wrote:
>>> Take a complex number (c), and a origin (z). Run them through an
>>> iteration:
>>> ______________________________________
>>> loop N times
>>> {
>>> 0: z = z^2 + c
>>> 1: plot z onto the pixel based screen
>>> }
>>> ______________________________________
>>
>> You can do this calculation mathematically, but can you do this
>> exactly with a computer? Do you need to do the calculation exactly?
>>
>> What's bothering me here is that computer arithmetic is done with
>> finite precision, and you will rapidly end up with irrational numbers
>> and numbers that require too much storage to store exactly (e.g.
>> 128GB per complex number, to go to a ridiculous extreme). You will
>> probably run into problems that two standards-compliant arithmetic
>> units will not produce the exact same results (e.g. they sometimes
>> round in opposite directions), so, for example, your code running
>> on a PC and a MAC or ARM will not interoperate, and you might have
>> problems finding a bignum package that will get around differences
>> in hardware and always produce the exact same results.
>
>
> Some thoughts here: first, perhaps the bignum package can/should be part
> of the cipher code.

Agreed.


> Second, if it is part of the cipher code, then the encrypter can use it
> to trial-decrypt the ciphertext and check whether it decrypts correctly.

Exactly right! This trial-decrypt is very important. I think it
basically has to be done.


> If not. he can (I think) just add some more bits.

Yeah, that works. Basically, I simulated this exact moment by starting
with a small number of decimal point precision, say 2, and run every
byte in a plaintext through the encrypt/decrypt cycle of given value of
(c). If there is a single error, I increase the precision by one decimal
point and try again. Once there's enough precision in the numbers such
that everything works, the ciphertext is ready.


> Third, consider it as a block cipher - you would want maybe 128 or 256
> bits in a block, and so 128 or 256 iterations, maximum.

I think it would work well as a block cipher, and simplify things somewhat.


> I haven't thought this through completely - and people keep urging me to
> read things instead, which is unlikely to happen - but it seems to me
> that there must be a limit as to how far a single lowest-bit flip can
> change the next iteration.

I am wondering if the following helps you better understand how
encryption and decryption works:

https://groups.google.com/forum/#!original/sci.crypt/mycXj0ViYaw/hVFJ3vE4BAAJ

https://groups.google.com/forum/#!original/sci.crypt/mycXj0ViYaw/lS28y_52BAAJ

? I think I laid it out fairly clearly, in a step by step manner.



> And thus how far a single lowest-bit flip can change the n-th iteration.

Interesting. Need to think on this.



> At a somewhat wild guess (well not really..) in this case, if you are
> sticking to say 128 iterations/=128-bits-per-block, I think you can with
> _100% reliability_ get by with 256 bits per component, so 512 bits in
> total per complex number/ciphertext.

I still have to do more experimentation, but that sounds about right.


>
> Anecdotal evidence of people semi-reliably getting 40 iterations with
> 64-bit precision would seem to support that idea.

Right.

> Sensitive dependence on initial conditions - but not unduly sensitive.
>
>
> So (if I am correct) ciphertext would be 4 times plaintext. And it is
> expensive computationally. But it may have some nice security properties.

That's what I am thinking as well.


> further thoughts:
>
> fix one component of c at 0, +-1, +-2, +-3.
>
> fix the last 128 bits of one/both components of c at zero.
>
> do the math as integers modulo some prime.

Humm... Need to think here. I know there is a way to project the complex
numbers into the integer plane. Also, I am almost finished with a little
webpage that allows one to encrypt the bytes of plaintext and play
around with different (c)'s and origin point (z)'s. Unfortunately, I
have been really crunched on time.

Chris M. Thomasson

unread,
Jun 30, 2016, 2:15:04 PM6/30/16
to
I think I may have figured out a way to store two numbers in the range
of -999999999999 to +999999999999, along with a byte. In addition to
encrypting a byte with +- roots, we use an origin point for (z) that
stores these two integers. I think the range of these extra numbers are
around 6 bytes each. So, it looks like I can store 13 bytes in a single
16 byte complex number based on two 8 byte doubles. Now, this extra byte
can be a random number, or hold anything we want. Humm... So, the idea
is to simply set (z) to an origin point that contains actual data. This
value of (z) will be restored during decryption. Here is some example data:


Encrypting values: -12301, 989854412345 and 63

z = { -12301, 989854412345 }
c = { -.74543, .11301 }
_____________________________________
z[origin]:((-12301.000000000000000,989854412345.000000000000000)
z[0]:(1) = (703510.625379827688448,703510.634121880866587)
z[1]:(1) = (921.527561135795622,381.708887927776345)
z[2]:(1) = (30.986873249490291,6.157379527378633)
z[3]:(1) = (5.658407163514809,0.534105213067071)
z[4]:(1) = (2.531946317498929,0.083156425978855)
z[5]:(1) = (1.810371315513342,-0.008245152186550)
z[6]:(-1) = (-1.599136856993362,0.037912687602776)
z[7]:(-1) = (-0.040599543843387,0.924854139826196)

Decryption:
------------------------------------------------------------
z[7]:(-1) = (-0.040599543843388,0.924854139826196)
z[6]:(-1) = (-1.599136856993362,0.037912687602775)
z[5]:(1) = (1.810371315513342,-0.008245152186545)
z[4]:(1) = (2.531946317498928,0.083156425978872)
z[3]:(1) = (5.658407163514803,0.534105213067157)
z[2]:(1) = (30.986873249490127,6.157379527379598)
z[1]:(1) = (921.527561135773453,381.708887927834041)
z[0]:(1) = (703510.625379742938094,703510.634121970389970)
z[end]:((-12301.000000000000000,989854412345.000000000000000)
_____________________________________
pt:63 == db:63


This is working. BTW, I am also rounding the final numbers. This
restores problems where the right number is just one digit off, but the
decimal is very close like. 989854412344.789...

This is experimental, but it seems to be working. Trial decrypt is very
important here!

;^o

Chris M. Thomasson

unread,
Jun 30, 2016, 2:53:18 PM6/30/16
to
On 6/26/2016 11:33 PM, Gordon Burditt wrote:
[...]
> I'm particularly concerned that reverse iterations won't exactly
> undo forward iterations (and note that you round ON EACH ITERATION),
> similar to dividing by the square root of 2, then taking that result
> and multiplying the square root of 2, in finite-precision arithmetic.

This is a key concern! A rather "simplistic" way around it is adding
more precision when a trial decrypt fails. The end result of encryption
after trial decrypt succeeds with be a complex number that can be
transmitted as ciphertext with just enough precision to work.

I am thinking of doing this as a block cipher and artificially confining
myself to 16 byte complex numbers as a start, before I move into a
bignum package...

BTW, I think I will have some free time tonight. This is very fun for me
to work on, and I am anxious to get the example webpage working that
allows one to play with this type of encryption, up on the internet.

Rich

unread,
Jun 30, 2016, 2:53:31 PM6/30/16
to
[Note - limited to sci.crypt]

In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
> 16 byte complex number based on two 8 byte doubles. Now, this extra byte
^^^^^^^^^^^^^^^^^^
> ...
> z[1]:(1) = (921.527561135773453,381.708887927834041)
> z[0]:(1) = (703510.625379742938094,703510.634121970389970)
> z[end]:((-12301.000000000000000,989854412345.000000000000000)
> ...
>
> This is working. BTW, I am also rounding the final numbers.

This will be a huge requirement on you here. You will need to be very
precise in exactly how you round if you want others, potentially
running different systems, to obtain repeatable results.

If you have not already done so, you should read this information:

What Every Programmer Should Know About Floating-Point Arithmetic
http://floating-point-gui.de/


The reason you'll need to be precise is that you appear to be
performing successive floating-point computations (i.e., the next
computation uses the result of the prior computation). In this
situation, the small differences accumulate, and depending upon the
implimentation, the end answer can potentially differ enough to result
in a failed decrypt by a receiver.

I.e., you encrypt on an Intel system, where doubles are 8 bytes
(64bits) external to the FPU, but are actually 80bit values internal to
the FPU.

Someone else decrypts on a RaspberryPI, where the FPU uses
64-bit values internally (assumption, for this explanation).

The difference in the internal numerical precision, if you don't
specify exactly how to round at each step, can accumulate enough to
possibly make a difference in what bytes the R-PI user obtains from a
decryption.

Chris M. Thomasson

unread,
Jun 30, 2016, 3:09:38 PM6/30/16
to
On 6/30/2016 11:53 AM, Rich wrote:
> [Note - limited to sci.crypt]
>
> In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
>> 16 byte complex number based on two 8 byte doubles. Now, this extra byte
> ^^^^^^^^^^^^^^^^^^
>> ...
>> z[1]:(1) = (921.527561135773453,381.708887927834041)
>> z[0]:(1) = (703510.625379742938094,703510.634121970389970)
>> z[end]:((-12301.000000000000000,989854412345.000000000000000)
>> ...
>>
>> This is working. BTW, I am also rounding the final numbers.
>
> This will be a huge requirement on you here. You will need to be very
> precise in exactly how you round if you want others, potentially
> running different systems, to obtain repeatable results.

I totally contradicted myself when I wrote that "this is working", and
then wrote:

“This is experimental, but it seems to be working. Trial decrypt is very
important here!”

Sorry about the non-sense! ;^o



FWIW, here is the code I wrote for the round function:
_____________________________________________
iim_float_t round_n(iim_float_t v)
{
iim_float_t s = (v < 0) ? -1 : 1;
iim_float_t a = std::abs(v);
iim_float_t r = std::floor(a + .5);
return r * s;
}
_____________________________________________

It takes the sign (s) of the input parameter (v); takes the absolute
value (a) of (v); takes the floor of (a + .5) as (r), then finally
restores the sign by multiplying (r) by (s) and returning the result to
the caller. Is this total crap, or perhaps just a little? Yikes!


> If you have not already done so, you should read this information:
>
> What Every Programmer Should Know About Floating-Point Arithmetic
> http://floating-point-gui.de/

I have read that, and its excellent! Thank you.


> The reason you'll need to be precise is that you appear to be
> performing successive floating-point computations (i.e., the next
> computation uses the result of the prior computation). In this
> situation, the small differences accumulate, and depending upon the
> implimentation, the end answer can potentially differ enough to result
> in a failed decrypt by a receiver.
>
> I.e., you encrypt on an Intel system, where doubles are 8 bytes
> (64bits) external to the FPU, but are actually 80bit values internal to
> the FPU.
>
> Someone else decrypts on a RaspberryPI, where the FPU uses
> 64-bit values internally (assumption, for this explanation).
>
> The difference in the internal numerical precision, if you don't
> specify exactly how to round at each step, can accumulate enough to
> possibly make a difference in what bytes the R-PI user obtains from a
> decryption.

If I define the required floating point representation and the rounding
on the final iteration wrt decoding, well that just might help out a
little bit?

Humm...

I need to go now, will be able to work on this tonight.

Thanks Rich. :^)

Chris M. Thomasson

unread,
Jun 30, 2016, 4:23:48 PM6/30/16
to
On 6/26/2016 8:52 AM, Peter Fairbrother wrote:
> On 21/02/16 21:38, Chris M. Thomasson wrote:
[...]
> For example, what is the n-th level set? Is it the same thing as the
> target set? (if so, please don't call it by two different names... )
[...]

FWIW, here is an animation of the n-th level sets as
anit-equipotentials: the field lines if you will. Basically the
perpendicular field that can also be used to store data:

https://en.wikibooks.org/wiki/Fractals/Iterations_in_the_complex_plane/Julia_set#/media/File:From_decomposition_to_checkerboard.gif

Here is a fairly crude animation I made of field lines:

http://funwithfractals.atspace.cc/ct_fdla_anime_test_0
(it runs a little slow on a phone...)


Rich

unread,
Jun 30, 2016, 5:26:17 PM6/30/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
> On 6/30/2016 11:53 AM, Rich wrote:
>> [Note - limited to sci.crypt]
>>
>> In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
>>> 16 byte complex number based on two 8 byte doubles. Now, this extra byte
>> ^^^^^^^^^^^^^^^^^^
>>> ...
>>> z[1]:(1) = (921.527561135773453,381.708887927834041)
>>> z[0]:(1) = (703510.625379742938094,703510.634121970389970)
>>> z[end]:((-12301.000000000000000,989854412345.000000000000000)
>>> ...
>>>
>>> This is working. BTW, I am also rounding the final numbers.
>>
>> This will be a huge requirement on you here. You will need to be very
>> precise in exactly how you round if you want others, potentially
>> running different systems, to obtain repeatable results.
>
> FWIW, here is the code I wrote for the round function:
> _____________________________________________
> iim_float_t round_n(iim_float_t v)
> {
> iim_float_t s = (v < 0) ? -1 : 1;
> iim_float_t a = std::abs(v);
> iim_float_t r = std::floor(a + .5);
> return r * s;
> }
> _____________________________________________
>
> It takes the sign (s) of the input parameter (v); takes the absolute
> value (a) of (v); takes the floor of (a + .5) as (r), then finally
> restores the sign by multiplying (r) by (s) and returning the result
> to the caller. Is this total crap, or perhaps just a little? Yikes!

Well, it is rounding to integer values, so I'm assuming that's what you
intended. But if you only do a round using this function after the
last computation, then if you happened to be unlucky enough to have a
value that was very close to a integer, or very close to the half way
point between integers (i.e., 123.49999999999876) and you had just
enough accumulated floating point imprecision in the middle
computations, you might get 123 on your CPU, and someone else might get
124 on their CPU. For the above example, it takes a mere
.00000000000124 of accumulated imprecision in a positive direction to
toggle the value over to be 124 at the end.

If you want repeatability, you'll likely need to specify a rounding
amount after every computation, not just at the end. And the rounding
amount would need to be within the precision range of the mantissa of
the floating point value you are using.

> If I define the required floating point representation and the
> rounding on the final iteration wrt decoding, well that just might
> help out a little bit?

That would help, but you may need to define a rounding that must happen
after every computation before you can be assured of approaching
anything resembling repeatable results across different architectures
(or even within generations on the same architecture).

Chris M. Thomasson

unread,
Jul 1, 2016, 12:15:21 AM7/1/16
to
On 6/30/2016 2:26 PM, Rich wrote:
> Chris M. Thomasson <inv...@invalid.invalid> wrote:
>> On 6/30/2016 11:53 AM, Rich wrote:
>>> [Note - limited to sci.crypt]
>>>
>>> In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
[...]
>> FWIW, here is the code I wrote for the round function:
>> _____________________________________________
>> iim_float_t round_n(iim_float_t v)
>> {
>> iim_float_t s = (v < 0) ? -1 : 1;
>> iim_float_t a = std::abs(v);
>> iim_float_t r = std::floor(a + .5);
>> return r * s;
>> }
>> _____________________________________________
>>
>> It takes the sign (s) of the input parameter (v); takes the absolute
>> value (a) of (v); takes the floor of (a + .5) as (r), then finally
>> restores the sign by multiplying (r) by (s) and returning the result
>> to the caller. Is this total crap, or perhaps just a little? Yikes!
>
> Well, it is rounding to integer values, so I'm assuming that's what you
> intended. But if you only do a round using this function after the
> last computation, then if you happened to be unlucky enough to have a
> value that was very close to a integer, or very close to the half way
> point between integers (i.e., 123.49999999999876)

Ahh! There is an interesting property wrt the size of the numbers we
store in the origin point (z). Is is data on storing (123), (0), and
(63) as a bit:

__________________________________________
z[origin]:((123,0)
z[0]:(1) = (11.12409348223363814156528,-0.005079515026572232853918631)
z[1]:(1) = (3.445260105156299879070048,-0.01713796802305799990562285)
z[2]:(1) = (2.047364243403080319438914,-0.03178427298474479495427047)
z[3]:(1) = (1.671726569376472903982744,-0.04330680496355057002011435)
z[4]:(1) = (1.555532440358869950003395,-0.05024543394526938266952953)
z[5]:(1) = (1.517845376351396602387922,-0.05377867748877805664786678)
z[6]:(-1) = (-1.50543815082906307090127,0.05539539349289292202715984)
z[7]:(-1) = (-0.03302038802140024043030309,0.8724095923671097985163669)
____________________________________________
z[7]:(-1) = (-0.03302038802140024043030309,0.8724095923671097985163669)
z[6]:(-1) = (-1.505438150829062848856665,0.05539539349289283876043299)
z[5]:(1) = (1.517845376351395492164897,-0.05377867748877779296989843)
z[4]:(1) = (1.555532440358867729557346,-0.05024543394526850836889764)
z[3]:(1) = (1.671726569376466242644597,-0.043306804963547634867993)
z[2]:(1) = (2.047364243403058559067631,-0.03178427298473440743009633)
z[1]:(1) = (3.445260105156210173049658,-0.01713796802301406629887026)
z[0]:(1) = (11.12409348223302174574201,-0.005079515026266426258594322)
z[end]:((122.9999999999863007360545,6.809899866233593002107227e-12)
z[end:rounded]:((123,0)
pt = 63
__________________________________________

Notice how close the numbers are here? AFAICT, there is no chance that
adding (.5) during rounding will screw things up with numbers as small
as (123). However, if we choose larger numbers for (z) such as
(+999999999999), well, then you have a point where the probability of
rounding causing an error is getting a little too close for comfort. Humm...

Chris M. Thomasson

unread,
Jul 1, 2016, 12:26:47 AM7/1/16
to
On 6/30/2016 11:15 AM, Chris M. Thomasson wrote:
> I think I may have figured out a way to store two numbers in the range
> of -999999999999 to +999999999999, along with a byte. In addition to
> encrypting a byte with +- roots, we use an origin point for (z) that
> stores these two integers. I think the range of these extra numbers are
> around 6 bytes each. So, it looks like I can store 13 bytes in a single
> 16 byte complex number based on two 8 byte doubles. Now, this extra byte
> can be a random number, or hold anything we want. Humm... So, the idea
> is to simply set (z) to an origin point that contains actual data. This
> value of (z) will be restored during decryption. Here is some example data:
[...]

FWIW, there is a direct connect between the level of precision loss and
the size of the integers we store in the origin point (z).
(+-999999999999) for real and imaginary parts of (z) are about as far as
I can push this thing before shi% hits the damn fan during the decoding
process. Numbers less than that, say (+-9999999999) just get more and
more precise, and that is nice!

Chris M. Thomasson

unread,
Jul 1, 2016, 2:03:28 AM7/1/16
to
On 6/30/2016 11:15 AM, Chris M. Thomasson wrote:
> I think I may have figured out a way to store two numbers in the range
> of -999999999999 to +999999999999, along with a byte. In addition to
> encrypting a byte with +- roots, we use an origin point for (z) that
> stores these two integers. I think the range of these extra numbers are
> around 6 bytes each. So, it looks like I can store 13 bytes in a single
> 16 byte complex number based on two 8 byte doubles. Now, this extra byte
> can be a random number, or hold anything we want. Humm... So, the idea
> is to simply set (z) to an origin point that contains actual data. This
> value of (z) will be restored during decryption. Here is some example data:
[...]
> This is experimental, but it seems to be working. Trial decrypt is very
> important here!

There are many possibilities wrt taking advantage of the extra byte wrt
using +- roots in reverse iteration. We can store plaintext bytes in the
origin points and use random numbers in the extra byte to scramble the
ciphertext even further. Or, we can use it to store information about
the block. We can use the high nibble for random data, and the lower
nibble for information about the block. We can use it for an exponent to
store larger numbers wrt the range of (+-999999999999).

We can store an entire channel of auxiliary/meta data in the extra byte.

This is very interesting to me.

Rich

unread,
Jul 1, 2016, 8:43:37 AM7/1/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
> On 6/30/2016 2:26 PM, Rich wrote:
>> Chris M. Thomasson <inv...@invalid.invalid> wrote:
>>> On 6/30/2016 11:53 AM, Rich wrote:
>>>> [Note - limited to sci.crypt]
>>>>
>>>> In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
> [...]
It is not the 'smallness' or 'largeness' of the numbers that matters.

It is the 'closeness' of any of the numbers to the 1/2 point such that
the magnitude of the sum of the accumulated floating point round off
error from each prior computatuion performed to compute that 'close'
number is larger than the closeness of that number to the half way
point.

Take your final number (z[end]). You have 122.9999999999863007360545
above. Now, lets just say, for sake of example here, that instead you
had 122.500000000000007360545 as [end]. Normally, that value would
round up to 123 and you would be good.

But, the difference beteen 122.5... and an exact 122.5 is
-0.000000000000007360545. That is the "closeness" of the
(hypothetical)) [end] result to 122.5. If, by chance, the accumulated
floating point round off error across the (by my count) 17 sequential
floating point computations was larger in magnitude than
-0.000000000000007360545 (say -.000000000000007360546 [last digit])
you'll have an issue. Note that:

122.500000000000007360545 + -0.000000000000007360546

is 122.499999999999999999999

which will round to 122 in your rounding function at the end.

And, the smaller the numerical distance between any result and that
critical 0.5 point, the smaller net magnitude roundoff error necessary
to trigger a flip (or not trigger a flip) to the next higher integer
improperly.

If instead at [end] you had 122.5000000000000000000001, then you only
need a net roundoff error of -0.0000000000000000000002 across the 17
computations to result in not rounding to 123.

Rich

unread,
Jul 1, 2016, 8:47:50 AM7/1/16
to
In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
That is likely because a 64-bit floating point value stores 53 bits of
mantissa, which works out to somewhere about 15 decimal digits at most.
Your 99... value is already 12 digits, leaving only three fractional
decimal digits for you to use for your 'subdividing' aspect.

Chris M. Thomasson

unread,
Jul 1, 2016, 3:24:03 PM7/1/16
to
Yes, it would! ;^o

However, for a number that small (123) with 64-bit doubles in a complex
number, it would never get that far away. It would be around
(122.99999999[blah]);

Anyway, I am using a fairly nice big decimal library:

http://mikemcl.github.io/decimal.js
(trig functions are a bit slow on high precision numbers, but they work
and allow a proof of concept to be created)

I am storing 256-bit blocks that require around 90 bit's of precision
wrt significant digits. I am using an adaptive encryption algorithm that
performs trial decryption, and adds more precision each time it fails.
Basically, its the same thing that Peter Fairbrother described. He
suggested trial decrypt, and adding more precision. Well, it works. I
can store quite a bit of data in a single complex number. Here is a
simple example ciphertext that stores the following string:

plaintext - 32-bytes, 256-bits:
_______________________________________________
Having Fun With Fractals is Good
_______________________________________________



ciphertext, 81 point of precision required:
_______________________________________________
x:-1.40671908764936961512398419133109623095250597042532480395711455165016474134535925

y:0.00944239408403734327190341674814485098947052840036562960580747161769090947636525034
_______________________________________________


Also, the precision can vary depending on the bit pattern of the 256-bit
block of plaintext. Also, interesting deep zooms wrt the secret key (c)
can be more efficient and require less precision overall.


This is awesome to me! The size of the ciphertext is pretty darn gnarly
in size, but the security is pretty darn nice. Not sure how to crack the
plaintext out of this. Humm...


Example webpage will be online in a couple of days. So far, its working
very nicely.

Thank you Rich!

Rich

unread,
Jul 1, 2016, 4:11:23 PM7/1/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
>> 122.500000000000007360545 + -0.000000000000007360546
>>
>> is 122.499999999999999999999
>>
>> which will round to 122 in your rounding function at the end.
>
> Yes, it would! ;^o
>
> However, for a number that small (123) with 64-bit doubles in a complex
> number, it would never get that far away. It would be around
> (122.99999999[blah]);

Other than your assertion of "trust me, it won't happen" do you have
any coherent explanation for *why* it would never get that far away, or
for *why* it would be around 122.99999999[blah]?

Chris M. Thomasson

unread,
Jul 1, 2016, 4:41:39 PM7/1/16
to
Well, I do not know how to prove it, but storing (+-999999999999) takes
up much more precision in this limited 128-bit space of a complex number
comprised of two 8 byte doubles! 123 is nothing and always gets very,
very close. BTW, what do you think of using the big decimal library? Its
working great. A little slow, but it gets the job done.

Chris M. Thomasson

unread,
Jul 1, 2016, 4:59:51 PM7/1/16
to
Agreed! The nice thing is that it takes around 3 digits of precision to
store that extra byte. This fractal storage thing is very interesting to
me. VERY!

BTW, thank you for your help wrt all the great questions.

Chris M. Thomasson

unread,
Jul 1, 2016, 5:23:45 PM7/1/16
to
On 2/21/2016 1:38 PM, Chris M. Thomasson wrote:
[...]

I am thinking on how to crack this thing. So far, using the following
arbitrary precision library:

https://mikemcl.github.io/decimal.js

allows me to store plaintext in a (single complex number) of a (custom
fitted precision) by performing (trial decrypts) and (adding more
precision) during (reverse iteration).

However, if we were to turn this into a block based cipher, then the
number of complex numbers would be increased; greater than one. Okay, so
if we send a large ciphertext with a lot of complex numbers each
representing a block, well, Eve can simply plot those fuc%ing things and
get a visual insight into possible orbits of (c)! Her job is still hard
because (c) can be a thousand digits. However, she can get close to the
initial area; damn it. The more points we send as ciphertext, the easier
Eve's job gets wrt just plotting them. I can get around this by sending
a single point, or using my existing forward iteration fractal
encryption to heavily disguise each point in the block style
implementation of the reverse fractal cipher. Heck, I can increase
precision and encrypt garbage/random meaningless bits to try and hide
each point. Single point is super hard to crack, multiple points are
easier. The webpage I am working on only deals with reverse fractal in
block style mode, however I am also creating a hybrid with this and my
existing work. Online example:

http://funwithfractals.atspace.cc/ffe

;^)



Rich

unread,
Jul 1, 2016, 5:27:32 PM7/1/16
to
You are still missing the point. It is not how big or how small the
individual numbers are. It is how close one of the numbers (before you
round it) is to the 1/2 point on the number line.

It is a relative issue, against another anchor point, not a "how big is
this thing". You keep missing the point, and repeating that the "size"
of the number is the issue I'm talking about.

Using a big decimal library would, maybe, remove most all of the
rounding issues. Whether it does will depend upon if it uses decimal
or binary internally. If it uses binary, you'll still have the issue
of the much larger number of decimal fractions that have infinite
representations in binary and so can never be stored exactly in a
binary fraction.

Chris M. Thomasson

unread,
Jul 2, 2016, 1:21:26 AM7/2/16
to
On 6/27/2016 12:21 AM, austin...@hotmail.com wrote:
> On Monday, June 27, 2016 at 7:34:03 AM UTC+1, Gordon Burditt wrote:
[...]
>> I'm particularly concerned that reverse iterations won't exactly
>> undo forward iterations (and note that you round ON EACH ITERATION),
>> similar to dividing by the square root of 2, then taking that result
>> and multiplying the square root of 2, in finite-precision arithmetic.
>
> Well said Gordon.

Well, we just add enough precision to make it work; its an adaptive
algorithm based on arbitrary precision via trial decrypt. I am also
taking a look at unum's:

https://en.wikipedia.org/wiki/Unum_(number_format)

Christian Gollwitzer

unread,
Jul 2, 2016, 2:17:48 AM7/2/16
to
Am 01.07.16 um 23:23 schrieb Chris M. Thomasson:
> Online example:
>
> http://funwithfractals.atspace.cc/ffe
>

There is a bug in the decryptor.

I tried: Plaintext -> 6D 32 B0 90 0F 50 4F E3 DE

If I change only a single byte and decrypt

6D 32 B0 90 0F 50 4F E3 DF -> Plaintexu

First I thought it is a flaw, but encrypting again gives a different
ciphertext.

Christian

Chris M. Thomasson

unread,
Jul 2, 2016, 3:25:18 PM7/2/16
to
On 7/1/2016 11:17 PM, Christian Gollwitzer wrote:
> Am 01.07.16 um 23:23 schrieb Chris M. Thomasson:
>> Online example:
>>
>> http://funwithfractals.atspace.cc/ffe
>>
>
> There is a bug in the decryptor.

I don't think there is, but lets see here.

> I tried: Plaintext -> 6D 32 B0 90 0F 50 4F E3 DE

Okay.


> If I change only a single byte and decrypt
>
> 6D 32 B0 90 0F 50 4F E3 DF -> Plaintexu
>
> First I thought it is a flaw,

This is normal. You changed a single byte in the ciphertext. It will
change a single byte in the plaintext. I will do this right now.

The plaintext is
___________________
Christian
___________________


the ciphertext with the default key is:
___________________
0.059597818467851275 0.069599977755982
0.060204896883700613 0.20476592051063616

37 57 40 E6 4B AF 31 4A 83
___________________

You can check this by going to the page, pasting the ciphertext in the
ciphertext box. Click decrypt, and you get your first name.

Now... If I change a single byte, say the last (83), to say (38), and
hit decrypt I get:

______________________
Christia#
______________________


Now, If it hit encrypt again, I get a ciphertext of:
______________________
0.3368721280009776 0.4406627195365929
0.2638329392146355 0.16157543875510105

83 96 47 12 D5 23 FF 60 37
______________________


This decrypts into

______________________
Christia#
______________________



AFAICT, there is no bug. Can you please try out the ciphertext I posted
with the default key and tell me what happens?


> but encrypting again gives a different
> ciphertext.

Yes. Each time you click encrypt it will give a different cipher text
because it inserts an offset location into the ciphertext. These are the
4 base 10 decimal numbers. Each time you click encrypt it randomizes
this IV.

Chris M. Thomasson

unread,
Jul 2, 2016, 3:28:25 PM7/2/16
to
On 7/2/2016 12:25 PM, Chris M. Thomasson wrote:
> On 7/1/2016 11:17 PM, Christian Gollwitzer wrote:
>> Am 01.07.16 um 23:23 schrieb Chris M. Thomasson:
>>> Online example:
>>>
>>> http://funwithfractals.atspace.cc/ffe
>>>
>>
>> There is a bug in the decryptor.
>
> I don't think there is, but lets see here.
>
>> I tried: Plaintext -> 6D 32 B0 90 0F 50 4F E3 DE
>
> Okay.
>
>
>> If I change only a single byte and decrypt
>>
>> 6D 32 B0 90 0F 50 4F E3 DF -> Plaintexu
>>
>> First I thought it is a flaw,
>
> This is normal. You changed a single byte in the ciphertext. It will
> change a single byte in the plaintext.

When you have the secret key, or private key in the webpage, a single
change to a byte in the ciphertext creates a single change in the
resulting plaintext. This is normal.

Chris M. Thomasson

unread,
Jul 2, 2016, 3:47:46 PM7/2/16
to
On 7/1/2016 11:17 PM, Christian Gollwitzer wrote:
> Am 01.07.16 um 23:23 schrieb Chris M. Thomasson:
>> Online example:
>>
>> http://funwithfractals.atspace.cc/ffe
>>
>
> There is a bug in the decryptor.
>
> I tried: Plaintext -> 6D 32 B0 90 0F 50 4F E3 DE
I am sorry, did you use the hexbyte ciphertext for another plaintext?

I get garbage when I map these bytes to ascii table:

m2[blah]

Or, are these hexbytes derived from the ciphertext of a plaintext you
encrypted on the page? I am wondering because there are no axes, the 4
decimal numbers. I cannot decrypt this because I need those darn axes.

Peter Fairbrother

unread,
Jul 2, 2016, 4:26:26 PM7/2/16
to
ah, I'm pretty sure it not secure; it falls to a simple known plaintext
attack.


For the non-cryppies here, a known plaintext attack is where an attacker
knows both the plaintext and ciphertext of a message block, and uses
that plaintext/ciphertext pair to find out something else, usually the key.

This might at first glance sound unlikely or unwieldy, but it was the
type of attack used to break enigma, and a modern cipher would be
expected to withstand something much more severe, eg an adaptive
chosen-ciphertext attack, where the attacker can get decrypts of
ciphertexts he chooses, then use those decrypt results to choose further
ciphertexts, get decrypts of those, and so on.

Defense against known plaintext attacks is a very minimum requirement
for a cipher.



How this known plaintext attack works is, suppose the first bit of the
message is 1, then an attacker can tell something about the key c -
certain values of c in the 1st iteration will give a +ve real part,
certain values won't.

The second iteration is more complicated, but not much more so - you
have to do a double iteration to check, but only certain values of c
will give a +ve or -ve result. The range of possible c's gets smaller.

And so on.

If a single block isn't enough to nail down c, we would expect the
attacker to have access to many blocks using the same c.




So I'm pretty sure it's a bust, as a secure cipher.


-- Peter Fairbrother

Christian Gollwitzer

unread,
Jul 2, 2016, 4:41:43 PM7/2/16
to
Am 02.07.16 um 21:28 schrieb Chris M. Thomasson:
If it's not a bug, then I think it is a flaw. I didn't bother to read
through your algorithm description, and my knowledge of encryption is
shallow - but I know that in modern algorithms, each bit of the output
is dependent on each bit of the input and the key. I think otherwise it
makes it vulnerable to known plaintext attacks. Or is each byte a block
in your block cipher (for demonstration purposes?)

However I do not understand how the website works. If I hit encrypt
multiple times, I get different answers with different public keys, yet
the same private key. Is this intended? I would have expected that there
is a "Generate key" button, and a button "encrypt" and another one
"decrypt" so that I can encrypt different texts with the same key over
and over again.

Christian

Chris M. Thomasson

unread,
Jul 2, 2016, 5:11:56 PM7/2/16
to
On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
> ah, I'm pretty sure it not secure; it falls to a simple known plaintext
> attack.
>
>
> For the non-cryppies here, a known plaintext attack is where an attacker
> knows both the plaintext and ciphertext of a message block, and uses
> that plaintext/ciphertext pair to find out something else, usually the key.
>
> This might at first glance sound unlikely or unwieldy, but it was the
> type of attack used to break enigma, and a modern cipher would be
> expected to withstand something much more severe, eg an adaptive
> chosen-ciphertext attack, where the attacker can get decrypts of
> ciphertexts he chooses, then use those decrypt results to choose further
> ciphertexts, get decrypts of those, and so on.
>
> Defense against known plaintext attacks is a very minimum requirement
> for a cipher.
>
>
>
> How this known plaintext attack works is, suppose the first bit of the
> message is 1, then an attacker can tell something about the key c -
> certain values of c in the 1st iteration will give a +ve real part,
> certain values won't.

Right, but that's normal for any fractal iteration. The signs of the
real parts will flutter back and forth. How do you identify a bit
pattern to a plaintext? There will be bit patterns that create many
different plaintexts, but what one is the correct, original plaintext?
AFAICT, the easiest way to get (c) wrt the block version of the reverse
cipher as is to plot them. Also, the sign of the real part at the end
iteration is the sign of the first bit! This is NO GOOD! So, this final
block style ciphertext needs to be hidden, however... If we send a
single point, then it can be easily hidden, and hard to crack.


>
> The second iteration is more complicated, but not much more so - you
> have to do a double iteration to check, but only certain values of c
> will give a +ve or -ve result. The range of possible c's gets smaller.
>
> And so on.
>
> If a single block isn't enough to nail down c, we would expect the
> attacker to have access to many blocks using the same c.
>
>
>
>
> So I'm pretty sure it's a bust, as a secure cipher.

I think its a stab in the heart. But, what about augmenting this reverse
iteration cipher, with my existing Funny Fractal Encryption based on
forward iteration?

Chris M. Thomasson

unread,
Jul 2, 2016, 5:19:00 PM7/2/16
to
On 7/2/2016 1:41 PM, Christian Gollwitzer wrote:
> Am 02.07.16 um 21:28 schrieb Chris M. Thomasson:
>> On 7/2/2016 12:25 PM, Chris M. Thomasson wrote:
>>> On 7/1/2016 11:17 PM, Christian Gollwitzer wrote:
>>>>
>>>> If I change only a single byte and decrypt
>>>>
>>>> 6D 32 B0 90 0F 50 4F E3 DF -> Plaintexu
>>>>
>>>> First I thought it is a flaw,
>>>
>>> This is normal. You changed a single byte in the ciphertext. It will
>>> change a single byte in the plaintext.
>>
>> When you have the secret key, or private key in the webpage, a single
>> change to a byte in the ciphertext creates a single change in the
>> resulting plaintext. This is normal.
>
> If it's not a bug, then I think it is a flaw. I didn't bother to read
> through your algorithm description, and my knowledge of encryption is
> shallow - but I know that in modern algorithms, each bit of the output
> is dependent on each bit of the input and the key. I think otherwise it
> makes it vulnerable to known plaintext attacks. Or is each byte a block
> in your block cipher (for demonstration purposes?)

Each byte is a block. It transforms each byte in the plaintext to a
point in the complex plane.


>
> However I do not understand how the website works. If I hit encrypt
> multiple times, I get different answers with different public keys, yet
> the same private key. Is this intended?

Yes! Also, my terminology wrt private/public key is flawed. The private
key should be secret key, and public key should be the random IV sent
along with the ciphertext. I used the word pubic because it gets sent
out for an attacker to see.


> I would have expected that there
> is a "Generate key" button, and a button "encrypt" and another one
> "decrypt" so that I can encrypt different texts with the same key over
> and over again.

You can generate different ciphertexts with the same key. Just keep
hitting the encrypt button, and see how the ciphertext changes. If you
change a single byte in the plaintext, all of the ciphertext bytes
change. This is a fairly decent avalanche effect. However, if you change
a single byte in the ciphertext, a single change will occur in the
decrypted plaintext. This is normal.

Chris M. Thomasson

unread,
Jul 2, 2016, 5:21:21 PM7/2/16
to
On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
[...]
> How this known plaintext attack works is, suppose the first bit of the
> message is 1, then an attacker can tell something about the key c -
> certain values of c in the 1st iteration will give a +ve real part,
> certain values won't.

Okay, you much be referring to the fact that the first bit of the
message can be determined by looking at the sign of the real part. this
has to be hidden!

austin...@hotmail.com

unread,
Jul 2, 2016, 5:32:29 PM7/2/16
to
Hi Chris,

Dare I say it and not sound patronising but your algorithm is in very rocky waters right from day one.

I was very surprised to find that you were ignoring the basic crypto maxim that says "keep away from float data" when you went down the road of complex numbers initially but I assumed that you had something up your sleeve.

The maxim given to me along time ago is stick with integers for safety!

*You were given some very bad advice on 'rounding' but it should not have gone that far in the first place.

It's a breath of fresh air to see somebody broadening the scope of crypto research as you did by going into maths for an encryption model and thus getting away from the paralysis of probabilism at last.

I hope you will keep on trying.

Austin O'Byrne

Chris M. Thomasson

unread,
Jul 2, 2016, 5:37:31 PM7/2/16
to
On 7/1/2016 2:23 PM, Chris M. Thomasson wrote:
> On 2/21/2016 1:38 PM, Chris M. Thomasson wrote:
> [...]
>
> I am thinking on how to crack this thing. So far, using the following
> arbitrary precision library:
[...]

There is a flaw, Peter Fairbrother noticed it... The problem is the sign
of the real part is the first bit of a real byte in the damn plaintext!
This is crap: Total garbage. However, how can we hide a single complex
number, with around 90 points of precision? Can we just multiply it by a
complex with irrationals 90 points deep for real and imaginary parts,
try to get it back, and add more bits until we can? Can we just expand
the secret key space from a single (c), to multiple (c) and an offset to
hide this point? I think we can also add an randomized IV to the
ciphertext, along with encrypting random bytes. Also, we can use forward
iteration (c) using each byte of the plaintext as a pixel, to hide the
final point of reverse iteration. I am thinking of a hybrid of all the
above.

If we have a single point, it should be easy to hide? However, a block
cipher would give up much more information about the hiding process. I
think a single point is "more secure" if we cleverly hide its digits.

A clever combination of my existing forward iteration with Juaquin's
reverse iteration will produce a single point with many digits and a
random IV as the ciphertext that will not give any clear insight of the
first bit of the plaintext.

Chris M. Thomasson

unread,
Jul 2, 2016, 6:01:05 PM7/2/16
to
On 7/2/2016 2:37 PM, Chris M. Thomasson wrote:
> On 7/1/2016 2:23 PM, Chris M. Thomasson wrote:
>> On 2/21/2016 1:38 PM, Chris M. Thomasson wrote:
>> [...]
>>
>> I am thinking on how to crack this thing. So far, using the following
>> arbitrary precision library:
> [...]
>
> There is a flaw, Peter Fairbrother noticed it... The problem is the sign
> of the real part is the first bit of a real byte in the damn plaintext!
> This is crap: Total garbage.

I mean, the sign of the real part of the single arbitrary precision
complex number in the _ciphertext_ will be a byte in the plaintext. So,
we need to hide this single point. Block cypher makes it more difficult.

Any clever ideas? Suggestions?

Thank you all.

Chris M. Thomasson

unread,
Jul 2, 2016, 6:07:57 PM7/2/16
to
On 7/2/2016 2:32 PM, austin...@hotmail.com wrote:
> On Saturday, July 2, 2016 at 10:21:21 PM UTC+1, Chris M. Thomasson wrote:
>> On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
>> [...]
>>> How this known plaintext attack works is, suppose the first bit of the
>>> message is 1, then an attacker can tell something about the key c -
>>> certain values of c in the 1st iteration will give a +ve real part,
>>> certain values won't.
>>
>> Okay, you much be referring to the fact that the first bit of the
>> message can be determined by looking at the sign of the real part. this
>> has to be hidden!
>
> Hi Chris,
>
> Dare I say it and not sound patronising but your algorithm is in very rocky waters right from day one.

Hell fuc%ing yeah it is! Big time.


>
> I was very surprised to find that you were ignoring the basic crypto maxim that says "keep away from float data" when you went down the road of complex numbers initially but I assumed that you had something up your sleeve.
>
> The maxim given to me along time ago is stick with integers for safety!
>
> *You were given some very bad advice on 'rounding' but it should not have gone that far in the first place.

Well, imy heart of hearts I have a feeling that this fractal encryption
scheme can be made to work really nice, I am thinking of a hybrid
between by existing forward iteration, and Juaquin Anderson's reverse
iteration techniques, to say the least, it will definitely be fun for
me. I am very happy that other smart people are tearing the shi% out of
it! That's exactly what I want, damn it! :^)


>
> It's a breath of fresh air to see somebody broadening the scope of crypto research as you did by going into maths for an encryption model and thus getting away from the paralysis of probabilism at last.
>
> I hope you will keep on trying.

I Absolutely Will: Thanks Austin!

:^)

Chris M. Thomasson

unread,
Jul 2, 2016, 6:36:11 PM7/2/16
to
On 7/2/2016 2:18 PM, Chris M. Thomasson wrote:
> On 7/2/2016 1:41 PM, Christian Gollwitzer wrote:
[...]
>> I would have expected that there
>> is a "Generate key" button,

That's an interesting question in and of it self. How can we generate
these secret keys? I think we can use existing fractal explorer
programs, or something simple like the one I made here, just click on a
point-of-interest to zoom in:

http://webpages.charter.net/appcore/fractal/webglx/ct_complex_field.html
(a crude webgl experiment I made)


Its very crude, but all clickable points are valid (c)'s, this is only
in 32 bit precision, however I can do this with arbitrary precision for
very complex and sensitive values of (c). Zooming in just means that the
clickable surface area of (c) will have more digits of precision to
target the zoom just right. So, one can click in many times, and get to
a place, then click on a "capture secret key" button or something. Bang!
They have one.

Hummm... I need to think a lot more on this. Any thoughts on using
fractal explorers to generate secret keys?

Thanks again.

Rich

unread,
Jul 2, 2016, 8:11:10 PM7/2/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
> On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
>> ah, I'm pretty sure it not secure; it falls to a simple known plaintext
>> attack.
>>
>>
>> For the non-cryppies here, a known plaintext attack is where an
>> attacker knows both the plaintext and ciphertext of a message block,
>> and uses that plaintext/ciphertext pair to find out something else,
>> usually the key.
>>
>> This might at first glance sound unlikely or unwieldy, but it was
>> the type of attack used to break enigma, and a modern cipher would
>> be expected to withstand something much more severe, eg an adaptive
>> chosen-ciphertext attack, where the attacker can get decrypts of
>> ciphertexts he chooses, then use those decrypt results to choose
>> further ciphertexts, get decrypts of those, and so on.
>>
>> Defense against known plaintext attacks is a very minimum
>> requirement for a cipher.
>>
>> How this known plaintext attack works is, suppose the first bit of
>> the message is 1, then an attacker can tell something about the key
>> c - certain values of c in the 1st iteration will give a +ve real
>> part, certain values won't.
>
> Right, but that's normal for any fractal iteration. The signs of the
> real parts will flutter back and forth. How do you identify a bit
> pattern to a plaintext?

You missed Peter's point. He's using a known plaintext attack.
https://en.wikipedia.org/wiki/Known-plaintext_attack

This type of attack is a minimum requirement for a cryptosystem because
in real world usage, there is often some known values in the plaintext
that allow an attacker leverage to deduce hints about the key and
therefore reduce the keysearch space. In real world situations these
known elements take the form of headers to data in the plaintext
stream. I.e., if a cryptographer could deduce that the plaintext for a
block of cipertext was a word docx file, then there are some constant
values at known positions in the beginning bytes of a word docx file
that help in performing this type of attack.

For the cipher to be at all secure, then knowledge of both the full
plaintext input and the full ciphertext output should give the attacker
zero hints about the key value. Peter's assertion (which looks
accurate to me) is that your system leaks huge hints about the key from
this type of attack. Which is not a good thing.

Rich

unread,
Jul 2, 2016, 8:15:59 PM7/2/16
to
In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
> Yes! Also, my terminology wrt private/public key is flawed. The
> private key should be secret key, and public key should be the random
> IV sent along with the ciphertext. I used the word pubic because it
> gets sent out for an attacker to see.

Please do not do things such as this above. Where a term already has a
very widely well known meaning, you do nothing but cause confusion for
everyone else and end up getting a lot of "talking past each other"
because you say Y, folks think you are talking about Z, reply with an
answer around Z, but it does not fit a Y situation.

If the values don't fit the standard meanings of the standard terms,
then invent names that have no assigned meanings, at least that way the
only confusion others have with your descriptions is "what is meant by
Q". And once they know that Q means "blah blah" then they can follow
along.

Peter Fairbrother

unread,
Jul 2, 2016, 8:57:04 PM7/2/16
to
No, I'm talking about the result of the first forward iteration, I was
assuming the sign of the ciphertext would be unused.


And that is not the weakness.

Suppose an attacker knows a ciphertext z is 2,0. Suppose the attacker
also knows the first bit of the relevant plaintext is 0.

And you can't say an attacker can't know some plaintext/ciphertext
pairs, that is assumed in the known-plaintext attack model.

Iterating z' -> z^2 + c, we get z^2 = 4,0. The attacker knows the real
part of z' is negative; therefore the attacker now knows the real part
of c is less than -4.

That gives the attacker some information about c, the key.

And he can rinse and repeat with a new block, or with minimum math use
the second and later iterations of a single block, to get more and more
information about c - and it doesn't take all that long until he can
find c, the key, exactly.


-- Peter Fairbrother


Chris M. Thomasson

unread,
Jul 3, 2016, 3:06:35 AM7/3/16
to
On 7/2/2016 5:57 PM, Peter Fairbrother wrote:
> On 02/07/16 22:21, Chris M. Thomasson wrote:
>> On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
>> [...]
>>> How this known plaintext attack works is, suppose the first bit of the
>>> message is 1, then an attacker can tell something about the key c -
>>> certain values of c in the 1st iteration will give a +ve real part,
>>> certain values won't.
>>
>> Okay, you much be referring to the fact that the first bit of the
>> message can be determined by looking at the sign of the real part. this
>> has to be hidden!
>
> No, I'm talking about the result of the first forward iteration, I was
> assuming the sign of the ciphertext would be unused.
>
>
> And that is not the weakness.
>
> Suppose an attacker knows a ciphertext z is 2,0. Suppose the attacker
> also knows the first bit of the relevant plaintext is 0.
>
> And you can't say an attacker can't know some plaintext/ciphertext
> pairs, that is assumed in the known-plaintext attack model.
>
> Iterating z' -> z^2 + c, we get z^2 = 4,0.

How does the attacker get (c) to iterate the ciphertext in the first place?

Chris M. Thomasson

unread,
Jul 3, 2016, 3:09:05 AM7/3/16
to
On 7/3/2016 12:06 AM, Chris M. Thomasson wrote:
> On 7/2/2016 5:57 PM, Peter Fairbrother wrote:
>> On 02/07/16 22:21, Chris M. Thomasson wrote:
>>> On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
>>> [...]
>>>> How this known plaintext attack works is, suppose the first bit of the
>>>> message is 1, then an attacker can tell something about the key c -
>>>> certain values of c in the 1st iteration will give a +ve real part,
>>>> certain values won't.
>>>
>>> Okay, you much be referring to the fact that the first bit of the
>>> message can be determined by looking at the sign of the real part. this
>>> has to be hidden!
>>
>> No, I'm talking about the result of the first forward iteration,
You can get a bit on of off condition in the real part on the first
iteration. How to tell if its a valid bit?

Christian Gollwitzer

unread,
Jul 3, 2016, 3:19:46 AM7/3/16
to
Am 01.07.16 um 21:23 schrieb Chris M. Thomasson:
> Well, it works. I
> can store quite a bit of data in a single complex number. Here is a
> simple example ciphertext that stores the following string:
>
> plaintext - 32-bytes, 256-bits:
> _______________________________________________
> Having Fun With Fractals is Good
> _______________________________________________
>
>
>
> ciphertext, 81 point of precision required:
> _______________________________________________
> x:-1.40671908764936961512398419133109623095250597042532480395711455165016474134535925
>
>
> y:0.00944239408403734327190341674814485098947052840036562960580747161769090947636525034
>
> _______________________________________________


Storing 256 bits in 81 decimal places is not very impressive. A decimal
number carries log(10)/log(2)=3.32 bits of information. That makes 256
bits ~ 77.1 decimal places. You have two numbers with 81 decimal
figures, which amounts to 538 bits, more than twice as much as the input.

Christian


Chris M. Thomasson

unread,
Jul 3, 2016, 3:20:18 AM7/3/16
to
On 7/2/2016 5:11 PM, Rich wrote:
> Chris M. Thomasson <inv...@invalid.invalid> wrote:
>> On 7/2/2016 1:26 PM, Peter Fairbrother wrote:
[...]
> For the cipher to be at all secure, then knowledge of both the full
> plaintext input and the full ciphertext output should give the attacker
> zero hints about the key value. Peter's assertion (which looks
> accurate to me) is that your system leaks huge hints about the key from
> this type of attack. Which is not a good thing.

I would love some help with an example attack. We need to define a
plaintext, then pretend we are Eve and blast this sucker in the form of
grabbing something that works. It could be really close to the secret
key (c), or be based on some other process. Can we try to crack this
with known plaintext attack here? For fun, perhaps? Once we work
together, we create an attack than get get say, 60% of plaintext from a
ciphertext, I will be happy!

:^)

Chris M. Thomasson

unread,
Jul 3, 2016, 3:21:26 AM7/3/16
to
On 7/3/2016 12:19 AM, Christian Gollwitzer wrote:
> Am 01.07.16 um 21:23 schrieb Chris M. Thomasson:
[...]
> Storing 256 bits in 81 decimal places is not very impressive. A decimal
> number carries log(10)/log(2)=3.32 bits of information. That makes 256
> bits ~ 77.1 decimal places. You have two numbers with 81 decimal
> figures, which amounts to 538 bits, more than twice as much as the input.


Yes. This not compression! Wow, the size of the ciphertext is large, but
I still think there is some promise.

Chris M. Thomasson

unread,
Jul 3, 2016, 3:23:23 AM7/3/16
to
On 7/3/2016 12:21 AM, Chris M. Thomasson wrote:
> On 7/3/2016 12:19 AM, Christian Gollwitzer wrote:
>> Am 01.07.16 um 21:23 schrieb Chris M. Thomasson:
> [...]
>> Storing 256 bits in 81 decimal places is not very impressive. A decimal
>> number carries log(10)/log(2)=3.32 bits of information. That makes 256
>> bits ~ 77.1 decimal places. You have two numbers with 81 decimal
>> figures, which amounts to 538 bits, more than twice as much as the input.
>
>
> Yes. This not compression!

Its anti compression, because we are using 2d points to store 1d data.
Arithmetic coding is much more efficient, because it has no imaginary part.

Chris M. Thomasson

unread,
Jul 3, 2016, 3:36:19 AM7/3/16
to
On 2/21/2016 1:38 PM, Chris M. Thomasson wrote:
> Original idea by Juaquin Anderson in the comments of the
> following thread:
[...]

Here is pretty neat projection to the integer plane that really
increases storage efficiency:

Reverse Fractal Encryption 1d Integer Plane:

https://xp-dev.com/svn/FractalCodes/trunk

Chris M. Thomasson

unread,
Jul 3, 2016, 3:50:37 AM7/3/16
to
We assume Alice and Bob have been using the same (c) forever, and Eve
has quite a bit of ciphertext, and her spies have some plaintext. Even
though I am sending a single point per message, well, the more I send
the easier Eve's job is. I propose encrypting random bytes, vastly
expand the key space by using multiple values of (c), axes, and scales
during iteration. Heck, my exiting funny fractal encryption has a much
larger secret key space. But, that does not mean reverse fractal
encryption does not have to. This is basically i embryonic stages here.
I do not want to abort quite yet! ;^o

Chris M. Thomasson

unread,
Jul 3, 2016, 4:09:33 AM7/3/16
to
On 2/21/2016 1:38 PM, Chris M. Thomasson wrote:
> Original idea by Juaquin Anderson in the comments of the
> following thread:
[...]
> What do you think about the code? Is it crap?
>
> ;^)
>
>
> Thank you all.


Well, it does seem to be vulnerable to known plaintext attack, Eve is
smart with many spies. I think a single point is hard, well if I sent a
shi% load of them, then Eve's tap will just plot them and get visually
close to the secret key, comprised of a single complex number and an
origin point that is random for each ciphertext. Still, Eve should not
get naked points from reverse iteration. The should be hidden.
Encrypting random bytes, and using entropy from forward iteration will
help. Also, radically increasing the key space with several (c)'s and
random IV's and direct hiding of the points. Also, we have not even got
into zooming, and the effects it casts. Yes we have a single (c) in the
secret key, but, we can add a zoom level.... This increases key space
right off the bat.

Any other ideas? I do not think this is totally doomed.

Rich

unread,
Jul 3, 2016, 10:12:09 AM7/3/16
to
A known plaintext attack is primarially an attack that recovers the key
used to encrypt. Once you have the key, then you get to decrypt
anything that was encrypted using that key. If the cipher is then used
in a mode where a lot of data ends up encrypted with the same key, once
an attacker has that key, they can decrypt *all* of the data encrypted
with that key.

Because the attack is called "known plaintext" in the normal scientific
use, the attacker knows 100% of the plaintext and 100% of the
ciphertext and can recover the key used knowing these two values.

What makes this attack so devastating is that most encrypted data often
contains chunks of static text (protocol or data file header fields)
that provide "known plaintext" for a real attacker to leverage.

As for performing the test, I think Peter gave you enough information
to do the test yourself. Pick something, encrypt it, then begin
performing Peter's suggested method. If after the first iteration the
sign tells you whether the first bit of the key was 0 or 1, you've got
the start of a problem. If after a second iteration, the sign now
tells you whether the second bit of the key was 0 or 1, then you've
really got a problem brewing.

Rich

unread,
Jul 3, 2016, 10:18:58 AM7/3/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
You'd need some seriously impressive attack resistances in order for
_anyone_ to take seriously a system with an over doubling growth of the
cipertext vs. the plaintext seriously as a contender for an alternative
to AEA or Twofish or Serpent (where growth of the ciphertext is usually
at most the size of an IV [1] plus from 0 to n-1 [2] of padding. So
worst case growth about 2n-1 bytes [2].

And right now, it appears that there's a huge known plaintext break
that Peter has offered, so it would fail for serious usage for that
reason alone as currently designed.



[1] size of the number of bytes in a block for the cipher

[2] n = cipher block size in bytes

Rich

unread,
Jul 3, 2016, 10:22:57 AM7/3/16
to
Chris M. Thomasson <inv...@invalid.invalid> wrote:
But an over doubling of the ciphertext size vs. the input plaintext
size is going to make most people ask: "Does it have more than double
the strength of AES to all of: [list of cipher attacks]"

If it is weaker at any of the "list", no one is going to accept a
doubling in size for a weaker cipher.

As an educational endeavor it is fine, but that doubling in size factor
means that it really needs to excell in other areas to be more than
"educational".

Peter Fairbrother

unread,
Jul 3, 2016, 11:04:05 AM7/3/16
to
He doesn't.

Writing the forward iteration as z' = z^2 + c

The attacker knows z, from which he calculates z^2. He also knows the
sign of the real part of z'.

Initially, he does not know anything about c.

But from those two pieces of information which he does know, he can find
a limit on c.

Considering only real parts [I will write as Re(x) is the real part of
the complex number x] in my example we know that R(z') the real part of
z', is negative, ie

Re(z') < 0. Now we know

Re(z') = Re(z)^2 + R(c), therefore

Re(z)^2 + Re(c) < 0

Re(c) < 0 - Re(z)^2

Re(c) < 0 - 4

Re(c) < -4.

Thus the attacker learns a little about c.

He repeats this, each time learning a little more about c, until he
knows enough about c to reconstruct it exactly.


Actually it is more complex than that, as an attacker can use the second
and later iterations and their signs to put limits on both the real and
imaginary parts of c - but I won't go into that math here.

(mainly because I can't be bothered to work it out in detail, it is left
as an exercise for the interested.

It might be worth working through it, as it might be a little harder
than I envisage to collect enough information to reconstruct c exactly.

However from a cryptologist's point of view, as a cipher, the above is
more than enough to say that, as a secure cipher, it is broken.)


-- Peter Fairbrother

Rich

unread,
Jul 3, 2016, 11:49:47 AM7/3/16
to
Peter Fairbrother <pe...@tsto.co.uk> wrote:
> Actually it is more complex than that, as an attacker can use the
> second and later iterations and their signs to put limits on both the
> real and imaginary parts of c - but I won't go into that math here.
>
> ...
>
> It might be worth working through it, as it might be a little harder
> than I envisage to collect enough information to reconstruct c
> exactly.
>
> However from a cryptologist's point of view, as a cipher, the above
> is more than enough to say that, as a secure cipher, it is broken.)

Yes. Chris, for your benefit, real cryptographers consider *any* break
that produces a method of finding the key or decrypting a message in
any amount faster than exhaustive brute force search to be a break.

Peter's method looks like it gives a cryptographer a huge limit on
possible values for the key, so it looks like it would work with *much*
less effort than exhaustive brute force, and therefore it is a serious
flaw to your current scheme.

MM

unread,
Jul 3, 2016, 12:44:07 PM7/3/16
to
On Sunday, 3 July 2016 16:49:47 UTC+1, Rich wrote:
> Yes. Chris, for your benefit, real cryptographers consider *any* break
> that produces a method of finding the key or decrypting a message in
> any amount faster than exhaustive brute force search to be a break.

Thats more of an "attack" than a "break". An attack that reduces a 256-bit
search to a 244-bit search may be a significant piece of cryptanalysis, and
an interesting attack, but will not mean that the cipher concerned could be
broken any time soon, as 2^244 is still a bloody big space to search.

> Peter's method looks like it gives a cryptographer a huge limit on
> possible values for the key, so it looks like it would work with *much*
> less effort than exhaustive brute force, and therefore it is a serious
> flaw to your current scheme.

Quite so, but I haven't seen it in actual numbers yet :-)

Chris' method is still interesting, as it is a new idea, AFAICT.

M
--

Chris M. Thomasson

unread,
Jul 3, 2016, 3:07:27 PM7/3/16
to
On 7/3/2016 7:18 AM, Rich wrote:
> Chris M. Thomasson <inv...@invalid.invalid> wrote:
[...]
> And right now, it appears that there's a huge known plaintext break
> that Peter has offered, so it would fail for serious usage for that
> reason alone as currently designed.

I am going to try really hard to show exactly how a known plaintext
attack can potentially wreak some rather serious havoc. This is
basically what I was looking for to begin with: A way to crack it! This
is most interesting to me. Learning how to crack it, will give be some
insight on how to potentially "fix" it. I will make two web pages... One
that encrypts/decrypts, and another one that takes a series of
ciphertext, and some known plaintext and attempts to attack and break
(c) such that the attacker can get around 20-60% of the plaintext. That
would be neat to try.

Chris M. Thomasson

unread,
Jul 3, 2016, 3:19:57 PM7/3/16
to
Yeah. Sorry about. I will change the text on the webpage to:

Secret Key, and Random IV; instead of the misleading public/private crap.

Chris M. Thomasson

unread,
Jul 3, 2016, 3:26:33 PM7/3/16
to
On 7/2/2016 5:15 PM, Rich wrote:
> In sci.crypt Chris M. Thomasson <inv...@invalid.invalid> wrote:
>> Yes! Also, my terminology wrt private/public key is flawed. The
>> private key should be secret key, and public key should be the random
>> IV sent along with the ciphertext. I used the word pubic because it
>> gets sent out for an attacker to see.
>
> Please do not do things such as this above. Where a term already has a
> very widely well known meaning, you do nothing but cause confusion for
> everyone else and end up getting a lot of "talking past each other"
> because you say Y, folks think you are talking about Z, reply with an
> answer around Z, but it does not fit a Y situation.

[...]

Its done, goto the page:

http://funwithfractals.atspace.cc/ffe

And refresh/reload the content. (Private Key) turns into (Secret Key),
(Public Key) turns into (Random IV).


Chris M. Thomasson

unread,
Jul 3, 2016, 3:34:29 PM7/3/16
to
I think stating small is good... We crack 40% of the bits out of a byte...


Chris M. Thomasson

unread,
Jul 3, 2016, 3:46:46 PM7/3/16
to
Thank you.

FWIW, I personally think it has some promise: I am not ready to pull the
damn plug quite yet. I still need to create a bunch simulated attacks,
throw them at the cipher and see how many bits I can reap. Once I do
that, I think this thing can be improved. Any thoughts?

:^o

I would love all the help I can get wrt cracking this thing.

Thanks.
It is loading more messages.
0 new messages