tag:blogger.com,1999:blog-104570422018-08-30T20:38:38.033+02:00Nicola's MAME RamblingsUnknownnoreply@blogger.comBlogger64125tag:blogger.com,1999:blog-10457042.post-71338679690220657372013-02-18T00:16:00.000+01:002013-02-18T00:30:20.563+01:00Dusting off some cobwebsWell, it looks like I hadn't been here for some time.<br /><br />I'd like to thank all the people that are still coming over to this blog, even if it hadn't been updated for several years. <br /><br />I couldn't even find the password to access the admin pages, but I recovered it eventually, so I could finally remove a lot of spam that had piled up among the comments to the previous post. While I was there, I also updated the blog template.<br /><br />I'm afraid I don't have much to say about MAME now, because I haven't been involved in its development for quite some time. Sorry! MAME was an endless source of stimulating challenges, but required too much time and dedication for a hobby.<br /><br />As some of you might have guessed from my contributions to decryption of arcade games, I've always had a strong interest for mathematical and logic puzzles. Mobile devices are the ideal platform for this kind of games, so that's where my main focus is at the moment.<br />In 2012 I released my first game for iPhone/iPod: <a href="https://itunes.apple.com/us/app/twin-beams/id534199524?mt=8">Twin Beams</a>. I'm now working on a new game.<br /><br />I've also started a new blog: <a href="http://nontrivialgames.blogspot.com/">Nontrivial Games</a>. It is dedicated to reviews of logic puzzles for iPhone and iPad. So if you share my interest for puzzles, hopefully you'll like to follow my ramblings over there.<br /><br /><br />Kind Regards,<br /><br />Nicola<br /><br />Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-10457042.post-1171715820697770642007-02-17T13:06:00.000+01:002013-02-17T23:39:47.598+01:00CPS2 not much left to doWhen I originally wrote the key searching program, that was on the assumption that the key for the second Feistel network was 96 bits long.<br /><br />Each (E,D) pair reduces the key space by a factor of about 2<sup>16</sup>, so to isolate the correct key with good confidence one would need at least 96/16 = 6 (E,D) pairs.<br /><br />The big problem is finding those pairs. Remember that they must be at compatible addresses, that is addresses whose bottom 17 bits are the same. This is a serious limitation, because the code of several games only covers a range of 0x80000 bytes, which would give a maximum of 4 pairs at any address. For the Super Puzzle Fighter 2 games, the range is just 0x40000 bytes, giving just 2 pairs per address.<br />One can find hundreds, even thousands of of (E,D) pairs, but if they are not at compatible addresses they are of no use to find the key using this attack.<br /><br />However, now we know that the key actually has only 64 significant bits, some of which are repeated. I therefore rewrote the program to take that into account. This means that only 4 (E,D) pairs are needed to isolate the key.<br /><br />Also, I made several important optimisations that I missed the first time around, like caching intermediate results and speeding up the s-boxes calculations by using precalculated tables (this last optimisation also made into MAME so the decryption when loading a game is now faster).<br /><br />The end result is a program that is orders of magnitude faster than the previous one.<br />Now it takes just 15 seconds to find the key given 8 (E,D) pairs. With 5 pairs, which was just plain impossible before, it takes 5 minutes. With 4 pairs, 35 minutes.<br /><br />These improvement made it simple to find most of the remaining keys, even for games that didn't have a matching revision already decrypted (most notably some of the Steeet Fighter Zero versions).<br /><br />But there's more: the program is now fast enough to go one step further, and look for the key with just 3 pairs. Of course 3 pairs are not enough to isolate the right key: they only reduce the key space by about 2<sup>48</sup>, therefore leaving about 2<sup>16</sup> keys which are compatible with the data. Once a 64-bit key for the second Feistel network is selected, the compatible 64-bit master keys can then be easily generated, and used to verify other (E,D) pairs at different addresses. This allows to find the correct key in less than one day, and I had to use this extended attack for a couple of the most problematic games.<br /><br />In the meantime, Andreas Naive has been busy implementing the attack he had <a href="http://andreasnaive.blogspot.com/2007/02/cps-2-11.html">described on his blog</a>, and was able to find the keys for two of the Super Puzzle Fighter 2 games. Unfortunately, the attack failed on the third. Work is still in progress on that one, and there is some hope that the key will eventually be found.<br /><br />The only other games that are missing a key are the two CPS2 versions of Mega Man. There is no decrypted CPS2 version of that game to compare with, and the CPS1 version seems to be too different to be able to find good pairs.Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-10457042.post-1169377547012138822007-01-21T12:05:00.000+01:002007-02-17T11:33:16.476+01:00CPS2 Key Bit OrderAs <a href="http://mamelife.blogspot.com/2007/01/cps2-getting-closer.html">previously mentioned</a>, the 64-bit keys I'm currently using should be the same as the hardware ones, except for a fixed permutation of the bits.<br /><br />The permutation is actually irrelevant as far as the algorithm is concerned, since it is already taken into account when generating subkeys. The difference that it does make, however, is that there are strong suspicions that some of the keys are not random numbers, so what looks like random gibberish currently would show some order if we had the correct permutation.<br /><br />Take the ssf2 versions for example. There are currently 6 different versions supported: World, USA, Asia, Japan, Tournament World, Tournament Japan. Here are the keys (in a different order):<br /><br />3D9E1E15A58C32CE<br />3599DF35AD98284C<br />B74433502F4653D7<br />8758E3923FFA1A50<br />F0AE3D08420DD6BF<br />6260014FD857F7A7<br /><br />there is something immediately obvious about those keys: they all contain exactly 32 0s and 32 1s.<br />When picking one random 64-bit numbers, the likelihood of this happening is about 1 in 10, so it's ok. But the likelihood of it happening for SIX numbers is about 1 in 1 <em>million</em>! So we can be pretty sure that those keys are <strong>not</strong> random numbers.<br /><br />What is one particularly simple sequence that has exactly 32 1s? Well, of course 0123456789ABCDEF. And sure enough, after looking at the bits for a while and applying an appropriate permutation, here is what the above keys become:<br /><br />0123456789ABCDEF<br />1032547698BADCFE<br />45673210CDEFAB89<br />67451032FEDC98BA<br />89ABDCEF45672301<br />CDEFBA9823016754<br /><br />looks much better doesn't it?<br />Though there's no way to tell how close it is to the real thing.Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-10457042.post-1169242644819532612007-01-19T22:37:00.000+01:002007-01-21T11:46:55.323+01:00CPS2 Moving Slowly NowThe <a href="http://mamelife.blogspot.com/2007/01/cps2-fight-continues.html">improved attack</a> works, and I've been able to recover a few more keys, but it takes a lot of computation time--several hours per game.<br /><br />I've also experienced some failures, e.g. I could find the key for dimahoo but not for gmahou. This might have been because of a false positive when looking for pairs with the complementation property, so now I'm trying again with a different pair. Since the searches take so long, experimenting isn't easy.<br /><br />On the plus side, I've applied the improved attack also to some games for which XOR files were not available, and it worked in a number of cases--though it failed in many others.<br /><br />One of the new versions supported is mshb, which I is the first Brazilian version of a CPS2 game to work.<br /><br />Andreas has published details on a theoretical <a href="http://andreasnaive.blogspot.com/2007/01/cps-2-10.html">attack</a> using <a href="http://en.wikipedia.org/wiki/Linear_cryptanalysis">differential cryptanalysis</a> which looks promising. If Andy's calculations are correct, it should allow to retrive the key for the three most problematic games: spf2t, spf2xj, and spf2ta. It does require a lot of (E,D,k) triplets, something in the order of 2<sup>16</sup>-2<sup>17</sup>, which is a bit steep, but we should be able to do that in a few cases.<br /><br />One thing to note about <a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html">my attack</a>, which I might not have explained clearly, is that it requires a remarkably small amount of data: it has worked for many games with just 7 (E,D) pairs. The problem is that those pairs must all be at the same address (as far as the encryption is concerned; that is, bits 1-16 of the address must be the same). Those 7 pairs allow to retrieve the 96-bit key for the second round at that address, and once that is known, the 64-bit master key can be found in less than 1 second, without having to know ANY other (E,D) pair at any address.<br /><br />Unfortunately for game like spf2t, whose full encryption range covers just 2 repetitions of an address, we are never going to have 7 pairs so the attack will never work.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1169075004745299682007-01-17T23:38:00.000+01:002007-01-19T22:13:25.836+01:00CPS2 The Fight ContinuesI've finished going through all the games previously supported by MAME using XOR files, and generating keys using <a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html">this attack</a>.<br /><br />The attack needs a minimum of 7 (E,D) pairs at some address in order to work, though with just 7 pairs it takes several hours to find the key.<br /><br />Most of the games provided at least 8 pairs, a few 7, so the attack worked.<br /><br />On 11 games the attack didn't work. Three of them only provide 2 pairs, so there's no way for the attack to work--a different approach will be needed.<br /><br />The others provide 4 pairs, and I'm now trying to still perform the attack, using a new trick.<br /><br />Remember the <a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-2.html">complementation property</a>? For every address A, we know that exists another address A<sub>1</sub> such that D(X, A) = D(X ^ 0xffff, A<sub>1</sub>) ^ 0xffff. The problem is that we don't know A<sub>1</sub>. We can search it, however, using the XOR data. Pick an address, look at the four (E,D) pairs associated to it, and then see if at another address there is a pair (E ^ 0xffff, D ^ 0xffff). That way we can put together the information from the two addresses, raising the number of pairs from 4 to 7, barely enough to run the attack.<br /><br />There's a possibility of false positives when doing this, so avoid all pairs where E or D are 0x0000 or 0xffff, because those values are very common and make the probablity of a false positive much higher.<br /><br />In theory this trick should work, though it will require some luck and a lot of time. The holy grail remains an attack which could use pairs from different addresses; that would be the only way to retrieve the key for the games that lack XORs.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-10457042.post-1168801398411695592007-01-14T19:37:00.000+01:002007-01-17T23:38:07.630+01:00CPS2 Getting CloserThe correlations between the 96-bit keys of the two Feistel networks were crucial in getting the s-boxes with 4 or 5 inputs "in sync"--that is, make them idential to the real ones apart from a fixed XOR or permutation applied to the whole box.<br /><br />Eventually, I ended with a layout which I'm 99.9% sure is equivalent to the real one. We cannot know the exact contents of the real s-boxes without getting them from the actual hardware, but the current ones should be matematically equivalent.<br />The result is here: http://xoomer.alice.it/nicola.salmoria/cps2crptv2.zip.<br /><br />The most notable news is that the key is now reduced to 64 bits, and the one we are currently using should be identical to the one used by the hardware, apart from a fixed permutation of the bits.<br />Finding the real permutation would be nice, but obviously that's not something we can determine from the algorithm, since the order of the bits of the key is completely irrelevant.<br /><br />What is interesting to note is that the keys used by some games don't seem to be random. If they were random one would expect there to be around 32 0s and 32 1s, but sometimes this isn't the case. E.g.<pre>pzloop2: 3332206a0077f829<br />mshj: 01c0c951370f4c80<br />dstlka: 04048b4e2a498879<br />ringdest: 0405541367806575<br />cybotsj: 0404821534388354</pre><br />Of these, the last three literally scream "I'm not a random number!". Guessing the right bit order to make something appear, of course, is another matter.<br />Some of the watchdog values contain birth dates, e.g. cmpi.l #$19660419,D1, so I expect the same thing might be happening here.<br />Also, it makes sense for the pzloop2 one to be more regular than the others because it's third party game.<br /><br />On the key extraction front, things are going reasonably well. The brute force attack described in the <a href="http://mamelife.blogspot.com/2007/01/how-to-bruteforce-cps2.html">previous article</a> is working decently on most games, however for some of them the available data isn't enough. I'll have a more precise list once I've finished going through all the games. After that, we'll need to devise a better attack if we want to get the missing keys.<br /><br />The discovery that the key is only 64 bits might help to construct a better attack, though at the moment I don't have many ideas. The fact that the algorithm is divided in two parts, with the output of the first one affecting the key on the second part, complicates things.Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-10457042.post-1168626992289720732007-01-12T19:36:00.000+01:002007-01-14T19:37:32.766+01:00How to bruteforce CPS2I couldn't devise an attack using differential cryptanalysis and the XOR files. The fact that the second 96-bit key changes with the address makes thing more difficult, and I couldn't think of a way to effectively use data from different addresses.<br /><br />The XOR files give us no more than 8-16 (E,D) pairs at a given address (remember that the encryption only uses the low 16 bits of the address). We have no choice of what data we have, so we have to make the best of it.<br /><br />So the idea I had is to use a meet in the middle brute force attack which exploits a weakness in the s-boxes.<br /><br />Remember that<br /><br />L<sub>1</sub> = R<sub>0</sub><br />R<sub>1</sub> = L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>)<br /><br />L<sub>2</sub> = R<sub>1</sub><br />R<sub>2</sub> = L<sub>1</sub> XOR f<sub>2</sub>(R<sub>1</sub>)<br /><br />L<sub>3</sub> = R<sub>2</sub><br />R<sub>3</sub> = L<sub>2</sub> XOR f<sub>3</sub>(R<sub>2</sub>)<br /><br />L<sub>4</sub> = R<sub>3</sub><br />R<sub>4</sub> = L<sub>3</sub> XOR f<sub>4</sub>(R<sub>3</sub>)<br /><br />Remember also that the f<sub>n</sub> round functions are made of 4 s-boxes each.<br />These are the 16 s-boxes, with their inputs and outputs:<br /><pre>f1b1 03457- 67<br />f1b2 12346- 35<br />f1b3 124567 14<br />f1b4 023567 02<br /><br />f2b1 0246-- 46<br />f2b2 134567 03<br />f2b3 013457 17<br />f2b4 123567 25<br /><br />f3b1 2346-- 35<br />f3b2 01357- 02<br />f3b3 012357 16<br />f3b4 024567 47<br /><br />f4b1 01367- 03<br />f4b2 012456 47<br />f4b3 023457 12<br />f4b4 234567 56</pre><br />f2b1 is the weakest link. It has only four inputs, 0246. To get those four inputs, we need just <em>three</em> boxes in round 1: f1b1, which outputs 67, f1b3, which outputs 14, and f1b4, which outputs 02. We don't need f1b2, which outputs 35.<br /><br />So if we start from the ciphertext and run it through the first two rounds of the Feistel network, scanning all 2<sup>24</sup> possible keys for f1b1, f1b3, f1b4, and f2b1, we'll get all possible values for bits 46 of R2.<br /><br />Now let's start from the plaintext instead, and go up. If we scan all 2<sup>6</sup> keys for f4b2, we'll get all possible values for bits 47 of R2 again.<br /><br />Now we impose that bit 4 calculated in these two ways is the same, and given enough (E,D) pairs we have a huge pruning of the valid keys. From experiments, at least 8 pairs are needed for the attack to work effectively, but with 12 it's faster.<br /><br />When we have a match on bit 4, we start adding more key bits, 6 or 12 at a time. First f4b4, to match bit 6 of R2. Then f1b2 and f2b3, to match bit 7 of R2. At this point, we are most likely already left with a single key, so adding more key bits doesn't increase the computation time. The important thing is to do it 6 bits at a time, in order to avoid unnecessary calculations. Soon enough, we have reconstructed the whole 96-bit key.<br /><br />This will be the key at a specific address--of course, before running the search we'd have scanned the whole data and selected the address with most different pairs, in order to make the attack more effective.<br /><br />After the 96-bit key at one address is found, the rest is easy. Since the 96-bit key is modified by the 16-bit result of the first FN in a fixed way, we just use brute force to find the correct 16-bit value at every address, and then we have a full subkey table as when we had the full 8GB tables at the beginning.<br /><br />The process is working reasonably well, it's taking me 20-40 minutes to find the 192-bit key for a game. It could be made faster, probably. I've done some games for which I had more data, and Razoola was kind enough to provide additional data that will help with many other games. I'm not yet sure that the attack will work on all games, but it surely will on a good percentage.<br /><br />Some very good news after obtaining more keys is that I found strong correlations between the first and second 96-bit keys, so they are effectively the same key, just permuted. This will also allow to fix the order of the subtables in the s-boxes of the first FN, in the same way I did for the second.<br /><br />Should we consider ourselves finished after that?<br /><br />Not yet: whether it will be possible to generate keys for games for which we lack XOR data is an open problem. In that case, the best we can expect to do is to match the startup code from a different version of the game, so we'll have several (E,D) pairs at consecutive addresses, and no more than one pair at a given address. A new attack will have to be devised in order to use that kind of information. Hopefully the discovery that the first and second 96-bit keys are correlated will help.Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-10457042.post-1168382666194958552007-01-09T23:26:00.000+01:002007-01-12T19:37:03.343+01:00CPS2 coming to MAMEI've submitted to MAMEDEV the code to replace the 4GB CHDs with 192-bit keys.<br />The code is here: http://xoomer.alice.it/nicola.salmoria/cps2crpt.zip<br />It contains all the information needed to understand the algorithm, including the s-boxes.<br /><br />There is still a lot of uncertainty about the contents of the s-boxes. They do their job, but since they are different from the originals they also affect the key. Using the real s-boxes might make correlations between the key bits more apparent, if they exist (anyway, having only 7 keys to look at, there's not enough data to speculate on any kind of correlation).<br /><br />I'm hoping that it will be possible to extract the s-boxes contents from photos of the decapped CPS2 chip. That would be an important step forward in the accuracy of the emulation.<br /><br />Now the next challenge is finding the keys for the other CPS2 games that have XOR files but not full tables. I have some ideas, but it doesn't look simple.<br />We have a lot of (E,D,k) triplets for those games, but unfortunately not many once you fix k (the 96-bit key used in the second FN), and that would be the most important part.<br /><br />Note that we don't have to find the whole 192-bit key all at once. Once the second 96-bit was found, then we could easily use brute force to get the 16-bit key seed at every address, and therefore easily find the first 96-bit key.Unknownnoreply@blogger.com6tag:blogger.com,1999:blog-10457042.post-1168222116572883012007-01-08T02:16:00.000+01:002007-01-09T23:25:51.646+01:00CPS2 Fundamental BreakthroughToday I realised why I was having problems with the correlations between subkey bits, where some bits had to be derived from the others not only using XOR, but also AND and OR.<br /><br />The reason was again in the s-boxes that only have 4 or 5 data inputs instead of the full 6. Those boxes contain 2 or 4 subtables, and the order of the subtables inside the box or the order of the bits inside each subtable isn't particularly important when decrypting a single address, because they can always be compensated by appropriate bits in the subkey.<br /><br />However, when putting all subkeys together, those things became important. E.g. I could be finding that when using subtable #3 in a box, then two of the inputs had to be inverted. To fix this, I had to rearrange the subtables inside the s-boxes to make everything in sync.<br /><br />The result was excellent. Previously, some of the correlations among the 96 bits were overly complex, taking up to 4 bits at once. Now every bit is directly correlated to another. The only exception is the bits that correspond to the "empty" inputs of s-boxes that take only 4 or 5 data inputs. What this means is that all 6 inputs of all s-boxes always receive the XOR of three sources: either a data bit, a key seed bit, and a global key bit; or two key seed bits, and a global key bit.<br /><br /><br />That's only the beginning of the good news, though. After fixing the s-boxes, I could attack again the first part on the algorithm on the assumption it was a 4-round Feistel network, and indeed it was.<br /><br />So the algorithm turns out to be like this:<ol><br /><li>Take the 16-bit address and a 96-bit key and run them through the first Feistel network, to produce a 16-bit subkey.</li><br /><li>Take the 16-bit ciphertext, 16-bit subkey, and another 96-bit key and run them through the second Feistel network, to produce the 16-bit plaintext</li></ol><br /><br />So now, for the first time, I would be able to produce a program that algorithmically decrypts one of the game for which we have full tables, without using any table.<br /><br />It's not yet time to celebrate, though: the s-boxes for the first Feistel network still have to be properly determined, and this might require having access to some more games.<br /><br />Once that is done, producing keys for games that we have complete tables for will be quite simple.<br /><br />Finding keys for games for which we don't have full tables, however, is an entirely different matter. As said above, we are potentially dealing with a 192-bit key here; it's possible that the key is smaller and the bits are reused, however since we don't know how they would be, we have to treat it like a 192-bit one. For a key of that size, obviously brute force is out of the question; and while the XOR tables do provide some information, it's probably not the kind of information that would allow to use the <a href="http://en.wikipedia.org/wiki/Differential_cryptanalysis">differential cryptanalysis</a> techniques we'd need.Unknownnoreply@blogger.com4tag:blogger.com,1999:blog-10457042.post-1168137348504665362007-01-07T02:16:00.000+01:002007-01-08T01:51:54.146+01:00CPS2 Won't Be Tamed That EasilySome people thought we were almost finished with the CPS2 algorithm, but this doesn't seem to be the case.<br />True, at least the 4GB tables could now be replaced with a single 128kB table, but that's still not how the hardware works, and it wouldn't be possible to generate proper keys for the games that are missing the full 8GB tables, which is the main concern.<br /><br />From the full tables, we can extract a 96-bit subkey for every address.<br /><em>Edit: I had a link to a file here. I've removed it since I've found an error which I'll correct soon.</em><br />These wouldn't be the actual keys used by the hardware, however I think me and Andy have agreed that they are, apart from a fixed XOR and bit permutation that wouldn't change from game to game. So we can forget about this step of the decryption for the time being, and move on.<br /><br />The problem now is to understand how the hardware generates the 96-bit subkey starting from the address and from the global key.<br /><br />I have determined that only 16 bits are needed to generate the 96-bit subkey; this was sort of expected, but it isn't without problems.<br />We can generate only <em>94</em> bits of the subkey starting from those 16 bits and using only XOR operations. The remaining 2 bits need AND/OR operations, something which I have no explaination for at this point.<br /><br />That was the least of the problems anyway. The major hurdle at this point is that the mapping from address to 16-bit key seed is very far from trivial.<br /><br />The scheme should be as follows:<br /><ol><li>take 16-bit address, N-bit global key, and generate a 16-bit key seed using an unknown algorithm.</li><br /><li>take 16-bit key seed, M-bit global key, and generate 96-bit subkey using an unknown algorithm.</li><br /><li>take 16-bit ciphertext, 96-bit subkey, and generate 16-bit plaintext using the algorithm we have discovered.</li></ol><br />I think it would make sense for the algorithm in step 1. to be another 4-round Feistel network.<br />If this is the case, things are quite harder than before. To break the other Feistel network, we could rely on complete knowledge of ciphertext-plaintext relationship. Now we can't: we only have a vague idea of what the 16-bit key seed could be.<br /><br />If we could rely on a 16-bit value except for a constant XOR and permutation, it wouldn't be a problem, since that wouldn't change the nature of the Feistel network. Unfortunately, we don't have that luxury.<br /><br />Let's see that with an example. Let's say that the first algorithm generates a 4-bit key seed, <em>abcd</em>, which is expanded into the 6-bit subkey <em>ABCDEF</em> this way:<br /><br />A = a<br />B = a XOR b<br />C = a XOR c<br />D = b XOR c<br />E = b XOR d<br />F = b XOR c XOR d<br /><br />We don't know anything about <em>abcd</em>, all we see is <em>ABCDEF</em>, but we need to guess what <em>abcd</em> looks like. So we notice that<br /><br />D = B XOR C<br />F = A XOR C XOR E<br /><br />and we decide that<br /><br />a' = A<br />b' = B<br />c' = C<br />d' = E<br /><br />so we would have<br /><br />A = a'<br />B = b'<br />C = c'<br />D = b' XOR c'<br />E = d'<br />F = a' XOR c' XOR d'<br /><br />This all works as far as generating the subkey from the seed goes, the problem is that <em>abcd</em> and <em>a'b'c'd'</em> are two completely different numbers! We have that<br /><br /><em>a'b'c'd'</em> = <em>abcd</em> XOR <em>aab</em><br /><br />so this isn't simply a XOR with a constant value, it's a variable modification of the number. And this is something that the Feistel network cannot handle.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-10457042.post-1168092061644319832007-01-06T14:47:00.000+01:002007-01-07T03:41:09.533+01:00CPS2 SubkeysI said earlier that I was going to post the program to extract subkeys from a CHD, and the subkey lists for a few games, however after extracting the subkeys I found important relationships between the subkey bits so I'll have to work on that first.<br /><br />A subkey consists of 24*4 = 96 bits. There are 65536 subkeys, so the total is 786kB of data.<br /><br />What I found that one bit of the subkey is constant, while 59 can be derived from the others with a XOR (which is constant for all 65536 addresses, but changes from game to game).<br /><br />So this hints at a 64-bit global key, while the independent subkey bits drop for now at 96-1-59 = 36 bits.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1168000983429483692007-01-05T13:42:00.000+01:002007-01-07T03:40:51.606+01:00CPS2 S-Boxes readyAndy has published his program but is reporting some <a href="http://andreasnaive.blogspot.com/2007/01/cps-2-9.html">problems</a> in recreating the original tables--the values generated by his program are XORed with a constant value when compared with the original table.<br /><br />I have just verified that this doesn't happen to me, so I presume this is due to a different method we used to reconstruct the Feistel function for the first two rounds.<br /><br />Let's recap how this was done. The fundamental idea was published by <a href="http://andreasnaive.blogspot.com/2006/12/cps-2-5.html">Andy</a>:<br /><br />since R<sub>4</sub> = L<sub>3</sub> XOR F<sub>4</sub>(L<sub>4</sub>), if you pick (E,D) and (E',D') such that L<sub>4</sub> = L'<sub>4</sub>, then<br /><br />R'<sub>4</sub> = L'<sub>3</sub> XOR F<sub>4</sub>(L'<sub>4</sub>) = L'<sub>3</sub> XOR F<sub>4</sub>(L<sub>4</sub>) = L'<sub>3</sub> XOR R<sub>4</sub> XOR L<sub>3</sub><br /><br />therefore<br /><br />L<sub>3</sub> XOR L'<sub>3</sub> = R<sub>4</sub> XOR R'<sub>4</sub><br /><br />Now if we pick (E,D) and (E',D') such that L<sub>4</sub> = L'<sub>4</sub> and E and E' differ by only one bit, we can see how flipping a single bit in the input changes the output after the third round. Andy's fundamental discovery was that flipping certain bits never affects certain other bits.<br /><br />That knowledge can easily be used to determine F<sub>4</sub>. Take (E,D) and (E',D'), where E and E' differ only by one bit which we know doesn't affect bit <em>b</em> in L<sub>3</sub>. Then we know that<br /><br />B<sub>b</sub>(L<sub>3</sub> XOR L'<sub>3</sub>) = 0<br /><br />where B<sub>b</sub>(x) gives me the value of bit b of x.<br /><br />Therefore<br /><br />B<sub>b</sub>(R<sub>4</sub> XOR F<sub>4</sub>(L<sub>4</sub>) XOR R'<sub>4</sub> XOR F<sub>4</sub>(L'<sub>4</sub>)) = 0<br /><br />that is,<br /><br />B<sub>b</sub>(F<sub>4</sub>(L<sub>4</sub>) XOR F<sub>4</sub>(L'<sub>4</sub>)) = B<sub>b</sub>(R<sub>4</sub> XOR R'<sub>4</sub>)<br /><br />Do that for all <em>b</em> and for all E, E' pairs, and you quickly reconstruct the whole F<sub>4</sub> structure. I'm saying its structure and not F<sub>4</sub> itself, because it's all done through XOR so you need to set F<sub>4</sub>(0) arbitrarily, then all the others are derived from it through XOR.<br /><br />After F<sub>4</sub> is reconstructed, it can be used to undo the fourth round of the encryption. Then you repeat exactly the same process to reconstruct F<sub>3</sub> (still XOR an arbitrary value). Then use F<sub>3</sub> to undo the third round, and you are left with just two rounds.<br /><br />Now things get really simple, because by definition<br /><br />L<sub>2</sub> = L<sub>0</sub> XOR F<sub>1</sub>(R<sub>0</sub>)<br />R<sub>2</sub> = R<sub>0</sub> XOR F<sub>2</sub>(L<sub>2</sub>)<br /><br />and since you know all of L<sub>0</sub>, R<sub>0</sub>, L<sub>2</sub>, and R<sub>2</sub>, F<sub>1</sub> and F<sub>2</sub> are immediately derived as<br /><br />F<sub>1</sub>(R<sub>0</sub>) = L<sub>0</sub> XOR L<sub>2</sub><br />F<sub>2</sub>(L<sub>2</sub>) = R<sub>0</sub> XOR R<sub>2</sub><br /><br />Note that here we derive F<sub>1</sub> and F<sub>2</sub> explicitly, not XOR an arbitrary value.Unknownnoreply@blogger.com13tag:blogger.com,1999:blog-10457042.post-1167858022232529752007-01-03T22:00:00.000+01:002007-01-04T12:55:04.356+01:00CPS2 is not a 4-round Feistel network (...NOT)<em>Edit: As Andy pointed out, the following reasoning is fatally flawed by the fact that the f<sub>n</sub> functions are <strong>not</strong> bijective.<br /><br />So, given the strong evidence Andy has found, it really looks like the algorithm is a 4-round Feistel network.<br /><br />This is actually good news, I have to say I am relieved ;)<br /></em><br /><br />Remember that<br /><br />L<sub>1</sub> = R<sub>0</sub><br />R<sub>1</sub> = L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>)<br /><br />L<sub>2</sub> = R<sub>1</sub><br />R<sub>2</sub> = L<sub>1</sub> XOR f<sub>2</sub>(R<sub>1</sub>)<br /><br />L<sub>3</sub> = R<sub>2</sub><br />R<sub>3</sub> = L<sub>2</sub> XOR f<sub>3</sub>(R<sub>2</sub>)<br /><br />L<sub>4</sub> = R<sub>3</sub><br />R<sub>4</sub> = L<sub>3</sub> XOR f<sub>4</sub>(R<sub>3</sub>)<br /><br /><br />In the <a href="http://mamelife.blogspot.com/2007/01/cps2-is-not-4-round-feistel-network.html">previous article</a> I showed that if we take (E,D) and (E',D') such that L<sub>0</sub> XOR L<sub>4</sub> = L'<sub>0</sub> XOR L'<sub>4</sub> and R<sub>0</sub> = R'<sub>0</sub>, then<br /><br />R<sub>2</sub> = R'<sub>2</sub>.<br /><br />I'll now take a different route from the one I took yesterday, to avoid the flaw that Andy noticed.<br /><br />From R<sub>2</sub> = R'<sub>2</sub> follows that<br /><br />L<sub>1</sub> XOR f<sub>2</sub>(R<sub>1</sub>) = L'<sub>1</sub> XOR f<sub>2</sub>(R'<sub>1</sub>), that is<br /><br />R<sub>0</sub> XOR f<sub>2</sub>(R<sub>1</sub>) = R'<sub>0</sub> XOR f<sub>2</sub>(R'<sub>1</sub>), that is (since R<sub>0</sub> = R'<sub>0</sub>)<br /><br />f<sub>2</sub>(R<sub>1</sub>) = f<sub>2</sub>(R'<sub>1</sub>), that is (since f2 is bijective)<br /><br />R<sub>1</sub> = R'<sub>1</sub>, that is<br /><br />L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>) = L'<sub>0</sub> XOR f<sub>1</sub>(R'<sub>0</sub>), that is (since R<sub>0</sub> = R'<sub>0</sub>)<br /><br />L<sub>0</sub> = L'<sub>0</sub>, therefore<br /><br />(E,D) = (E',D')<br /><br />Therefore two different pairs with the requested property cannot exist.<br /><br />When converting the 16-bit values to and from (L,R) pairs, we need to take the initial and final permutation into account. Note that we are not using R<sub>4</sub> in the above; we are only using L<sub>0</sub>, R<sub>0</sub>, and L<sub>4</sub>. Also, we don't care about the effects of the permutation on L<sub>0</sub> and R<sub>0</sub>, the only thing we care about is that when we do L<sub>0</sub> XOR L<sub>4</sub> we XOR the correct bits together. So we can arbitrarily fix the permutation on L<sub>0</sub> and R<sub>0</sub>, and try all possible permutations on L<sub>4</sub>.<br /><br />So if the CPS2 algorithm were a Feistel network, for some permutation of the bits in L4 it should not be possible to select two different pairs (E,D) and (E',D') with the requested property.<br /><br />This doesn't happen: for every permutation, such pairs exist. Therefore CPS2 is not just a 4-round Feistel network.<br /><br />This is not to say that Andy isn't on the right track, on the contrary, the findings in <a href="http://andreasnaive.blogspot.com/">CPS-2 (5)</a> are extremely interesting, but the algorithm cannot be just a 4-round Feistel network. There's something else we are missing.Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-10457042.post-1167781315672340622007-01-02T23:41:00.000+01:002007-01-04T12:54:49.686+01:00CPS2 is not a 4-round Feistel network (maybe)<em>Edit Jan 3: Andy has pointed out a flaw in this article. The order of the bits in the L and R groups is important, so we cannot draw any conclusion yet.</em><br /><br /><a href="http://andreasnaive.blogspot.com/">Andreas Naive</a> has been doing some very interesting observations lately.<br /><br />I thought it would make sense to check if we were lucky and the algorithm was indeed structured like a 4-round <a href="http://en.wikipedia.org/wiki/Feistel_cipher">Feistel network</a> as Andy supposed.<br /><br />The basic idea of a Feistel network if that you have a <em>round function</em> f() which operates on some bits of the data (8 in our case), and modifies them depending on a key. The function f is the same on every round, while the key changes.<br /><br />We don't need to care about a key at this point, since we don't know anything about the algorithm. It's easier (and more general) to simply assume that at every round a different function f<sub>n</sub> is used, where f<sub>n</sub> describes a <a href="http://en.wikipedia.org/wiki/Permutation">permutation</a> of the values 0 to 255.<br /><br />We have decided that there is strong evidence indicating that the 16 bits of the data should be split in two groups of 8 bits like this:<br />L = { 0, 1, 2, 4, 6, 7, 13, 14 }<br />R = { 3, 5, 8, 9, 10, 11, 12, 15 }<br /><br />So a 4-round Feistel network would work like this:<br />Given the ciphertext E = (L<sub>0</sub>, R<sub>0</sub>),<br /><br />L<sub>1</sub> = R<sub>0</sub><br />R<sub>1</sub> = L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>)<br /><br />L<sub>2</sub> = R<sub>1</sub><br />R<sub>2</sub> = L<sub>1</sub> XOR f<sub>2</sub>(R<sub>1</sub>)<br /><br />L<sub>3</sub> = R<sub>2</sub><br />R<sub>3</sub> = L<sub>2</sub> XOR f<sub>3</sub>(R<sub>2</sub>)<br /><br />L<sub>4</sub> = R<sub>3</sub><br />R<sub>4</sub> = L<sub>3</sub> XOR f<sub>4</sub>(R<sub>3</sub>)<br /><br />and the resulting plaintext is D = (L<sub>4</sub>, R<sub>4</sub>)<br /><br />By the properties of a Feistel network, we can also go backwards, starting from D = (L<sub>4</sub>, R<sub>4</sub>)<br /><br />R<sub>3</sub> = L<sub>4</sub><br />L<sub>3</sub> = R<sub>4</sub> XOR f<sub>4</sub>(L<sub>4</sub>)<br /><br />R<sub>2</sub> = L<sub>3</sub><br />L<sub>2</sub> = R<sub>3</sub> XOR f<sub>3</sub>(L<sub>3</sub>)<br /><br />R<sub>1</sub> = L<sub>2</sub><br />L<sub>1</sub> = R<sub>2</sub> XOR f<sub>2</sub>(L<sub>2</sub>)<br /><br />R<sub>0</sub> = L<sub>1</sub><br />L<sub>0</sub> = R<sub>1</sub> XOR f<sub>1</sub>(L<sub>1</sub>)<br /><br />Now let's start from both sides and meet in the middle. Going from E to D we have<br /><br />L<sub>2</sub> = R<sub>1</sub> = L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>)<br /><br />Going from D to E we have<br /><br />L<sub>2</sub> = R<sub>3</sub> XOR f<sub>3</sub>(L<sub>3</sub>) = L<sub>4</sub> XOR f<sub>3</sub>(R<sub>2</sub>)<br /><br />Putting the two together we have<br /><br />L<sub>0</sub> XOR f<sub>1</sub>(R<sub>0</sub>) = L<sub>4</sub> XOR f<sub>3</sub>(R<sub>2</sub>), that is<br /><br />L<sub>0</sub> XOR L<sub>4</sub> = f<sub>1</sub>(R<sub>0</sub>) XOR f<sub>3</sub>(R<sub>2</sub>)<br /><br />Now remember that we know <strong>all</strong> (E,D) pairs, so we can take advantage of that.<br />If we take (E,D) and (E',D') such that L<sub>0</sub> XOR L<sub>4</sub> = L'<sub>0</sub> XOR L'<sub>4</sub>, then it follows that<br /><br />f<sub>1</sub>(R<sub>0</sub>) XOR f<sub>3</sub>(R<sub>2</sub>) = f<sub>1</sub>(R'<sub>0</sub>) XOR f<sub>3</sub>(R'<sub>2</sub>)<br /><br />If additionally E and E' are such that R<sub>0</sub> = R'<sub>0</sub>, then we are left with just<br /><br />f<sub>3</sub>(R<sub>2</sub>) = f<sub>3</sub>(R'<sub>2</sub>)<br /><br />and since f<sub>3</sub> is a <a href="http://en.wikipedia.org/wiki/Bijection">bijective function</a>, this implies that<br /><br />R<sub>2</sub> = R'<sub>2</sub>, that is<br /><br />L<sub>3</sub> = L'<sub>3</sub>, that is<br /><br />R<sub>4</sub> XOR f<sub>4</sub>(L<sub>4</sub>) = R'<sub>4</sub> XOR f<sub>4</sub>(L'<sub>4</sub>), that is<br /><br />f<sub>4</sub>(L<sub>4</sub>) XOR f<sub>4</sub>(L'<sub>4</sub>) = R<sub>4</sub> XOR R'<sub>4</sub><br /><br />Now we can repeat the procedure for all (E,D) pairs, and get a large number of equations on f<sub>4</sub>.<br /><br />If the CPS2 encryption was a 4-round Feistel network, all those equations would not be contradictory, and they would allow us to reconstruct the structure of f<sub>4</sub>.<br /><br />Unfortunately, they <strong>are</strong> contradictory. E.g. you get something like this:<br /><br />f<sub>4</sub>(0xff) XOR f<sub>4</sub>(0xfc) = 0x11<br />f<sub>4</sub>(0xff) XOR f<sub>4</sub>(0xfc) = 0x48<br /><br />Therefore CPS2 is not a 4-round Feistel network.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-10457042.post-1166556958129876382006-12-19T19:07:00.000+01:002007-01-03T14:42:09.336+01:00CPS2 notes, part 5In <a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html">part 1</a> I showed some constant values in the table that shows how many times flipping a bit in the ciphertext flips a bit in the plaintext.<br />But there's more than that. It seems that there are more properties which are true for all games, regardless of the key.<br /><br /><pre> 0 1 2 3 4 5 6 7<br /> 0 7FE0 75B0 8028 7AF4 6EB0 8284 734C 7420<br /> 1 8208 7FE0 7E48 7FA4 81CC 8050 72F8 7FDC<br /> 2 7F38 7F8C 8000 7FD0 87B0 7EF4 7BF8 8068<br /> 3 <span style="background-color:red; color:white">7200</span> <span style="background-color:lime; color:black">6CA0</span> <span style="background-color:orange; color:white">7B00</span> 76E0 <span style="background-color:limegreen; color:white">6800</span> 8044 <span style="background-color:orange; color:white">B280</span> <span style="background-color:lime; color:black">8180</span><br /> 4 7F18 7FCC 7F84 8130 7BC4 80E4 8154 8014<br /> 5 8980 7B80 7780 81D4 6200 7D78 7540 7DE0<br /> 6 83C0 7E98 7F3C 831C 6CF0 8080 7BD8 7D20<br /> 7 80B0 81B0 7EAC 8190 7DB4 8050 8364 7F68<br /> 8 7D80 80E0 7D80 8110 78C0 7FC4 6F40 8DA0<br /> 9 <span style="background-color:red; color:white">5080</span> <span style="background-color:green; color:white">7510</span> <span style="background-color:orange; color:white">C000</span> 643C <span style="background-color:palegreen; color:black">6DC0</span> 8414 <span style="background-color:orange; color:white">4800</span> <span style="background-color:green; color:white">72C0</span><br />10 7BE0 7A30 7F40 7F08 6A00 8110 7720 7B80<br />11 8040 81A0 7E80 7E2C 5680 7FFC 73C0 8020<br />12 7A80 8370 7100 818C 7E80 7BE8 6200 8060<br />13 8018 7D24 8040 7F60 7E2C 80EC 7F9C 7EA0<br />14 7D18 7F00 7EEC 80DC 799C 7F90 7F34 8010<br />15 7E80 8710 8540 8128 8200 7F50 7C40 8540<br /><br /> 8 9 10 11 12 13 14 15<br /> 0 8054 7C58 7BF4 7E88 7C80 7610 7C7C 7C28<br /> 1 8008 7FA4 80F0 8020 7FB8 7E24 7EE8 8078<br /> 2 7FB8 7F18 7FE4 7F14 7FDC 80C0 7C3C 8130<br /> 3 80DC 7F34 7EE0 8124 77F0 <span style="background-color:limegreen; color:white">7800</span> <span style="background-color:red; color:white">5A80</span> 7064<br /> 4 800C 7F98 7D3C 7E60 803C 7C74 80E0 80A0<br /> 5 8024 7BA8 79C8 8020 7A24 7E00 7F60 7AAC<br /> 6 7F80 7E94 7B08 7FE8 7E98 6DA0 7FD4 7E50<br /> 7 7FE8 7E20 7D6C 7F88 8004 7BD4 803C 7FCC<br /> 8 7F4C 7FE4 7E48 7F10 7F40 7FC0 74C0 82B4<br /> 9 812C 8064 6520 78D8 7D5C <span style="background-color:palegreen; color:black">5040</span> <span style="background-color:red; color:white">5800</span> 8588<br />10 7D50 7FB8 883C 7E00 7EDC 8A00 78E0 7FDC<br />11 7EF8 7F64 7860 7E30 804C 6780 82C0 81E8<br />12 8094 7CCC 7A44 7EF0 7FC0 7C80 8100 7EF4<br />13 8180 7FA0 7FF4 8084 8000 8088 7F9C 8024<br />14 8004 8080 809C 7F44 806C 8044 7A5C 7FEC<br />15 7EC0 814C 7A10 7F2C 7E80 9200 7E20 8064</pre><br /><span style="background-color:red">   </span> are constant.<br /><br /><span style="background-color:orange">   </span> are correlated and can be only one of 2 quadruplets.<br /><br /><span style="background-color:lime">   </span> <span style="background-color:limegreen">   </span> <span style="background-color:palegreen">   </span> <span style="background-color:green">   </span> are all correlated and values can be taken in one of 4 "groups".<br /><br />Once chosen the group:<br /><span style="background-color:lime">   </span> are correlated and can be only one of 2 pairs.<br /><span style="background-color:green">   </span> are correlated and can be only one of 2 pairs.<br /><span style="background-color:limegreen">   </span> are correlated and can be only one of 4 pairs.<br /><span style="background-color:palegreen">   </span> are fixed by <span style="background-color:green">   </span> and <span style="background-color:limegreen">   </span>.<br /><br />So in total there are 2x4x2x2x4 = 128 combinations. Each combination is used by exactly 256 tables.<br /><br />Note the symmetry of it all. 16 values are affected, related to 2 bits of the ciphertext and 8 bits of the plaintext.<br /><br />This suggests that the algorithm might work on the data 8 bits at a time, or even only 4 bits at a time. The regular behaviour could be caused by a step, at the beginning or at the end of the algorithm, that doesn't use the key.<br /><br />Another thing we can do is check which of the 128 combinations corresponds to each memory address, and look for a way to correlate the two. Unfortunately there doesn't seem to be a simple way to do that.Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-10457042.post-1166524307081113592006-12-19T11:17:00.000+01:002007-01-02T23:39:40.853+01:00CPS2 notes, part 4I have to stress that there is NO progress being made in breaking the encryption. The things I am showing in these notes have been known for over a year and haven't lead to any breakthrough. Hopefully, a public discussion of these properties could generate some valuable feedback.<br /><br />There also isn't any kind of competition against the people that are attacking the CPS2 encryption in hardware. On the contrary, I think that the hardware path will be the only way to gather more information about the algorithm.<br /><br />In these notes I have shown several properties that are always true, regardless of the key. This means that they are properties of the algorithm itself, and therefore are hardcoded in hardware. For example, there almost surely are fixed substitution boxes which could be extracted from the custom CPU.<br /><br />If an algorithm is reconstructed by studying the CPU, we can also test it against the known properties, regardless of the key. If it doesn't match, then the algorithm isn't right. Once an algorithm fitting the properties is found, we can start looking for the key.Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-10457042.post-1166479213089184602006-12-18T22:34:00.000+01:002007-01-02T23:39:45.886+01:00CPS2 notes, part 3In <a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html">part 1</a> we were flipping bits in the ciphertext, and seeing what happened to bits in the plaintext.<br /><br />We can do the opposite, of course, and there's something unexpected in the results.<br />I'll show the total number of times the bits change (in hex) instead of percentages, to make the point more visible.<br /><pre> 0 1 2 3 4 5 6 7<br /> 0 80BC 7844 7E24 7FD4 7EBC 8090 8138 8044<br /> 1 7FB0 8138 7A90 7EB0 7D54 7F04 7FE4 8074<br /> 2 7F20 7F30 81A4 8018 80C4 7FB4 7F08 7EF8<br /> 3 7F30 8180 7D10 7EA0 6F40 7E30 85E0 79E0<br /> 4 7EA8 7B1C 8240 7FD4 7DE4 7F24 7F44 80C4<br /> 5 A2C0 6D00 6CC0 69E0 6700 7F28 <span style="background-color:orange; color:white;">5E00</span> 4E00<br /> 6 7F5C 7ECC 7FB8 7FF8 7C38 7FF0 7EF0 7CAC<br /> 7 7FD0 7D80 8168 8058 8104 7FA0 7FAC 80E8<br /> 8 71E0 <span style="background-color:red; color:white;">B500</span> 8E80 8020 7900 8124 7980 8240<br /> 9 7A20 6E40 7AE0 7FA8 8080 7F84 8240 88E0<br />10 7930 6900 7A50 81BC 7220 7C48 7A20 6FC0<br />11 7950 8C00 7600 8054 6F20 806C 7CE0 89C0<br />12 6F40 <span style="background-color:red; color:white;">4B00</span> 85C0 8010 7600 809C 7E00 7E80<br />13 7F30 7B20 7FB8 8028 803C 80B4 7E80 8140<br />14 7A90 8034 7D4C 8124 80D8 7E8C 7FC8 7FC0<br />15 73F0 79C0 7990 80D0 9440 7D94 7AC0 6EA0<br /><br /> 8 9 10 11 12 13 14 15<br /> 0 8048 7E84 7DB8 801C 80B8 80A4 62BC 7FB0<br /> 1 803C 7FE8 7E20 81E8 80F0 7D68 8144 7FBC<br /> 2 807C 80C4 7F80 7FFC 7F90 7EE0 82B0 80B4<br /> 3 7EB0 80E0 7E68 7F70 7E78 8010 7580 7BBC<br /> 4 7FF0 7F68 7FB8 7FFC 7FAC 8074 7DD4 813C<br /> 5 7F08 6FA0 7254 6BB8 6C10 <span style="background-color:orange; color:white;">6380</span> 6300 7AE8<br /> 6 7FF4 7F9C 8018 7FCC 8138 8118 6E14 80BC<br /> 7 8088 80DC 7FC0 7DB8 7F8C 7EE4 84E0 7F48<br /> 8 7EEC 8090 84EC 7E28 8328 8960 <span style="background-color:red; color:white;">2D00</span> 85AC<br /> 9 7F94 7EA4 7D6C 8080 8068 8200 5FC0 82F0<br />10 7AF0 80AC 80C8 7CB4 8054 8640 7100 7F8C<br />11 81F0 8080 7F2C 8064 7F94 82C0 6E80 7B30<br />12 809C 7FD0 7F98 7ED0 75C8 83C0 <span style="background-color:red; color:white;">D300</span> 7CE8<br />13 8134 8160 80A0 7F40 7D6C 809C 80E4 7F58<br />14 7F68 7F14 7F44 7F28 8010 7EB4 7F10 7F80<br />15 82E0 7D4C 78D8 804C 8000 78A0 6240 75DC</pre><br />The values highlighted in orange are the only two that are constant in every table (there were four in the inverse table).<br /><br />But the values highlighted in red are the most interesting. They are not constant--they can vary among a few possible values. But the <b>sum</b> of the two values in each column is constant, and it's always 0x10000.<br /><br />Why? I have no idea.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1166453611529533332006-12-18T14:32:00.000+01:002006-12-18T22:34:05.806+01:00CPS2 notes, part 2The complementation property was an important discovery--and not just because it reduces the size of the tables in half. Still, we haven't taken full advantage of it yet.<br /><br />Let's recap the basics of the CPS2 encryption first.<br /><br />Inputs:<br /><ul><li>16-bit value stored in ROM</li><br /><li>16-bit address (bits 1-17 of the physical address)</li><br /><li>key of unknown size, different for every game</li></ul><br />Outputs:<br /><ul><li>16-bit decrypted value</li></ul><br /><br />Let's call D(X,A,K) the decryption of value X at address A using key K.<br />The complementation property says that for every A there is exactly one A<sub>1</sub> such that<br /><br />D(X,A,K) = D'(X',A<sub>1</sub>,K)<br /><br />where x' is the complement of x.<br /><br />This finding is important because it shows that A has an algorithmical effect on the encryption. In Sega's FD1094 CPU, the key for every address is just stored in a huge table. If the CPS2 CPU worked in the same way, the complementation property wouldn't happen.<br />This isn't too much of a surprise: with the Kabuki CPU, we had already seen that Capcom preferred a complex algorithm with a small key, while Sega preferred a simpler algorithm with a huge key.<br /><br />Unfortunately we don't yet know how to calculate A<sub>1</sub> given A. It varies from game to game so it must be a function of the key.<br /><br />The complementation property isn't unheard of, even in strong ciphers, so it isn't necessarily a weakness in the algorithm. For example, <a href="http://en.wikipedia.org/wiki/Data_Encryption_Standard#Minor_cryptanalytic_properties">DES</a> has it. In that case, it reads D(X,K) = D'(X',K').<br /><br />In general, the complementation property indicates that there are probably XOR operations happening, which cause the complement operation to cancel out. Let's see this with an example: consider a substitution function f, and an algorithm such that<br /><br />d = e XOR f(e XOR k)<br /><br />if we take the complements we have<br /><br />e' XOR f(e' XOR k') = e' XOR f(e XOR k) = (e XOR f(e XOR k))' = d'<br /><br />of course this is a very simple example. Note that x' doesn't have to be the complement in this case: you can define it as e.g. x' = x XOR 1, and it will still work. So the CPS2 algorithm obviously isn't that simple.<br /><br />A more realistic example would be a <a href="http://en.wikipedia.org/wiki/Feistel_cipher">Feistel network</a> (note that DES is an example of a Feistel network).<br /><br />If you define the Feistel network as<br />L<sub>i</sub> = R<sub>i-1</sub><br />R<sub>i</sub> = L<sub>i-1</sub> XOR f(R<sub>i-1</sub> XOR K<sub>i-1</sub>)<br /><br />it should be easy to see how the complementation property would ensue.<br /><br />The idea of the CPS2 encryption being a Feistel network is tempting, however I don't think this is the case, because I would expect the diffusion to be much better than what we have seen in <a href="http://mamelife.blogspot.com/2006/12/cps2-notes-part-1.html">part 1</a>.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1166388147415701602006-12-17T20:38:00.000+01:002006-12-18T22:34:01.680+01:00CPS2 notes, part 1Since the finding of the <a href="http://mamelife.blogspot.com/2006/01/8gb-2-is-still-4gb.html">complementation property</a> almost one year ago, there has been no progress at all on the CPS2 encryption.<br /><br />I'm going to explain here some of the (remarkably few) things we know about the encryption.<br /><br />A common misconception is that the decryption tables look like "random data". They may look so to the naked eye, but the most basic statistical checks show that this isn't the case.<br /><br />Take an encrypted value, change a bit in it, and look at what happens to the output. For a random table, you'd expect every bit in the decrypted value to change with 50% probability. This isn't happening.<br />Take a look at the following statistics taken on a single table: on rows, you have the encrypted bit that changes; on columns, the frequency with which the decrypted bit changes.<br /><pre><br /> 0 1 2 3 4 5 6 7 <br /> 0 50,26% <span style="color:brown">44,09%</span> 50,98% 49,68% <span style="color:brown">42,94%</span> 50,81% <span style="color:brown">44,99%</span> <span style="color:brown">43,87%</span><br /> 1 49,52% 49,73% 49,87% 49,90% 49,32% 49,77% 45,37% 50,43%<br /> 2 49,62% 50,05% 49,67% 50,25% 51,56% 49,86% 49,07% 50,07%<br /> 3 <span style="color:white; background-color:red">44,53%</span> 45,75% 48,05% 48,93% <span style="color:brown">40,63%</span> 50,22% <span style="color:brown">69,73%</span> <span style="color:brown">44,29%</span><br /> 4 49,83% 50,19% 49,62% 49,98% 48,35% 49,88% 50,38% 50,57%<br /> 5 50,24% 46,53% 50,78% 50,21% <span style="color:brown">28,13%</span> 49,79% <span style="color:brown">44,63%</span> 47,80%<br /> 6 51,92% 49,73% 50,10% 50,17% <span style="color:brown">38,28%</span> 50,10% 48,35% 47,86%<br /> 7 50,29% 49,51% 49,16% 49,86% 48,35% 49,93% 50,85% 50,07%<br /> 8 51,95% 52,51% 51,37% 48,71% 49,22% 50,07% 43,55% 46,78%<br /> 9 <span style="color:white; background-color:red">31,45%</span> 48,32% <span style="color:brown">75,00%</span> <span style="color:brown">43,55%</span> 46,39% 50,51% <span style="color:brown">28,13%</span> 46,92%<br />10 50,20% 50,95% 51,37% 49,78% <span style="color:brown">28,13%</span> 50,06% 47,17% 51,66%<br />11 45,17% 45,85% 47,66% 50,38% <span style="color:brown">25,20%</span> 50,58% 44,43% 53,37%<br />12 47,85% 47,51% <span style="color:brown">44,14%</span> 50,04% 53,03% 49,24% <span style="color:brown">38,28%</span> 49,17%<br />13 49,68% 49,90% 49,43% 50,10% 50,02% 49,46% 50,05% 49,89%<br />14 49,35% 50,32% 49,98% 49,80% 48,29% 49,65% 49,48% 50,42%<br />15 48,97% 51,59% 51,07% 49,57% <span style="color:brown">67,19%</span> 49,55% 45,70% 50,39%<br /><br /> 8 9 10 11 12 13 14 15<br /> 0 50,43% 48,46% 49,02% 49,49% 49,21% <span style="color:brown">43,35%</span> 49,05% 47,69%<br /> 1 49,85% 49,69% 50,57% 49,76% 50,01% 49,40% 49,88% 50,15%<br /> 2 50,14% 50,05% 49,86% 49,57% 50,25% 50,96% 48,99% 50,18%<br /> 3 49,46% 50,18% 48,31% 50,30% 46,96% <span style="color:brown">40,63%</span> <span style="color:white; background-color:red">35,35%</span> <span style="color:brown">44,34%</span><br /> 4 49,82% 50,43% 49,70% 50,34% 49,79% 47,74% 50,16% 49,57%<br /> 5 49,91% 48,74% 49,68% 49,88% 48,79% <span style="color:brown">28,91%</span> 49,02% 48,36%<br /> 6 49,74% 49,21% 50,24% 49,62% 49,40% <span style="color:brown">39,32%</span> 49,91% 49,62%<br /> 7 50,14% 50,03% 49,63% 50,39% 49,65% 47,67% 50,43% 49,37%<br /> 8 49,83% 49,96% 48,57% 50,43% 49,15% <span style="color:brown">40,63%</span> 46,97% 50,50%<br /> 9 50,15% 49,08% <span style="color:brown">44,80%</span> 48,27% 49,65% 50,78% <span style="color:white; background-color:red">34,38%</span> 50,81%<br />10 49,76% 49,92% 50,28% 49,24% 49,21% <span style="color:brown">67,97%</span> 49,27% 49,87%<br />11 47,55% 50,00% 50,16% 47,17% 49,61% <span style="color:brown">25,39%</span> 48,93% 51,68%<br />12 49,83% 48,97% 49,69% 49,86% 49,30% 52,93% 50,39% 49,90%<br />13 49,85% 50,37% 50,52% 49,94% 49,60% 51,22% 49,96% 49,92%<br />14 49,85% 50,18% 49,97% 49,89% 50,09% 49,84% 47,50% 49,64%<br />15 49,49% 49,37% 49,39% 50,09% 49,57% <span style="color:brown">38,28%</span> 49,17% 49,57%<br /></pre><br />So there is a large number of values around 50%, which look just random, but there are also values very far from that.<br /><br />This indicates that the encryption algorithm <em>doesn't have good <a href="http://en.wikipedia.org/wiki/Confusion_and_diffusion">diffusion</a></em>. This is a weakness, though it hasn't been exploited yet.<br /><br />Of particular interest are the four values I highlighted in red. While the other values change from game to game and from table to table, those four values <em>are always the same</em>. E.g. flipping bit 9 in the encrypted value causes bit 0 in the decrypted value to flip exactly 0x5080 times out of 0x10000, for every game, at every address.<br /><br />This property is quite interesting. It is the most obvious "signature" of the algorithm. Does it help? Well, it tells us that if the algorithm contains bit permutations that depend on the key, those permutations cannot affect bits 3 and 9 in the encrypted value, nor bits 0 and 14 of the decrypted data. Apart from that, however, the property doesn't tell us much, because even if we know that the bits have to change that many times, we don't know exactly <em>when</em> to flip them. Discovering that would be a significant advance in the understanding of the algorithm.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1165595579307717392006-12-08T15:31:00.000+01:002006-12-17T21:43:39.536+01:00Katamino(This article is not MAME related)<br /><br />Some time ago I was shopping looking for a set of <a href="http://en.wikipedia.org/wiki/Pentomino">Pentomino</a> pieces and found this game called <a href="http://www.katamino.co.uk/">Katamino®</a>.<br /><br />It looked like a decent enough set of wooden pieces, so I bought it. Pentominoes are a decades old puzzle, so I didn't expect anything more than that. Instead, when I opened the box, I was blown away by how cleverly the puzzle is presented.<br />The idea is credited to André Perriolat, who is the owner of the company that produces the game, <a href="http://www.katamino.com">DJ Games</a>.<br /><br />Here is how it works: take four pentominoes, and make a 5x4 rectangle with them. After you've accomplished that, add another pentomino, and make a 5x5 square. Then add another, and make a 5x6 rectangle. And so on, until you add the final piece to make a 5x12 rectangle. The box contains a board with a moving slider to place your pieces in.<br /><br />There is only one rule: when you add the I piece, you cannot place it vertically. Otherwise it would be cheating, since you could take the solution to the previous puzzle and just stick the I to the side.<br />For the same reason, the I piece is not used for the 5x5 puzzles, since even if you put it horizontally it would still be a 5x4 rectangle with the I stuck to the side.<br /><br />In the box there's a list of 12 such sequences that you can follow, each one ending with a different piece.<br /><br />This is absolutely brilliant. You start with easy puzzles wich practically anyone can solve, and then gradually increase the difficulty until you complete the full puzzle--or run out of patience, whichever comes first.<br /><br />Every time you complete one of the puzzles there's a sense of achivement--and then immediately of frustration, because to add one more piece you have to throw away the perfect shape you just created, and start again from scratch.<br /><br />I liked this idea so much that I started thinking about it. How many ways are there to build sequences to play the game? Are the ones provided the best possible, or can they be improved? Let's see what the goal is:<br /><ul><br /><li>build 12 sequences, each one ending with a different piece</li><br /><li>every combination of pieces must be used only once</li><br /></ul><br />Things get interesting from the start. There are only 19 ways to select 4 pieces that can form a 5x4 rectangle; but 6 of them cannot be extended to 5x5 without using the I piece. This leaves us with 13 initial choices, just one more than what we need.<br /><br />How can we rate our sequences to decide which ones are better than others? The obvious answer is to look at the number of different solutions for each combination of pieces. The less the solutions, the better the puzzle is. If two sequences have the same number of solutions, then the one that contains more puzzles which have a single solution is better.<br />The 5x11 puzzles are obviously the same for every choice, so we don't have to count them. This leaves us with 12 sets of 7 puzzles (from 5x4 to 5x10) for a total of 84 puzzles, which we want to be as hard as possible.<br /><br />Turns out that the sequences accompanying my copy of the game aren't very good: there's a total of 3084 solutions, and only 20 puzzles with a single solution. Even worse, one of the puzzles is repeated twice.<br />It seems that I have and old version of the game (the instructions say (c) 1992-1998). The version currently being produced uses a better list, whith 1556 solutions and 26 single solutions (and no duplicates).<br /><br />Writing a program to find the best solution is a remarkably difficult task. I'm not even sure if it has been classified. If it is, I'd expect it to be as part of problems related to graph theory.<br /><br />With a mix of manual pruning and computer search, I've selected this sequence which looks quite good:<br /><br /><pre><br />L P U F [1] W [1] I [4] Z [1] T [5] N [1] V [83] Y [1277] X [786]<br />L Y U F [3] Z [1] I [2] N [2] T [4] X [2] V [16] P [ 508] W "<br />Y N V T [1] F [1] I [3] W [1] U [5] X [1] L [ 8] P [ 371] Z "<br />L Y P W [5] N [1] V [1] I [5] X [1] Z [5] F [25] U [ 216] T "<br />Y P U F [1] T [1] I [2] Z [1] N [2] X [1] W [ 2] L [ 183] V "<br />L Y P T [1] W [1] F [1] N [5] X [3] Z [1] I [ 8] V [ 133] U "<br />L V P Z [2] Y [1] T [2] I [5] X [1] W [1] F [15] U [ 125] N "<br />L Y P Z [1] W [2] T [1] V [1] X [1] U [3] N [21] I [ 116] F "<br />L N P U [2] Z [2] X [1] V [1] F [1] T [2] W [14] Y [ 112] I "<br />L N V Z [2] U [1] T [1] F [2] I [6] W [3] X [ 1] P [ 101] Y "<br />Y N P U [1] V [1] Z [1] X [1] F [2] T [1] W [ 1] I [ 59] L "<br />L Y V U [2] Z [1] F [1] W [1] X [1] N [1] T [ 1] I [ 14] P "<br /></pre><br /><br />The numbers in square brackets are the solutions for each puzzle.<br />The total is <b>331</b> solutions, and <b>45</b> puzzles with a single solution.<br /><br />I think this should be quite close to the minimum, but I don't have a way to prove it.<br /><br />Can anyone do better?Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1154783827473583802006-08-05T14:11:00.000+02:002006-12-08T23:22:07.163+01:00Completed, at LastAs you'd probably noticed, the pics in the previous post are of the Bubble Bobble custom MCU.<br /><br />Despite being one of the most popular games of all times, and having been in MAME for many years, the emulation of this game has never been perfect due to the lack of the original ROM for the MCU.<br /><br />For some time, we had been using a 68705 program found in a bootleg board, believing it had been extracted from the original. However, monster behaviour was wrong and there were other problems, like the wrong behaviour of the clock item.<br /><br />After some study of the program and of the game schematics, it became clear that the original MCU is not a 68705 at all (the pinout doesn't match) but looked more like a 68701.<br />The 68705 program had been written from scratch by the bootleggers using black box reverse engineering techniques, by running the original MCU and logging all its reads and writes from memory. Indeed, the 68705 program does a lot of reads from memory without doing anything with them--simply because the original MCU would read that memory and do some unknown action with it.<br /><br />Eventually, the useless 68705 program was replaced by simulation code inside the emulator, which greatly improved the emulation accuracy. Monster behaviour was improved, the clock item behaviour fixed. However, there were still some unknown things, like how the randomisation of the EXTEND bubbles really worked.<br /><br />At last, thanks to excellent work by Trinity, the original MCU ROM has been extracted. This required removing the cover from the chip, taking photographs of it under a microscope, and manually decoding the contents of the ROM bit by bit. The photo shown in the previous post confirms that it's in the 6801 class, not a 68701 however as it was conjectured, but a 6801U4.<br /><br />With this ROM, we finally have the final piece of the puzzle for a 100% guaranteed perfect emulation.<br /><br />Checking the original MCU program was very interesting. It was designed to provide many protection features that were eventually not used by the game, like:<br /><ul><li>process coin inputs and update the credit counter</li><li>handle the number of remaining lives for both players</li><li>handle the current round number</li><li>handle variable speed incrementing for four variables</li><li>return values from a 1280 bytes table of seemingly random data</li></ul>The reasons why those features were not used are probably various. Some of them were probably awkward to use because they require to one one frame for the MCU to process the data, others weren't flexible enough like the coin input processing that wouldn't allow for coinage settings different from the ones hardcoded in the MCU (though versions of Bubble Bobble with different coinage settings don't seem to have been made anyway).<br /><br />So, how close was the simulation to the real thing? Very close; "too good", actually. Let's see why.<br /><br />The clock item behaviour was spot on, but off by one frame (the simulation made the counter expire one frame too late).<br /><br />The EXTEND randomisation simply doesn't exist in the original MCU. While the simulation code used a RNG to provide truly random letters, the original MCU simply increases the counter every frame. This seriously affects the game, making the EXTEND letters predictable.<br />Since a new bubble enters the screen exactly 128 frames after the previous one, and the remainder of 128 / 6 is 2, this means that if you get consecutive letters each one will be 2 places after the previous one. So if you get 3 letters you can get either E, T, N or X, E, D. After that they will repeat. There are exceptions, though: if you create a new bubble in exactly the same frame when a new bubble should enter the screen, the bubble is delayed by one frame. So by timing the fire button exactly right you can change the bubble order. In theory you could get all 6 letters in a single level--let me know if you manage to do that! :)<br />Also, new bubbles will not appear if there are already 16 bubbles on the screen, so that will change the order as well.<br /><br />The last, and most important, thing that the MCU does is compare the player coordinates with the monsters. The results are returned as flags indicating whether each coordinate is >, =, or <, and the absolute difference. This was done correctly in the simulation code, however there appears to be a bug in the original MCU. The code there attempts to check if the player collided with a moster and set a flag and indicate which monster in that case, but it just doesn't work. It would set the flag even if the player's Y coordinate matches one monster and the X coordinate matches a different monster!<br />This isn't much of a problem since the main program just ignores the flag--the collision detection is done correctly by the second Z80.<br />However, the MCU also completely stops processing the monster coordinates as soon as it finds a monster whose X coordinate is within 8 pixels of the player. So e.g. if you have a monster right above you three platforms up, and that monster is the first in the list, the other monsters could stop following you. This is a very subtle effect that's completely unnoticeable from what I can tell, though in theory it exists.Unknownnoreply@blogger.com12tag:blogger.com,1999:blog-10457042.post-1154638361478498302006-08-03T22:47:00.000+02:002006-12-08T23:22:00.723+01:00Good News<p>What's inside this?</p><br /><br /><img src="http://photos1.blogger.com/blogger/6506/809/320/JPH1011P.jpg" alt="JPH1011P" /><br /><br /><p>This:</p><br /><br /><img src="http://photos1.blogger.com/blogger/6506/809/1600/6801U4.jpg" alt="6801U4" /><br /><br /><p>More on this later.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-10457042.post-1150796579022228062006-06-20T11:01:00.000+02:002006-12-08T23:21:56.086+01:00Political DigressionForgive me for abusing of this space to talk about an important matter of Italian politics.<br /><br />Il 25 e 26 giugno siamo chiamati alle urne per uno dei più importanti voti della storia della Repubblica. Dovremo decidere se mantenere la nostra Costituzione del 1947, o se adottarne una nuova.<br /><br />Questo è l'articolo 70 nella nostra Costituzione:<br /><br /><span style="font-style:italic;">"La funzione legislativa è esercitata collettivamente dalle due Camere."</span><br /><br /><br />Questo è l'articolo con cui verrebbe sostituito se la nuova Costituzione sarà approvata dal referendum:<br /><br /><span style="font-style:italic;">"La Camera dei deputati esamina i disegni di legge concernenti le materie di cui all'articolo 117, secondo comma, fatto salvo quanto previsto dal terzo comma del presente articolo. Dopo l'approvazione da parte della Camera, a tali disegni di legge il Senato federale della Repubblica, entro trenta giorni, può proporre modifiche, sulle quali la Camera decide in via definitiva. I termini sono ridotti alla metà per i disegni di legge di conversione dei decreti-legge.<br />Il Senato federale della Repubblica esamina i disegni di legge concernenti la determinazione dei princìpi fondamentali nelle materie di cui all'articolo 117, terzo comma, fatto salvo quanto previsto dal terzo comma del presente articolo. Dopo l'approvazione da parte del Senato, a tali disegni di legge la Camera dei deputati, entro trenta giorni, può proporre modifiche, sulle quali il Senato decide in via definitiva. I termini sono ridotti alla metà per i disegni di legge di conversione dei decreti-legge.<br /><br />La funzione legislativa dello Stato è esercitata collettivamente dalle due Camere per l'esame dei disegni di legge concernenti le materie di cui all'articolo 117, secondo comma, lettere m) e p), e 119, l'esercizio delle funzioni di cui all'articolo 120, secondo comma, il sistema di elezione della Camera dei deputati e per il Senato federale della Repubblica, nonché nei casi in cui la Costituzione rinvia espressamente alla legge dello Stato o alla legge della Repubblica, di cui agli articoli 117, commi quinto e nono, 118, commi secondo e quinto, 122, primo comma, 125, 132, secondo comma, e 133, secondo comma. Se un disegno di legge non è approvato dalle due Camere nel medesimo testo i Presidenti delle due Camere possono convocare, d'intesa tra di loro, una commissione, composta da trenta deputati e da trenta senatori, secondo il criterio di proporzionalità rispetto alla composizione delle due Camere, incaricata di proporre un testo unificato da sottoporre al voto finale delle due Assemblee. I Presidenti delle Camere stabiliscono i termini per l'elaborazione del testo e per le votazioni delle due Assemblee.<br />Qualora il Governo ritenga che proprie modifiche a un disegno di legge, sottoposto all'esame del Senato federale della Repubblica ai sensi del secondo comma, siano essenziali per l'attuazione del suo programma approvato dalla Camera dei deputati, ovvero per la tutela delle finalità di cui all'articolo 120, secondo comma, il Presidente della Repubblica, verificati i presupposti costituzionali, può autorizzare il Primo ministro ad esporne le motivazioni al Senato, che decide entro trenta giorni. Se tali modifiche non sono accolte dal Senato, il disegno di legge è trasmesso alla Camera che decide in via definitiva a maggioranza assoluta dei suoi componenti sulle modifiche proposte.<br />L'autorizzazione da parte del Presidente della Repubblica di cui al quarto comma può avere ad oggetto esclusivamente le modifiche proposte dal Governo ed approvate dalla Camera dei deputati ai sensi del secondo periodo del secondo comma.<br />I Presidenti del Senato federale della Repubblica e della Camera dei deputati, d'intesa tra di loro, decidono le eventuali questioni di competenza tra le due Camere, sollevate secondo le norme dei rispettivi regolamenti, in ordine all'esercizio della funzione legislativa. I Presidenti possono deferire la decisione ad un comitato paritetico, composto da quattro deputati e da quattro senatori, designati dai rispettivi Presidenti. La decisione dei Presidenti o del comitato non è sindacabile in alcuna sede. I Presidenti delle Camere, d'intesa tra di loro, su proposta del comitato, stabiliscono sulla base di norme previste dai rispettivi regolamenti i criteri generali secondo i quali un disegno di legge non può contenere disposizioni relative a materie per cui si dovrebbero applicare procedimenti diversi"</span><br /><br /><br />La nuova Costituzione modifica più di 50 articoli della Costituzione originale. Credo che questo articolo da solo sarebbe sufficiente per decidere quale delle due è migliore. La nostra Costituzione è elegante, essenziale, efficace. La si vuole sostituire con una cosa verbosa e incomprensibile, scritta come una leggina qualsiasi, in cui si fa riferimento all'articolo X comma Y lettera Z. E' una cosa vergognosa. Non si può. Non va bene. E' la nostra Costituzione, non è una leggina qualsiasi. E' il documento fondante della nostra Repubblica, un documento che un ragazzo della scuola media dovrebbe poter leggere e capire senza difficoltà.Unknownnoreply@blogger.com5tag:blogger.com,1999:blog-10457042.post-1140738353952193662006-02-24T00:30:00.000+01:002006-12-08T23:21:52.676+01:00Still some doubts about Bubble BobbleThe emulation of Bubble Bobble is already virtually perfect, but there is still a doubt about the clock item.<br /><br />Currently, when you pick it up the enemies stop but the bubbles continue moving.<br /><br />It would make sense if the bubbles stopped moving too, and this idea is corroborated by the way variables are set up in the MCU shared RAM. The MCU would be responsible for stopping the bubbles and make them start again when the clock effect ends.<br /><br />What we need is to verify the behaviour on an <strong>original</strong> board. Bootlegs don't count (the clock behaviour is definitely wrong in them), nor do other emulator or ports count. Only the original board matters.<br /><br />Can anyone help?Unknownnoreply@blogger.com7tag:blogger.com,1999:blog-10457042.post-1139013400090793222006-02-04T01:11:00.000+01:002006-12-08T23:21:49.496+01:00Coinmaster<a href="http://www.citylan.it/reip/">Pierpaolo Prazzoli</a> made me look at the encrypted question ROMs of the Coinmaster games.<br /><br />It's nothing interesting, just a permutation of the address and data lines. The interesting thing, however, if how they gave away the encryption on the data lines by implementing the ROM checksum test in an unwise way.<br /><br />To verify the checksum, the game reads all bytes in the ROM <em>except</em> the one at offset 2, and adds them with 8-bit arithmetic. It then takes the opposite of the result and compares it with the byte at offset 2, expecting them to be equal. What this actually means, however, is that adding <em>all</em> bytes in the ROM will always give as result 0.<br /><br />Knowing that the sum of all bytes must be 0 instantly kills the data lines encryption. All one has to do is try to apply different permutations on the encrypted data, and calculate the resulting checksum. First look just at bit 0, ignoring the others. Try a permutation that leaves it in place, then one that replaces it with bit 1 of the encrypted data, then bit 2, and so on. Look at bit 0 of the resulting checksum. If it's 0 for all ROMs, then you got the right bit. So, in at most 8 tries, you'll find bit 0 of the permutation. Then move on to bit 1, and repeat the procedure. In at most 7 tries, you'll find bit 1 of the permutation. And so on.Unknownnoreply@blogger.com1