|
A little late to disguise myself and slink away at this point anyway. You people recognize me.
Real programmers use butterflies
|
|
|
|
|
|
I'm reverse-engineering some code, and I've found this as the "decryption" for some data:
unsigned char encrypted[...];
unsigned char decrypted[sizeof(encrypted)];
for (int i = 0; i < (int)sizeof(encrypted); i += 4)
{
DWORD temporary = ((((DWORD)encrypted[i + 0]) << 24) & 0xFF000000) |
((((DWORD)encrypted[i + 1]) << 16) & 0x00FF0000) |
((((DWORD)encrypted[i + 2]) << 8) & 0x0000FF00) |
((((DWORD)encrypted[i + 3]) << 0) & 0x000000FF);
temporary = temporary * 487709855;
decrypted[i + 0] = (BYTE)((temporary & 0xFF000000) >> 24);
decrypted[i + 1] = (BYTE)((temporary & 0x00FF0000) >> 16);
decrypted[i + 2] = (BYTE)((temporary & 0x0000FF00) >> 8);
decrypted[i + 3] = (BYTE)((temporary & 0x000000FF) >> 0);
} I remember seeing this sort of thing before, but I don't remember what it's called. Any suggestions?
Software Zen: delete this;
|
|
|
|
|
Obscurity?
Edit, how about:
Affine cipher - Wikipedia[^]
Further edit:
If it is Affine, is it Quadruple-Affine? Effectively using a different key for each of four bytes all at once?
modified 24-Nov-21 16:59pm.
|
|
|
|
|
I don't know its name, but I recognise the algorithm.
It's big-endian 32bit, with the encryption and decryption keys being multiplicative inverses mod 2^32.
On a big-endian machine, the loop becomes something like
for (int_32 i = 0; i < sizeof(array); i++)
{
array[i] *= magic;
} where (encrypt_magic * decrypt_magic) % (1<<32) == 1
As an encryption algorithm, it's nuisance value only. But I have used it a few times just to discourage tampering.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Thanks for the information. I recognized the form, but couldn't remember the rationale. The mental attic has become quite cluttered.Peter_in_2780 wrote: As an encryption algorithm, it's nuisance value only I recognized that. Even the Tiny Encryption Algorithm (TEA)[^], which I've used a number of times, is a lot more complicated.Peter_in_2780 wrote: I have used it a few times just to discourage tampering That is definitely the purpose here.
Software Zen: delete this;
|
|
|
|
|
Sometimes you get asked to implement an encryption in ten minutes without (or with very limited) internet access for stuff that can stay clear-text anyway.
These are the results.
GCS d--(d-) s-/++ a C++++ U+++ P- L+@ E-- W++ N+ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++* Weapons extension: ma- k++ F+2 X
|
|
|
|
|
Base-64. 
|
|
|
|
|
Keeps away a lot of amateurs. XOR your base64 to be safe from them hobbyist hackers.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
That's a very bad "algorithm". In fact the transform is not even bijective, because the "magic number" used for the multiplication is not a prime number (it is evidently a multiple of 5, even if it has no divisor by 2, which is a very weak but insufficient condition). This code creates some collisions.
Basically, this should just be a weak "hashing function" for use to compute fast hash keys in hash tables, to distribute the hash keys in a pseudo-random order, however it is limited to hashing short strings (hash tables require a small number of bits in the hash value, but here this hash has the same size as the input, which is assumed to be a multiple of 4 bytes, so typically an hash table would only distriobute the first few bytes of the input strings, ignoring completely the end).
It is extremely easy to decrypt by a very basic cryptanalysis (simply based on statistics, because each block of 4 bytes is encrypted separately, independantly of their position in the data stream).
If there's any app using this code, it should be marked as severely attackable (much more than MD5 which is already easily attackable, even when given some salt).
A much better affine transform would use the result of the previous block as an additive salt for the next block of 4 bytes, and the first block should be salted by an initial 32-bit constant. If this is used to compute a hash key, the hash should be the value you get from processing the last block, i.e. the last 4 bytes, and never the first 4 ones.
Beside this, the bitshifting done here is just here to allow processing unaligned block, in a very inefficient way: you don't need masking the "temporary" with 0xFF000000... if you just cast the temporary value to a byte, and the first part is extending a byte to a 32-bit DWORD before left-shifting, meaning that masking the low bits is unnecessary, and making the high bits would be also unnecessary of the left-shifting was not arithmetic but logical using unsigned byte: DWORD is the incorrect type to use because it is signed. May be the compiler will optimize this, but this code is just waste
But you should be aware that this code processes bytes past the end of the data, if the datasize (sizeof encrypted = sizeof decrypted) is not a multiple of 4 bytes: up to 3 trailing bytes have unpredictable contents and trying to access them could cause memory access violation: this is a clear case of BUFFER OVERFLOW.
|
|
|
|
|
The multiplier doesn't need to be a prime, it needs to be co-prime to 232. So it just needs to be odd, and it is. The inverse of 487709855 is 2188132191 (proof: 487709855 * 2188132191 = 1). It's a very weak encryption, but it's not incorrect.
|
|
|
|
|
|
IDK. I don't really want to call it an affine cipher, it kind of is, but that name is mostly used when the letters are independent, which here they are not (the upper byte of a block has four letters mixed together, the lowest byte in a block is the same as in a normal affine cipher though). Maybe it can be called an "affine block cipher", and there are some references to such a thing, but too few to really make sense. Also, the addition missing (or adding zero I suppose) is possibly important enough to warrant a different name, because it enables a fun "sum of ciphertexts decodes to the sum of corresponding plaintexts" attack, without needing any knowledge of the keys. It's not MMB, which is really close, but that uses a different modulus (for less asymmetric mixing).
|
|
|
|
|
yes its call copy a 8 bits in to 32 bit type, i do not believe that magic number qualifies it as encryption either. and why is this so efficient it s f***ing the whole thing is dome in one operation its seems dosn't matter how complex it seems its the same as almost the same as 1 + 1
|
|
|
|
|
hash values are not random
|
|
|
|
|
This not encryption or anything mysterious, it is simply copying unsigned char 8 bit into a 32 bit type by bit wise operations not all the time. NOT encryption.
|
|
|
|
|
The RA8875 is a controller for an 800x480 display I am using in a project.
You can rotate the screen via setting some registers.
There is no option to rotate 90 degrees, only 270, leaving the X axis, and thus text and bitmaps mirrored.
Whoever designed this should be forced to use it.
Real programmers use butterflies
|
|
|
|
|
Can't you just rotate it 3 times to get 90 degrees? Inelegant, but I must be missing something.
|
|
|
|
|
It's not quite 5am and my spatial reasoning may not be entirely on point right now.
Basically when I rotate it, it goes 90 degrees with the X axis inverted.
You cannot rotate it 3 times nor flip the X axis because they only use 2 bits to store the rotation.
These are the directions you can set the memory write order:
LRTD
RLTD
TDLR
DTLR
(T=Top, R=Right, D=Down, L=Left)
Real programmers use butterflies
|
|
|
|
|
I'm missing the TLDR option
|
|
|
|
|
Because you can mirror the x axis yourself reading the lines backwards.
GCS d--(d-) s-/++ a C++++ U+++ P- L+@ E-- W++ N+ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- r+++ y+++* Weapons extension: ma- k++ F+2 X
|
|
|
|
|
Yeah, no. Because then you can't send bitmap data using DMA, and you need to generate a lot more bus traffic. The device should have been designed correctly.
Real programmers use butterflies
|
|
|
|
|
"Rotate" doesn't exist -- there are only flips, on three axes.
Odd that they provide only two bits when you need three.
|
|
|
|
|
Call it what you want. You know what I was talking about so I did my part. Prescriptivism is annoying.
Real programmers use butterflies
|
|
|
|
|
Could you do the rotation and then use the horizontal and vertical scan direction registers to mirror the display (and get an extra 180 degrees of rotation)?
|
|
|
|