Welcome Guest [Log In] [Register]
Welcome to Crypto. We hope you enjoy your visit.


You're currently viewing our forum as a guest. This means you are limited to certain areas of the board and there are some features you can't use. If you join our community, you'll be able to access member-only sections, and use many member-only features such as customizing your profile, sending personal messages, and voting in polls. Registration is simple, fast, and completely free.


Join our community!


If you're already a member please log in to your account to access all of our features:

Username:   Password:
Add Reply
Baldr, A Stream Cipher; loki simple stream cipher challenge
Topic Started: Aug 9 2006, 01:31 PM (1,093 Views)
rot13
Elite member
[ *  *  *  *  * ]
Quote:
 
This is the proof that when you think your cipher is 'unbreakable' think again!


This is why I keep bringing up the idea of trying to crack them yourself. It is one thing to read what someone else has done, and another to actually identify weaknesses yourself. I would strongly urge you to try cracking the first 2 baldr ciphers. If you read up on various techniques used to crack Vigenere, I think you'll figure it out. I'm sure a lot of us would be glad to offer suggestions, but I think it is important to figure it out, not just have someone else tell you how it is done.

Quote:
 
I would still like to see if you can do part 2 of your challenge and discover the key and method of encryption


Anybody got an ideas on this? I can compute what I will call the "XOR key" for each key position, which is the value to XOR with the ciphertext to recover the plaintext, but I assume that this XOR key is computed by some transformation on an ASCII character.

Here are the XOR key values in both binary and hex:
Code:
 

10010000  b0
10011110  be
10100111  87
11010000  f0
10001010  aa
11010110  f6
10010010  b2
10101110  8e
10001010  aa
10010011  b3
10101000  88
10001010  aa
10011111  bf
10000100  a4
11010010  f2
10001111  af
10010011  b3
11011110  fe
10110100  94
10010000  b0
10100100  84
10000000  a0
10001100  ac
11010101  f5
10010011  b3
10011111  bf
11010100  f4
11011110  fe
10010111  b7
01000110  66
10110111  97
10010110  b6
10101110  8e
10001010  aa
10000011  a3
10010110  b6
11010010  f2
11010111  f7
10010001  b1
10001001  a9
10100011  83
10010110  b6
10111100  9c
10000011  a3
10011111  bf
10110100  94
10110011  93
11010100  f4
10001110  ae
01000000  60
10010011  b3
11010011  f3
10001001  a9
10000011  a3
10001100  ac
10001111  af
11010000  f0
10101000  88
10101010  8a
10000011  a3
10000101  a5
11011111  ff
10000111  a7
10101110  8e

62 15 14 34 25 34 42 27


The numbers at the bottom indicate the number of 1's at each bit position. I am sure that it is significant that all but two of them start with 1, and that in the next two, 1 occurs less than 25% of the time.

If you were to just invert the bits, you'd get all ASCII characters except for the two that don't start with 1. I thought it might be some combination like x ^ (x << 1) but I haven't found anything that works well.

Any suggestions?
Offline Profile Quote Post Goto Top
 
loki
Advanced Member
[ *  *  * ]
Wow, I have learned a lot. Have a look at it, it is what it is. Now that I have a solid understanding of writting fancyness and Making it look neat, I am going to learn about the mathmatics invloved.

Nope, Dont really have the slightest idea of whats going on there beyond layman terms.

Let me know what you think.
c(x) = 3x3 + x2 + x + 2; Find the inverse
Offline Profile Quote Post Goto Top
 
insecure
Elite member
[ *  *  *  *  * ]
This reply is, I'm afraid, nothing to do with cryptography, but I hope it is nevertheless educational.

I downloaded baldr.c, created a makefile for it, and submitted it to gcc - without at this stage having looked at the code. gcc gave me a 195-line report which I won't show here, as I'm sure you're relieved to hear!

First problem - carriage returns in the source. Well, that's life in my Linux world - hardly the OP's fault - so I fixed that and recompiled. This gave me the following list of errors:

baldr.c:37: syntax error before `void'
baldr.c: In function `hash':
baldr.c:126: warning: value computed is not used
baldr.c: In function `strlen':
baldr.c:136: warning: value computed is not used
baldr.c:132: warning: `i' might be used uninitialized in this function
baldr.c: In function `make_keys':
baldr.c:197: warning: value computed is not used
baldr.c: In function `encrypt':
baldr.c:206: warning: unused variable `round'
baldr.c:204: warning: unused variable `j'
baldr.c: In function `decrypt':
baldr.c:357: warning: unused variable `round'
baldr.c: In function `main':
baldr.c:544: warning: unused parameter `argc'
baldr.c:549: warning: `mode' might be used uninitialized in this function
baldr.c: At top level:
baldr.c:640: syntax error before `void'
make: *** [baldr.o] Error 1


