April 23rd, 2013, 10:30 AM
How to evaluate my algorithm
This is what I've written, but I don't know how to evaluate it. It is old-hat or what?
1) 256 byte key using RNGCryptoServiceProvider class (.NET)
2) Variable read buffer sizes, depends on the key
3) Variable number of rounds (passes) (3-20): each read buffer is encrypted/decrypted rounds # of times
4) unique key for each round and read
5) key expansion to size of read buffer
5) stream ciphers on entire read buffer, portions of the read buffer and non-contiguous bytes extracted by a formula based on the key
shift bytes in sub-arrays around like ROL/ROR, but on sub-arrays
use of XOR on sub-arrays
treating sub-arrays as bit streams rather than byte streams
so ROR/ROL on these streams act as if they were used on bytes (not like Rijandael's rotation)
exchanging bytes dependant on adjacent keys
reversing bytes in buffers (and subbuffers)
6) block ciphers:
moving arbitrary (key-dependant) blocks of bytes around; similar to block size depends on the key (probably weaker here than AES)
7) combinations of 5 and 6 repeated on the entire read-buffer and subbuffers (contiguous and non-contiguous)
8) 28 encryption/decryption functions which combine (package) the basic functions
April 24th, 2013, 12:56 AM
To begin, I think it would be helpful if you will post some information about what motivated you to design a cipher algorithm -- what do you hope to achieve? For example, is this simply for your own education or entertainment, or do you hope to accomplish more than that?
Also, what properties do you claim for the cipher? Ciphers can be assessed in several different ways.
Do you think the cipher does something better than well-known ciphers that are widely used? What does it do better? How do its other properties compare with well-known ciphers?
April 24th, 2013, 09:42 AM
Thanks for your reply
I've been off and on interested in cryptography since the mid-1980s when I started coding in assembly language. Things intervened, work, etc., and I sort of forgot about it. But then around 2008 I started to play around in my spare time with writing an encryption program. Mainly for my own edification, education, curiosity, could I even do it. I purposely (and maybe foolishly) did not read up much on what's out there. I just thought I'd like to see what I could come up with on my own.
My program encrypts in, broadly, three different ways: 1) it scrambles in both block and stream fashion, bytes, both from the read array and also subarrays, selected either by start and end positions based on the key, or by selecting groups of non-contiguous bytes.
2) It also treats arrays as streams of bits, as if the array, say two bytes long, were really 16 bits, so when you do ror or rol, for example, you move the high or low order bit around to the front of the array.
3) it also treats arrays as streams of nibbles and acts on them, manipulating them and then writing them back to the original positions.
4) The number of rounds per read buffer depends on the key
5) The size of the read buffer depends on the key.
6) the key is expanded to the size of the read array by using the encryption functions combined with just copying it to the size of the read array.
7) there are no repeating sequences in the final output files or the extended keys.
This is, broadly, what my program does now.
There are eight "atomic" functions which are incorporated into other functions.
Am I explaining it correctly?
As for whether it is better than other commonly used ciphers, I can't say. Logically, I can't imagine how one of the output files could be decrypted back to plaintext by any means, but that could be just my limitation.
April 24th, 2013, 03:57 PM
If I understand your response correctly:
- this is something you're doing for personal satisfaction
- you don't whether it might be an improvement on what the world already has
Did I get that right?
If so, it's difficult to attract interest from knowledgeable people to analyze an algorithm.
Not trying to be ornery here -- when you write, "I can't imagine how one of the output files could be decrypted back to plaintext by any means" ... does your own software decrypt correctly? Have you thoroughly tested that? That property is called completeness, and of course a cipher is useless without it. Probably you meant, "without knowing the key."
As someone who hasn't studied block ciphers at all, it looks to me that the scheme is pretty computation intensive -- that is, probably takes a lot more time (and perhaps storage) than standard block ciphers in use today. This would lead to the question, "why use a more costly cipher, unless it provides some other benefit?"
To go a little deeper, have you studied the techniques by which block ciphers are cracked? Are you aware of some of the different modes of attack? Have you tried attacking your own cipher?
If you want to get into deep crypto, attacking (also called cryptanalysis) is a strongly recommended direction of study.
April 24th, 2013, 04:15 PM
First off, I am again very grateful you took some time to respond and please don't apologize for being "ornery," as if.
First off, my own software decrypts perfectly. I test it constantly, against a wide variety of files. And yes, sorry, I meant, without knowing the key. My scheme is computationally intensive and I'm working on reducing that. Some of the routines (on my dinky Dell 620) run at about 15000 bytes per second; others in the 400-500 range. I'm converting it to C++ so I can use in-line asm for speed. There is no on-disk storage issues at all. And yes, I do want to get deeper into block ciphers and decryption.
As for why I'm doing it, well, it started out just as something intellectually interesting, a break from work where I'd spend my time coding more boring applications. Later on, when I got to a certain stage, about 2 years ago, I realize I might have something useful.
A question, if you don't mind? Does it matter why I do it? I spent significant time on it (not that that guarantees anything, of course). As for your improvement comment, well, that's the core of the issue, right? I need to figure out if and how what I've done is an improvement over anything commonly in use. Not sure what the criteria for that is.
April 24th, 2013, 04:54 PM
I asked because the motivation is likely to shape responses.
For example, if the motivation were to offer higher security than the best block ciphers currently in use, you would certainly get responses to the effect that you are about as likely to get a $500 million lottery win, and other stuff that would go along with that.
If the motivation were to protect the confidentiality of really critical data, you would get responses to the effect that it's a huge mistake to use your own cipher.
If the motivation is to experiment and learn, then the considerations above wouldn't apply.
April 24th, 2013, 05:27 PM
Well, of course I'm motivated by the desire to experiment and learn. You've given me a lot to think about. THANKS VERY MUCH!!
April 25th, 2013, 12:31 PM
This is what my little program does
This is what I do:
(assuming for simplicity sake, just encrypting)
Get a key from RNGCryptoServiceProvider
Determine the read buffer size by adding up the values in the key (why make that difficult? Could use some other technique)
Get the file size and divide by the read buffer size (of course accounting for small files)
This gets the number of reads
Create an array of keys, once for each read. And using the encrypting functions, extend the key size to the size of the read buffer. Determine the number of rounds.
Instantiate the encryptor class, set the key to the key value for that read
Start encrypting by calling the encrypt( ) function
Before anything happens, an array of delegates is created, 256 in length. There are (so far) 28 encryption functions. These are assigned to respective positions in the delegate array.
Then the encryption process begins. Since read buffer is the same length as the key, as it iterates (in a for loop) over the read buffer, it calls the respective delegate function.
That function may, for instance, ROR, XOR, ROL on the elements of the read buffer, or some sub buffer, or it might rotate the array elements (or sub buffers) around, or operate on the bits of the array directly, or divide an array into sections and shuffle them around, other things like that, 28 functions so far in all. When the read buffer is exhausted, it is re-encrypted using another key; until iRounds number of passes is reached. Then it is written out and the read from file process continues until EOF.
Everything is then flushed and closed; the read buffer is zeroed out in memory and the program ends.
As I mentioned on my little machine, some functions run at about 15000 bytes per second, but others, in the 400-500 range.
I worked on the program a bit. It now runs at about 5000 bytes per second on my dinky machine. Variable number of reads; rounds; each round is a one-time pad. etc.
A question about your key
I have been reading your description with interest. I understand you use a 256-byte key. Could you please explain what you mean by "Get a key from RNGCryptoServiceProvider" and tell us a bit about how you do that? Thanks
byte randomArray = new byte[length];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
Thanks for the response.
It seems to me that your algorithm very thoroughly mixes up the original message and I don't see any attack that could succeed apart from brute force -- and with a 256-byte random key, that would take forever.
I am a bit surprised by the advice "never use your own cipher". While this is probably good advice if one wants to be 99.99999% secure against the best attacker in the world, in actual fact any one of us is unlikely to face such an attack on his/her personal stuff.
I believe you are correct, but that's just a belief of mine. I have no idea how one could rate algorithms above a certain quality. That is to say, I don't see how it is even logically possible to break my algorithm but that could just be a limitation of mine. The code has interested me purely from an intellectual point of view: could I do it, even satisfying my own standards? I'm thinking of fixing the code up (stripping it of my false starts etc) and posting it online. I'm also trying to convert it from C# to C++ (unmanaged) to expose it to a wider audience and maybe decent criticism.
You're right of course. 99.9% of the time no one is going to use supercomputers to decrypt someone's resume or other documents.
I might also, just to see if it would generate interest, put a "challenge" file on a web site and offer $1000 to the first person/organization that decrypts it. The file is 120,123 bytes long, nearly all the same byte value except for a poem in English somewhere in the file and several other byte values scattered about.
I don't think brute force would work either, in the sense that, sure after a while you'd certainly get the original file back but you wouldn't know it. You'd get all possible byte combinations as well and no way to determine which was correct.
Following Kerckhoff's principles, I think you have got to assume that the complete architecture of your enciphering process becomes known. And thus the only thing you can rely on for security is keeping secret the key that you use.
As previously commented, your 256-byte key should be unassailable by brute force (always assuming you have used a 'random' key, which you have.) But with such a long key you will have a problem of key management. How are you going to communicate your key to the recipient of the message, bearing in mind that you will need to change the key for each message?
The fact that the plaintext is a mass of meaningless bytes with the message hidden inside is not, I think, any protection against brute force attack because scoring each try with log tetragraph frequencies would reveal the true plaintext without problem.
Frequently analysis is meaningless in this case. The bytes values show little bias and what bias there is has to do with my functions, not the original text.
If a 256 byte key is unassailable (in human time), then a longer message is even more unassailable. Of course the complete code will be known, that has to be an assumption. The strength is in the code; as for the key, I just chose 256 because it seemed like a good number. I could equally use 25 or 100, doesn't matter (I think). I have no thought at all about key management. The first thing is have some idea of how good the code is; is it worth pursuing?
Just as you would never know you got the key by random attempts, you also wouldn't know if you got the plaintext by random attempts. Of course by trying all byte values you would get it, along with every other combination.
Actually, the message is not hidden inside meaningless bytes; the message is the meaningless bytes. But again, the fact that I think decryption is impossible may only be an indication of my limitation.