> Firstly, both executables "work", i.e., if you encrypt and
> then decrypt, you get back the exact same original file.
> But if you encrypt using the 32-bit executable, scp the
> encrypted file to the 64-bit machine (md5's match) and then
> decrypt, the result is exactly the same length and almost
> identical except for about one byte in a thousand that doesn't
> diff. Vice versa (encrypt on 64-bit, decrypt on 32) gives
> the same behavior. (By the way, the 32-vs-64-bit encrypted files
> are also ~one-in-a-thousand different, so both stages exhibit
> this small problem.)
> And I tried cc -m32 on the 64-bit machine, but there's
> some stubs32.h that it's missing. So instead, I cc -static
> on my own box, and that executable does work on the 64-bit
> machine when run against files encrypted on either 32-bit box.
> So the problem doesn't seem to be the 64-bit os, but rather
> the cc executable, though I'm not 100% sure.
Does your encryption algorithm use the same block size for both
32-bit and 64-bit encryption? For example, you have a loop that
takes a chunk of the data, encrypts it, and then loops, but on the
32-bit machine, it does 4 (8-bit) bytes in a chunk, and it does 8
(8-bit) bytes in a chunk on the 64-bit machine.
In that situation, doing 4 bytes at a time vs. 8 bytes at a time
may *NOT* be equivalent if it's possible to get a carry between the
lower 32-bit half and the upper 32-bit half. On the 32-bit machine,
that carry would be dropped. On the 64-bit machine, it would get
passed through. For some algorithms (such as those that involve
reversing bit order end-to-end), it should be blatantly obvious
that they are not equivalent. For others, the two may be equivalent
except under an unusual condition.
Ok, I'm reaching a lot here since I haven't seen the code.
What happens if the length of the data to be encrypted is an odd
multiple of 4? Or does a padding algorithm prevent that from ever
happening?
What is your plaintext now? It wouldn't happen to be UTF-8 that's
mostly ASCII but maybe one in a thousand characters has the high
bit set for an accented letter or Microsoft "smart quote"? What
happens if your plaintext is Chinese encoded in UTF-8? (That is,
*ALL* of the characters have the 0x80 bit set).
Some general trouble spots to look for:
Dereferencing a pointer to a 32-bit or 64-bit buffer to load or
store a bunch of characters, *EVEN IF* you make sure that the buffer
is aligned on a 32- or 64-bit boundary.
Endianness differences between the machines (probably not an issue
here).
The use of signed variables to hold encrypted data may cause problems
(e.g. x >> n replicating the sign bit rather than shifting in zero,
unexpected overflow traps, etc.) Also, if you store individual
bytes in a signed char, sign extension of bytes may cause problems.
I recommend using unsigned variables, whether bytes or integers,
to hold plaintext, ciphertext, key, random bytes, or combinations
of these. Things like loop counters and the remaining text length
are a different situation.
x << 32 or x >> 32 is defined if x is 64 bits wide, but not if x
is 32 bits wide.
64-bit calculations can store extra bits (on the high-order end)
for intermediate calculations. An operation like "multiply by 2,
then divide by 3" may have to be re-written "multiply by 2, AND
with 0xffffffff, then divide by 3" for 32-bit calculations run on
a 64-bit machine. (However, you only see a difference if the
0x80000000 bit was on.)
It may be a good idea to temporarily cripple your random number
generators to make them put out something blatantly predictble,
like 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, ... . Or
perhaps 55, 55, 55, 55, 55, ... . If the problem doesn't go away,
you should have an easier time debugging with more predictable data.
If the problem DOES go away, perhaps you now have a clue to make
a pattern that causes the problem all the time.
As someone else mentioned, use of floating point in a random number
generator may cause issues, especially carrying of extra precision
in unexpected places, combined with rounding modes.
Among other possible problems, the default initial rounding mode
for floating point may be determined by the OS (NOT the C library
or compiled code). (I do recall someone discovering that this could
vary between different OS platforms, I think including Windows vs.
Windows (maybe XP vs. Windows 7) using the bit-for-bit same executable
on both. This can cause baffling problems of the exact same
executable running differently on different systems.