First problem is caused by "inline", which is legal in C99 but almost nobody has a C99 compiler (including me). So I removed all (okay, both!) references to inline. That helped enormously, but now I got these diagnostics:

baldr.c: In function `hash':
baldr.c:126: warning: value computed is not used
baldr.c: In function `strlen':
baldr.c:136: warning: value computed is not used
baldr.c:132: warning: `i' might be used uninitialized in this function
baldr.c: In function `make_keys':
baldr.c:197: warning: value computed is not used
baldr.c: In function `encrypt':
baldr.c:206: warning: unused variable `round'
baldr.c:204: warning: unused variable `j'
baldr.c: In function `decrypt':
baldr.c:357: warning: unused variable `round'
baldr.c: In function `main':
baldr.c:544: warning: unused parameter `argc'
baldr.c:549: warning: `mode' might be used uninitialized in this function

The first warning is for the following line of code:

*s++;

This is a fairly benign foul-up, which will not affect the program adversely, but it betrays a slight misunderstanding of C's syntax. Examining the code, it's clear to me that the intent is to increment the pointer value, s, and the code does in fact do this, but it also dereferences the pointer, yielding a value which is then ignored. The intent is adequately described thus:

s++;

The next issue, though, is rather more serious. The OP has defined a function named strlen, which not only repeats the above howler, but also - by its very name - breaks C's rules. Any external identifier that begins with the letters "str" and continues with a lower case letter is reserved for the implementation. strlen, in particular, is very reserved indeed!

The fix, though, is simple: (a) remove the function definition completely, and (b) #include <string.h> to get the standard strlen function. This also solves the problem of the uninitialised object in that function.

The next two problems are both identical to that *s++ issue I mentioned above. Easily fixed - just remove the * in each case.

I mentioned earlier that 'inline' is legal in C99 but not in C90, and you might argue that the OP has a C99 compiler. But if he does, then 'round' is in the implementation namespace! (A round() function was added to the Standard Library in C99.) Fortunately, this object is not used, and so its definition can be removed. In the same function, j can also be removed.

The same applies to the other use of 'round', in the decrypt() function.

We're now down to just two complaints - argc is unused, and mode might be used uninitialised (in main).

We do actually need to use argc. As the code stands at present, if argc is 4 or less, the behaviour of the program is undefined. So I added a check that argc >= 5 - if it isn't, I print an error message and halt the program.

The compiler is quite right to suggest that 'mode' might be used uninitialised. The fix is to initialise it! And to add a default to the switch statement. I chose -1 as mode's start value:

word mode = -1, i;

and added a default case to the switch that is keyed on mode:

default:
fprintf(stderr, "Invalid mode %d\n", (int)mode);
break;

The cast is not strictly necessary, but it is wise in this case because the OP has (unwisely, in my view) hidden good old int behind a typedef, and that suggests that he might choose to change it one day (otherwise, why typedef it in the first place?). If he changed it to, say, short int, the fprintf would break if the cast were not present.

With those changes, I got a clean compile.

I'm now getting very tired because it's very late, so I'll cut this shorter than I intended, but one glaring problem with the code stands out - it's those fflush calls.

Two problems here: the first is that closing a file, or ending the program "normally" - i.e. not via an abort() - automatically flushes anything that needs flushing, so you don't need to flush a file "manually" before closing it.

Secondly, the behaviour of fflush is not defined for streams open for input. Passing, say, stdin to fflush invokes undefined behaviour. So does fflush(plain_text).

Fortunately, the fix is simple - remove all the program's fflush calls!

That'll have to do for now.


Offline Profile Quote Post Goto Top
 
loki
Advanced Member
[ *  *  * ]
Thats Mad!, I compile in a Windows enviroment with not even a warning, I use gcc as a compiler as well, Why is this I wonder ?

if you can't compile Here it is in a rar file.

wow, I really feel bad at this point, I really put a lot of effort checking to make the code was right. I guess that you can never at your own code too much until someone else reviews it.

I really Dont understand the *s++ and s++ ??

*s++ increaments the pointer, which is what i want to do.

I did write a strlen, didn't I!, I feel i little silly now.

Well either way, thanks, I will look at your suggestions and make fix them.
c(x) = 3x3 + x2 + x + 2; Find the inverse
Offline Profile Quote Post Goto Top
 
insecure
Elite member
[ *  *  *  *  * ]
Quote:
 
Thats Mad!, I compile in a Windows enviroment with not even a warning, I use gcc as a compiler as well, Why is this I wonder ?


Try this:
gcc -W -Wall -ansi -pedantic -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef -Wnested-externs -Wcast-qual -Wshadow -Wconversion -Wwrite-strings -ffloat-store -O2 -o baldr baldr.c

It is always wise to crank up the warning level as high as you can reasonably manage it.

Quote:
 
wow, I really feel bad at this point,

I'm sorry. I didn't mean to make you feel bad! I hoped, rather, to help you learn a bit more about C.

Quote:
 
I really put a lot of effort checking to make the code was right. I guess that you can never at your own code too much until someone else reviews it.

Well, that's right - a second pair of eyes, especially as wizened and jaundiced as mine - can often spot the trees that you didn't see because you were too busy with the wood. Please don't take it too badly, because really your code isn't all that bad. I've seen far, far, far, far, far worse, I assure you.

Quote:
 
I really Dont understand the *s++ and s++ ??

*s++ increaments the pointer, which is what i want to do.


s++ increments the pointer. It's an expression, and expressions have values. The value of this expression is the value of s. Expressions can have side effects. The side effect of this expression is to add 1 to the pointer value, storing that result in s. But the value yielded by the expression is the old value of s.

* is the dereferencing operator. Since ++ has higher precedence, the value * operates on is the value yielded by the expression s++, which is the value s had before the increment. It's as if you'd written *(s++) instead. (You may have spotted that I'm being very formal and careful with my wording, because C does not specify the order of evaluation, only the precedence.)

Now, as you know, *p means "get me the value of the object that p points to". You can legally write:

*p;

but there wouldn't be much point, right? You don't use the value.

Similarly, in the statement:

*s++;

you don't use the value, and you're certainly not using * for any side effects, so you might as well omit it, leaving:

s++;

Sometimes, you do want the value of the object pointed to. For example, you can write a string to stdout like this:

const char *s = mystring;
while(*s != '\0')
{
putchar(*s++);
}
fflush(stdout);

This writes the character pointed to by s to stdout, and, as a side effect, increments s. If we didn't need to know which character we were pointing at, i.e. if we were only bothered about moving the pointer, we could just say s++.

I hope that makes it a bit clearer for you.

Offline Profile Quote Post Goto Top
 
Donald
Elite member
[ *  *  *  *  * ]
"loki"
 
wow, I really feel bad at this point

I'm a software engineer by trade, and having someone else point out problems in your code is NOT an insult. When I move something to production, if it breaks, the company loses money. So we ALWAYS try to get a second pair of eyes to go over everything we do because the other person will see mistakes that your eyes missed. A senior programmer will ask a junior programmer to go over their code sometimes, and the junior programmer will catch mistakes. Of course, another senior programmer would have caught more, but even the junior programmer will notice things the original programmer missed.

It's simply the nature of programming that once you are familiar with code, you miss things. Someone who is NOT familiar with what you did looks at the code with fresh eyes. They don't already think its doing certain things, so they see the mistakes more easily.

So take it as a complement when someone takes time to go over your code. It means they thought you were worth bothering with!
Offline Profile Quote Post Goto Top
 
loki
Advanced Member
[ *  *  * ]
By trade I am millitary.

Thanks everyone for the help in coding style, I am going to do the changes suggested and carry forward in becoming a better programmer, If you have complied and run the app by now you are aware that its dog slow on large files. I am reading about different mixings and why some are better then others and how they are defeated, I am looking at serpent right now for inspiration and Terry Ritters stuff.

I have discovered that if one is too learn modern cryptology, one should really really study DES and understand that first. It has really helped to give me a good grasp at what all the crypto white papers mean. I Find Twofishe's the best read.

Anyway, Baldr is not meant to be anything secure, There are professionals to that job. Its a mere project of mine to enchance my crypto knowledge. I work with the stuff all day and I really want to know whats inside the box. I Find this is the best method that works for me. Laniki's course is also helping me develop Baldr as well.

Most of all, the contructive critique from all of the forum, no I didn't take as an insult, just disappointent in my own performance.
c(x) = 3x3 + x2 + x + 2; Find the inverse
Offline Profile Quote Post Goto Top
 
1 user reading this topic (1 Guest and 0 Anonymous)
« Previous Topic · Challenges · Next Topic »
Add Reply